/server/src/main/java/com/paypal/selion/grid/servlets/transfer/UploadResponder.java

https://gitlab.com/CORP-RESELLER/SeLion · Java · 227 lines · 147 code · 41 blank · 39 comment · 8 complexity · 498fb5a1b72a7d44ac80fc1dff3b88d6 MD5 · raw file

  1. package com.paypal.selion.grid.servlets.transfer;
  2. import java.io.File;
  3. import java.io.IOException;
  4. import java.io.PrintWriter;
  5. import java.util.List;
  6. import java.util.Map;
  7. import java.util.logging.Level;
  8. import java.util.logging.Logger;
  9. import javax.servlet.http.HttpServletResponse;
  10. import com.google.gson.Gson;
  11. import com.google.gson.GsonBuilder;
  12. import com.google.gson.JsonArray;
  13. import com.google.gson.JsonObject;
  14. import com.paypal.selion.logging.SeLionGridLogger;
  15. import org.apache.commons.io.FilenameUtils;
  16. /**
  17. * <code>UploadResponder</code> responds to HTTP POST upload request for any type that extends {@link ManagedArtifact}.
  18. * The response Content-Type is decided by the implementations. The response URLs are REST styled formed after the user
  19. * Id folder and artifact name. Application folder is inserted if available.
  20. */
  21. public interface UploadResponder {
  22. /**
  23. * Responds into {@link HttpServletResponse}.
  24. */
  25. void respond();
  26. /**
  27. * Enum holding the MIME types for HTTP Accept header and the corresponding class that implements the logic for
  28. * serving the respective content.
  29. *
  30. */
  31. enum AcceptHeaderEnum {
  32. /**
  33. * Accept: application/json
  34. */
  35. APPLICATION_JSON("application/json", JsonUploadResponder.class),
  36. /**
  37. * Accept: text/plain
  38. */
  39. TEXT_PLAIN("text/plain", TextPlainUploadResponder.class);
  40. private String acceptHeader;
  41. private static final Logger LOGGER = SeLionGridLogger.getLogger(AcceptHeaderEnum.class);
  42. private Class<? extends UploadResponder> uploadResponder;
  43. AcceptHeaderEnum(String acceptHeader, Class<? extends UploadResponder> uploadResponder) {
  44. this.acceptHeader = acceptHeader;
  45. this.uploadResponder = uploadResponder;
  46. }
  47. public String getAcceptHeader() {
  48. return acceptHeader;
  49. }
  50. public Class<? extends UploadResponder> getUploadResponder() {
  51. return uploadResponder;
  52. }
  53. /**
  54. * Returns {@link AcceptHeaderEnum} for the given HTTP Accept header, or throws {@link ArtifactUploadException}
  55. * if there is no implementation for the Accept header or if the Accept header is null
  56. *
  57. * @param acceptHeader
  58. * Accept header of the HTTP method
  59. * @return Instance of {@link AcceptHeaderEnum}
  60. */
  61. public static AcceptHeaderEnum getAcceptHeaderEnum(String acceptHeader) {
  62. if (acceptHeader != null) {
  63. for (AcceptHeaderEnum acceptHeaderEnum : AcceptHeaderEnum.values()) {
  64. if (acceptHeader.contains(acceptHeaderEnum.getAcceptHeader())) {
  65. if (LOGGER.isLoggable(Level.FINE)) {
  66. LOGGER.log(Level.FINE, "Returning: " + acceptHeaderEnum.getClass().getSimpleName()
  67. + " for accept header: " + acceptHeader);
  68. }
  69. return acceptHeaderEnum;
  70. }
  71. }
  72. }
  73. throw new ArtifactUploadException("No 'UploadResponder' found for AcceptHeader: " + acceptHeader);
  74. }
  75. }
  76. /**
  77. * <code>AbstractUploadResponder</code> is abstract super class for concrete implementations that work on types of
  78. * {@link ManagedArtifact}.
  79. */
  80. abstract class AbstractUploadResponder implements UploadResponder {
  81. protected final TransferContext transferContext;
  82. protected final String requestUrl;
  83. protected final Map<String, String> headersMap;
  84. protected final List<ManagedArtifact> managedArtifactList;
  85. protected ManagedArtifact managedArtifactUnderProcess;
  86. public AbstractUploadResponder(TransferContext transferContext) {
  87. super();
  88. this.transferContext = transferContext;
  89. this.requestUrl = this.transferContext.getHttpServletRequest().getRequestURL().toString();
  90. this.managedArtifactList = this.transferContext.getUploadRequestProcessor().getUploadedData();
  91. this.headersMap = this.transferContext.getHeadersMap();
  92. }
  93. public void respond() {
  94. if (transferContext.getUploadRequestProcessor().getUploadedData().size() <= 0) {
  95. throw new ArtifactUploadException("No files processed by request processor");
  96. }
  97. respondFromRequestProcessor();
  98. }
  99. protected void addArtifactPath(StringBuffer url) {
  100. File repoFolder = ManagedArtifactRepository.getInstance().getRepositoryFolder();
  101. String relPath = managedArtifactUnderProcess.getAbsolutePath().replace(repoFolder.getAbsolutePath(), "");
  102. relPath = FilenameUtils.normalize(relPath);
  103. relPath = FilenameUtils.separatorsToUnix(relPath);
  104. url.append(relPath);
  105. }
  106. protected abstract void respondFromRequestProcessor();
  107. }
  108. /**
  109. * <code>JsonUploadResponder</code> for {@link AbstractUploadResponder} which sends out application/json responses
  110. * to {@link HttpServletResponse}
  111. */
  112. final class JsonUploadResponder extends AbstractUploadResponder {
  113. public static final String CONTENT_TYPE_VALUE = AcceptHeaderEnum.APPLICATION_JSON.getAcceptHeader();
  114. private final Gson gson;
  115. private final JsonObject jsonResponse;
  116. private final JsonArray files;
  117. public JsonUploadResponder(TransferContext transferContext) {
  118. super(transferContext);
  119. gson = new GsonBuilder().disableHtmlEscaping().create();
  120. jsonResponse = new JsonObject();
  121. files = new JsonArray();
  122. }
  123. protected void respondFromRequestProcessor() {
  124. SeLionGridLogger.getLogger(JsonUploadResponder.class).entering();
  125. PrintWriter out;
  126. transferContext.getHttpServletResponse().setContentType(CONTENT_TYPE_VALUE);
  127. try {
  128. out = transferContext.getHttpServletResponse().getWriter();
  129. jsonResponse.add("files", files);
  130. for (ManagedArtifact managedArtifact : managedArtifactList) {
  131. managedArtifactUnderProcess = managedArtifact;
  132. processArtifact();
  133. }
  134. out.println(gson.toJson(jsonResponse));
  135. SeLionGridLogger.getLogger(JsonUploadResponder.class).exiting();
  136. } catch (IOException e) {
  137. throw new ArtifactUploadException("IOException in retrieving HttpServletResponse's Writer", e);
  138. }
  139. }
  140. private void processArtifact() {
  141. JsonObject file = new JsonObject();
  142. StringBuffer url = new StringBuffer(requestUrl);
  143. addArtifactPath(url);
  144. file.addProperty(ManagedArtifact.ARTIFACT_FILE_NAME, managedArtifactUnderProcess.getArtifactName());
  145. file.addProperty("url", url.toString());
  146. files.add(file);
  147. }
  148. }
  149. /**
  150. * <code>TextPlainUploadResponder</code> for {@link AbstractUploadResponder} which sends out text/plain responses to
  151. * {@link HttpServletResponse}
  152. */
  153. final class TextPlainUploadResponder extends AbstractUploadResponder {
  154. public static final String CONTENT_TYPE_VALUE = AcceptHeaderEnum.TEXT_PLAIN.getAcceptHeader();
  155. private static final SeLionGridLogger LOGGER = SeLionGridLogger.getLogger(TextPlainUploadResponder.class);
  156. private final StringBuffer textResponse;
  157. public TextPlainUploadResponder(TransferContext transferContext) {
  158. super(transferContext);
  159. textResponse = new StringBuffer();
  160. }
  161. protected void respondFromRequestProcessor() {
  162. LOGGER.entering();
  163. PrintWriter out;
  164. transferContext.getHttpServletResponse().setContentType(CONTENT_TYPE_VALUE);
  165. try {
  166. out = transferContext.getHttpServletResponse().getWriter();
  167. for (ManagedArtifact managedArtifact : managedArtifactList) {
  168. managedArtifactUnderProcess = managedArtifact;
  169. processArtifact();
  170. }
  171. out.println(textResponse.toString());
  172. } catch (IOException e) {
  173. throw new ArtifactUploadException("IOException in retrieving HttpServletResponse's Writer", e);
  174. }
  175. LOGGER.exiting();
  176. }
  177. private void processArtifact() {
  178. StringBuilder fileName = new StringBuilder();
  179. StringBuffer url = new StringBuffer(requestUrl);
  180. addArtifactPath(url);
  181. fileName.append(ManagedArtifact.ARTIFACT_FILE_NAME).append("=")
  182. .append(managedArtifactUnderProcess.getArtifactName());
  183. textResponse.append(fileName.toString()).append(",url=").append(url.toString());
  184. }
  185. }
  186. }