/src/main/java/net/hockeyapp/bamboo/UploadTask.java

https://github.com/niick/HockeyBambooPlugin · Java · 144 lines · 119 code · 25 blank · 0 comment · 11 complexity · bbec6e5e6fb67da82d859dee27e3da67 MD5 · raw file

  1. package net.hockeyapp.bamboo;
  2. import java.io.File;
  3. import java.io.FileNotFoundException;
  4. import java.io.IOException;
  5. import java.util.Set;
  6. import net.hockeyapp.bamboo.CountingMultipartEntity.ProgressListener;
  7. import org.apache.commons.httpclient.HttpClient;
  8. import org.apache.commons.httpclient.methods.PostMethod;
  9. import org.apache.commons.httpclient.methods.multipart.FilePart;
  10. import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
  11. import org.apache.commons.httpclient.methods.multipart.Part;
  12. import org.apache.commons.httpclient.methods.multipart.StringPart;
  13. import org.apache.commons.httpclient.params.HttpMethodParams;
  14. import org.apache.commons.lang.StringUtils;
  15. import org.jetbrains.annotations.NotNull;
  16. import com.atlassian.bamboo.build.logger.BuildLogger;
  17. import com.atlassian.bamboo.task.TaskContext;
  18. import com.atlassian.bamboo.task.TaskException;
  19. import com.atlassian.bamboo.task.TaskResult;
  20. import com.atlassian.bamboo.task.TaskResultBuilder;
  21. import com.atlassian.bamboo.task.TaskType;
  22. import com.google.common.collect.Sets;
  23. public class UploadTask implements TaskType {
  24. private static final String HOCKEY_URL = "https://rink.hockeyapp.net/api/2/apps/upload";
  25. @NotNull
  26. @java.lang.Override
  27. public TaskResult execute(@NotNull final TaskContext taskContext) throws TaskException {
  28. final BuildLogger buildLogger = taskContext.getBuildLogger();
  29. final String apiToken = taskContext.getConfigurationMap().get("apitoken");
  30. buildLogger.addBuildLogEntry("Using API Token: " + apiToken);
  31. TaskResultBuilder taskResult = TaskResultBuilder.create(taskContext);
  32. PostMethod method = createPostRequest(taskContext, buildLogger, apiToken);
  33. if ((method != null) && (sendPostRequest(method, buildLogger))) {
  34. taskResult.success();
  35. }
  36. else {
  37. taskResult.failed();
  38. }
  39. return taskResult.build();
  40. }
  41. private PostMethod createPostRequest(TaskContext taskContext, BuildLogger buildLogger, String apiToken) {
  42. final PostMethod method = new PostMethod(HOCKEY_URL);
  43. method.addRequestHeader("X-HockeyAppToken", apiToken);
  44. final Set<Part> parts = Sets.newHashSet();
  45. final String ipaPath = taskContext.getConfigurationMap().get("ipa");
  46. if (!addIPAPart(taskContext, parts, ipaPath)) {
  47. buildLogger.addBuildLogEntry("Could not load the specified IPA file '" + ipaPath + "'");
  48. return null;
  49. }
  50. final String dsymPath = taskContext.getConfigurationMap().get("dsym");
  51. if ((!StringUtils.isEmpty(dsymPath)) && (!addDSYMPart(taskContext, parts, dsymPath))) {
  52. buildLogger.addBuildLogEntry("Could not load the specified dSYM file '" + dsymPath + "'");
  53. return null;
  54. }
  55. final String notes = taskContext.getConfigurationMap().get("notes");
  56. parts.add(new StringPart("notes", notes));
  57. final String download = taskContext.getConfigurationMap().get("download");
  58. parts.add(new StringPart("download", (download.equalsIgnoreCase("true") ? "2" : "1")));
  59. final String notify = taskContext.getConfigurationMap().get("notify");
  60. parts.add(new StringPart("notify", (notify.equalsIgnoreCase("true") ? "1" : "0")));
  61. final HttpMethodParams params = new HttpMethodParams();
  62. MultipartRequestEntity requestEntity = new MultipartRequestEntity(parts.toArray(new Part[parts.size()]), params);
  63. CountingMultipartEntity countingEntity = new CountingMultipartEntity(requestEntity, getLogListener(buildLogger, requestEntity.getContentLength()));
  64. method.setRequestEntity(countingEntity);
  65. return method;
  66. }
  67. private Boolean sendPostRequest(PostMethod method, BuildLogger buildLogger) {
  68. final HttpClient client = new HttpClient();
  69. try {
  70. buildLogger.addBuildLogEntry("Uploading build to HockeyApp...");
  71. final int status = client.executeMethod(method);
  72. if (status == 201) {
  73. buildLogger.addBuildLogEntry("Upload completed!");
  74. return true;
  75. }
  76. else {
  77. final String body = method.getResponseBodyAsString();
  78. buildLogger.addErrorLogEntry("Upload failed with response:");
  79. buildLogger.addErrorLogEntry(body);
  80. return false;
  81. }
  82. }
  83. catch (IOException e) {
  84. buildLogger.addErrorLogEntry("Upload failed with IOException: " + e.getLocalizedMessage());
  85. return false;
  86. }
  87. }
  88. private ProgressListener getLogListener(final BuildLogger buildLogger, final long totalSize) {
  89. return new ProgressListener() {
  90. private long lastSize = 0;
  91. public void transferred(long size) {
  92. if ((long)((double)lastSize / (double)totalSize * 10.0) < (long)((double)size / (double)totalSize * 10.0)) {
  93. buildLogger.addBuildLogEntry("Upload progress: " + (long)((double)size / (double)totalSize * 100) + "%");
  94. }
  95. lastSize = size;
  96. }
  97. };
  98. }
  99. private boolean addDSYMPart(TaskContext taskContext, Set<Part> parts, String dsymPath) {
  100. final File pathToFile = new File(taskContext.getWorkingDirectory(), dsymPath);
  101. try {
  102. parts.add(new FilePart("dsym", pathToFile));
  103. return true;
  104. }
  105. catch (FileNotFoundException e) {
  106. return false;
  107. }
  108. }
  109. private Boolean addIPAPart(TaskContext taskContext, Set<Part> parts, String ipaPath) {
  110. final File pathToFile = new File(taskContext.getWorkingDirectory(), ipaPath);
  111. try {
  112. parts.add(new FilePart("ipa", pathToFile));
  113. return true;
  114. }
  115. catch (FileNotFoundException e) {
  116. return false;
  117. }
  118. }
  119. }