From d0d6b87b68f7ea6af13c01af36c624dc68dd3750 Mon Sep 17 00:00:00 2001
From: Paulo Vitor Magacho da Silva
+ * Version 1.3 - Topcoder - Change Download URL in Direct Application + * - Add url property + *
* @author aubergineanode, singlewood * @author TCSDESIGNER, TCSDEVELOPER - * @version 1.2 + * @version 1.3 */ public class Upload extends AuditedDeliverableStructure { /** @@ -93,6 +97,12 @@ public class Upload extends AuditedDeliverableStructure { */ private String description; + /** + * Represent the s3 url + * + */ + private String url; + /** * Creates a new Upload. */ @@ -267,4 +277,22 @@ public boolean isValidToPersist() { && (parameter != null) && (super.isValidToPersist())); } + + /** + * Get url + * + * @return url + */ + public String getUrl() { + return url; + } + + /** + * Set url + * + * @param url url + */ + public void setUrl(String url) { + this.url = url; + } } diff --git a/components/deliverable_management/src/java/main/com/topcoder/management/deliverable/persistence/sql/SqlUploadPersistence.java b/components/deliverable_management/src/java/main/com/topcoder/management/deliverable/persistence/sql/SqlUploadPersistence.java index cc6b225c1..f59d3dcc3 100644 --- a/components/deliverable_management/src/java/main/com/topcoder/management/deliverable/persistence/sql/SqlUploadPersistence.java +++ b/components/deliverable_management/src/java/main/com/topcoder/management/deliverable/persistence/sql/SqlUploadPersistence.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2012 TopCoder Inc., All Rights Reserved. + * Copyright (C) 2006-2018 TopCoder Inc., All Rights Reserved. */ package com.topcoder.management.deliverable.persistence.sql; @@ -193,7 +193,14 @@ *+ * Version 1.6 - Topcoder - Change Download URL in Direct Application + *
+ * Version 1.3 - Topcoder - Change Download URL in Direct Application + * - Add support download from S3 + * - Add support for download studio + *
+ * * @author TCSASSEMBLER - * @version 1.2 + * @version 1.3 */ public class DownloadAllSoftwareSubmissionsAction extends ContestAction { @@ -126,6 +135,11 @@ public class DownloadAllSoftwareSubmissionsAction extends ContestAction { */ private static final String ALL_SUBMISSIONS = "All_Submissions.zip"; + /** + * Resource property for "Handle" + */ + private static final String RESOURCE_PROPERTY_HANDLE = "Handle"; + /** * Represents the upload parameters which are used to retrieve the uploaded files. */ @@ -136,6 +150,10 @@ public class DownloadAllSoftwareSubmissionsAction extends ContestAction { */ private FileUpload fileUpload; + /** + * Represents theFileUpload
service for studio. It will be injected by Spring.
+ */
+ private FileUpload studioFileUpload;
/**
* The round type of the software contest.
@@ -165,6 +183,11 @@ public class DownloadAllSoftwareSubmissionsAction extends ContestAction {
*/
private SoftwareCompetition contest;
+ /**
+ * S3 bucket
+ */
+ private String s3Bucket;
+
/**
*
* Creates a DownloadAllSoftwareSubmissionsAction
instance.
@@ -259,34 +282,55 @@ public InputStream getInputStream() throws Exception {
PipedInputStream in = new PipedInputStream();
PipedOutputStream out = new PipedOutputStream(in);
final ZipOutputStream zos = new ZipOutputStream(out);
- new Thread(new Runnable(){
+ new Thread(new Runnable() {
public void run() {
byte[] buffer = new byte[8192];
int read;
InputStream is = null;
try {
for (Submission sub : submissionsToDownload) {
- UploadedFile file = fileUpload.getUploadedFile(sub.getUpload().getParameter());
- is = file.getInputStream();
String submissionFileZipName;
-
- if(isCopilotPosting) {
- // special handling for the copilot posting submission, prefix the submitter's handle
- final String copilotHandle = getUserService().getUserHandle(Long.parseLong(sub.getUpload().getCreationUser()));
- String ext = FilenameUtils.getExtension(file.getRemoteFileName());
- if(ext != null && ext.trim().length() > 0) {
- ext = "." + ext;
+ // url != null is s3
+ if (sub.getUpload().getUrl() != null) {
+ S3Object s3Object = DirectUtils.getS3Client().getObject(new GetObjectRequest(s3Bucket,
+ DirectUtils.getS3FileKey(sub.getUpload().getUrl())));
+ is = s3Object.getObjectContent();
+ submissionFileZipName = DirectUtils.getS3FileKey(sub.getUpload().getUrl());
+ } else {
+ UploadedFile file;
+ if (DirectUtils.isStudio(contest)) {
+ Long userId = null;
+ String handle = null;
+ for (Resource r : contest.getResources()) {
+ if (r.getId() == sub.getUpload().getOwner()) {
+ userId = r.getUserId();
+ handle = r.getProperty(RESOURCE_PROPERTY_HANDLE);
+ }
+ }
+ file = studioFileUpload.getUploadedFile(DirectUtils.createStudioLocalFilePath(contest.getId(), userId, handle,
+ sub.getUpload().getParameter()));
} else {
- ext = "";
+ file = fileUpload.getUploadedFile(sub.getUpload().getParameter());
+ }
+ is = file.getInputStream();
+
+ if (isCopilotPosting) {
+ // special handling for the copilot posting submission, prefix the submitter's handle
+ final String copilotHandle = getUserService().getUserHandle(Long.parseLong(sub.getUpload().getCreationUser()));
+ String ext = FilenameUtils.getExtension(file.getRemoteFileName());
+ if (ext != null && ext.trim().length() > 0) {
+ ext = "." + ext;
+ } else {
+ ext = "";
+ }
+ submissionFileZipName = copilotHandle + COPILOT_POSTING_SUBMISSION
+ + ext;
+
+ is = DirectUtils.appendStringToFilesInZip(file, copilotHandle);
+ } else {
+ submissionFileZipName = "Submission-" + sub.getId() + "-" + file.getRemoteFileName();
}
- submissionFileZipName = copilotHandle + COPILOT_POSTING_SUBMISSION
- + ext;
-
- is = DirectUtils.appendStringToFilesInZip(file, copilotHandle);
- } else {
- submissionFileZipName = "Submission-" + sub.getId() + "-" + file.getRemoteFileName();
}
-
// create an entry for each file
ZipEntry outputEntry = new ZipEntry(submissionFileZipName);
@@ -375,4 +419,39 @@ public void setFileUpload(FileUpload fileUpload) {
public void setRoundType(ContestRoundType roundType) {
this.roundType = roundType;
}
+
+ /**
+ * Get S3 bucket
+ *
+ * @return s3 bucket name
+ */
+ public String getS3Bucket() {
+ return s3Bucket;
+ }
+
+ /**
+ * Set S3 bucket
+ * @param s3Bucket S3 bucket name
+ */
+ public void setS3Bucket(String s3Bucket) {
+ this.s3Bucket = s3Bucket;
+ }
+
+ /**
+ * Get FileUpload instance for studio
+ *
+ * @return FileUpload instance
+ */
+ public FileUpload getStudioFileUpload() {
+ return studioFileUpload;
+ }
+
+ /**
+ * Set FileUpload for studio
+ *
+ * @param studioFileUpload FileUpload instance
+ */
+ public void setStudioFileUpload(FileUpload studioFileUpload) {
+ this.studioFileUpload = studioFileUpload;
+ }
}
diff --git a/src/java/main/com/topcoder/direct/services/view/action/contest/DownloadSoftwareSubmissionAction.java b/src/java/main/com/topcoder/direct/services/view/action/contest/DownloadSoftwareSubmissionAction.java
index 197f4d06b..e63f3d242 100644
--- a/src/java/main/com/topcoder/direct/services/view/action/contest/DownloadSoftwareSubmissionAction.java
+++ b/src/java/main/com/topcoder/direct/services/view/action/contest/DownloadSoftwareSubmissionAction.java
@@ -1,8 +1,10 @@
/*
- * Copyright (C) 2011 - 2013 TopCoder Inc., All Rights Reserved.
+ * Copyright (C) 2011 - 2018 TopCoder Inc., All Rights Reserved.
*/
package com.topcoder.direct.services.view.action.contest;
+import com.amazonaws.services.s3.model.GetObjectRequest;
+import com.amazonaws.services.s3.model.S3Object;
import com.topcoder.direct.services.view.action.BaseDirectStrutsAction;
import com.topcoder.direct.services.view.dto.contest.ContestType;
import com.topcoder.direct.services.view.util.DirectUtils;
@@ -28,9 +30,15 @@
*
+ * Version 1.2 - Topcoder - Change Download URL in Direct Application + * - Add support download from S3 + * - Add support for download studio + *
+ * * @author TCSASSEMBLER - * @version 1.1 (Release Assembly - TC Cockpit Misc Bug Fixes) + * @version 1.2 * @since TCCC-2802 */ public class DownloadSoftwareSubmissionAction extends BaseDirectStrutsAction { @@ -39,6 +47,11 @@ public class DownloadSoftwareSubmissionAction extends BaseDirectStrutsAction { */ private static final long serialVersionUID = 1870450815370143413L; + /** + * Resource property for "Handle" + */ + private static final String RESOURCE_PROPERTY_HANDLE = "Handle"; + /** * Represents the submission id the user want to download. */ @@ -65,6 +78,11 @@ public class DownloadSoftwareSubmissionAction extends BaseDirectStrutsAction { */ private FileUpload fileUpload; + /** + * Represents theFileUpload
service for studio. It will be injected by Spring.
+ */
+ private FileUpload studioFileUpload;
+
/**
* The SoftwareCompetition instance representing the contest the submission is downloaded from.
*
@@ -72,18 +90,28 @@ public class DownloadSoftwareSubmissionAction extends BaseDirectStrutsAction {
*/
private SoftwareCompetition contest;
+ /**
+ * S3 url of uploaded file. Null if it use local file
+ */
+ private String s3Url;
+
+ /**
+ * S3 bucket
+ */
+ private String s3Bucket;
+
/**
* * Executes the action. It will get the uploaded file the user want to download. *
- * + * * @throws Exception * is any error occurs. */ @Override protected void executeAction() throws Exception { // get the submission of the project - Submission[] submissions = getContestServiceFacade().getSoftwareProjectSubmissions(getCurrentUser(), projectId); + Submission[] submissions = getContestServiceFacade().getSoftwareProjectSubmissions(getCurrentUser(), projectId); // check whether the project contains the submission the user want to download for (Submission sub : submissions) { if (sub.getUpload() != null && sub.getId() == submissionId) { @@ -99,20 +127,43 @@ protected void executeAction() throws Exception { contest = getContestServiceFacade().getSoftwareContestByProjectId(getCurrentUser(), projectId); - uploadedFile = fileUpload.getUploadedFile(submission.getUpload().getParameter()); + if (submission.getUpload().getUrl() == null) { + if (DirectUtils.isStudio(contest)) { + Long userId = null; + String handle = null; + for (Resource r : contest.getResources()) { + if (r.getId() == submission.getUpload().getOwner()) { + userId = r.getUserId(); + handle = r.getProperty(RESOURCE_PROPERTY_HANDLE); + } + } + + uploadedFile = studioFileUpload.getUploadedFile(DirectUtils.createStudioLocalFilePath(contest.getId(), userId, handle, + submission.getUpload().getParameter())); + } else { + uploadedFile = fileUpload.getUploadedFile(submission.getUpload().getParameter()); + } + } else { + s3Url = submission.getUpload().getUrl(); + } } /** * Gets theInputStream
of the download.
- *
+ *
* @return the InputStream
of the download.
* @throws Exception
* if any error occurs when getting the input stream of the uploaded file.
*/
public InputStream getInputStream() throws Exception {
+ if (s3Url != null) {
+ S3Object s3Object = DirectUtils.getS3Client().getObject(new GetObjectRequest(s3Bucket,
+ DirectUtils.getS3FileKey(s3Url)));
+ return s3Object.getObjectContent();
+ }
- if(contest.getProjectHeader().getProjectCategory().getId() == ContestType.COPILOT_POSTING.getId()) {
+ if (contest.getProjectHeader().getProjectCategory().getId() == ContestType.COPILOT_POSTING.getId()) {
// it's copilot posting, append user handle to each file in the copilot posting submission
Resource[] resources = contest.getResources();
long userId = 0;
@@ -131,12 +182,15 @@ public InputStream getInputStream() throws Exception {
/**
* Gets the content disposition of the uploaded file.
- *
+ *
* @return the content disposition of the upload file.
* @throws Exception
* if any error occurs when getting the file name of the uploaded file.
*/
public String getContentDisposition() throws Exception {
+ if (s3Url != null) {
+ return "attachment; filename=\"submission-" + submission.getId() + "-" + DirectUtils.getS3FileKey(s3Url) + "\"";
+ }
if (contest.getProjectHeader().getProjectCategory().getId() == ContestType.COPILOT_POSTING.getId()) {
// it's copilot posting, append user handle to each file in the copilot posting submission
@@ -148,7 +202,6 @@ public String getContentDisposition() throws Exception {
break;
}
}
-
return "attachment; filename=\"submission-" + getUserService().getUserHandle(userId) + "-" +
uploadedFile.getRemoteFileName()
+ "\"";
@@ -160,7 +213,7 @@ public String getContentDisposition() throws Exception {
/**
* Gets the submission id the user want to download.
- *
+ *
* @return the submission id the user want to download.
*/
public long getSubmissionId() {
@@ -169,7 +222,7 @@ public long getSubmissionId() {
/**
* Sets the submission id the user want to download.
- *
+ *
* @param submissionId
* the submission id the user want to download.
*/
@@ -178,7 +231,7 @@ public void setSubmissionId(long submissionId) {
}
/** Gets the project id of the upload.
- *
+ *
* @return the project id of the upload.
*/
public long getProjectId() {
@@ -187,7 +240,7 @@ public long getProjectId() {
/**
* Sets the project id of the upload.
- *
+ *
* @param projectId
* the project id of the upload.
*/
@@ -197,7 +250,7 @@ public void setProjectId(long projectId) {
/**
* Gets the FileUpload
service.
- *
+ *
* @return the FileUpload
service.
*/
public FileUpload getFileUpload() {
@@ -206,7 +259,7 @@ public FileUpload getFileUpload() {
/**
* Sets the FileUpload
service.
- *
+ *
* @param fileUpload
* the FileUpload
service.
*/
@@ -227,4 +280,39 @@ public void setFileUpload(FileUpload fileUpload) {
private InputStream prefixHandleToSubmissionFile(UploadedFile submissionFile, long userId) throws Exception {
return DirectUtils.appendStringToFilesInZip(submissionFile, getUserService().getUserHandle(userId));
}
+
+ /**
+ * Get S3 bucket
+ *
+ * @return s3 bucket name
+ */
+ public String getS3Bucket() {
+ return s3Bucket;
+ }
+
+ /**
+ * Set S3 bucket
+ * @param s3Bucket S3 bucket name
+ */
+ public void setS3Bucket(String s3Bucket) {
+ this.s3Bucket = s3Bucket;
+ }
+
+ /**
+ * Get FileUpload instance for studio
+ *
+ * @return FileUpload instance
+ */
+ public FileUpload getStudioFileUpload() {
+ return studioFileUpload;
+ }
+
+ /**
+ * Set FileUpload for studio
+ *
+ * @param studioFileUpload FileUpload instance
+ */
+ public void setStudioFileUpload(FileUpload studioFileUpload) {
+ this.studioFileUpload = studioFileUpload;
+ }
}
diff --git a/src/java/main/com/topcoder/direct/services/view/util/DirectUtils.java b/src/java/main/com/topcoder/direct/services/view/util/DirectUtils.java
index f9f391aa2..e69dc2153 100644
--- a/src/java/main/com/topcoder/direct/services/view/util/DirectUtils.java
+++ b/src/java/main/com/topcoder/direct/services/view/util/DirectUtils.java
@@ -3,6 +3,8 @@
*/
package com.topcoder.direct.services.view.util;
+import com.amazonaws.auth.PropertiesCredentials;
+import com.amazonaws.services.s3.AmazonS3Client;
import com.opensymphony.xwork2.ActionContext;
import com.topcoder.clients.dao.ProjectContestFeePercentageService;
import com.topcoder.clients.dao.ProjectContestFeeService;
@@ -116,6 +118,7 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.net.URL;
import java.nio.channels.FileLock;
import java.sql.Connection;
import java.sql.PreparedStatement;
@@ -752,9 +755,15 @@
* Version 2.4 - Quick72Hrs!! Topcoder - Remove VM Management Feature In Direct App version 1.0
* - remove VM related functionality
*
- *
+ *
+ * + * Version 2.5 - Topcoder - Change Download URL in Direct Application + * - Add {@link #s3Client} + * - Add {@link #getS3Client()} to get S3 client instance + * - Add {@link #getS3FileKey(String)} to get S3 key from url + *
* @author BeBetter, isv, flexme, Blues, Veve, GreatKevin, minhu, FireIce, Ghost_141, jiajizhou86, TCSCODER - * @version 2.4 + * @version 2.5 */ public final class DirectUtils { @@ -1011,13 +1020,30 @@ public final class DirectUtils { "WHERE ls.example = 0 AND ls.long_component_state_id = lcs.long_component_state_id " + "AND lcs.round_id = r.round_id "; + /** + * AWS S3 client + */ + private static final AmazonS3Client s3Client; + + /** + * The AWS credentials file. + */ + private static final String AWS_CREDENTIALS_FILE = "AwsS3Credentials.properties"; /** * The jackson object mapping which is used to deserialize json return from API to domain model. */ protected static final ObjectMapper objectMapper; + static { objectMapper = new ObjectMapper(); + try { + ClassLoader loader = DirectUtils.class.getClassLoader(); + URL credentialURL = loader.getResource(AWS_CREDENTIALS_FILE); + s3Client = new AmazonS3Client(new PropertiesCredentials(new File(credentialURL.getFile()))); + } catch (Throwable e) { + throw new RuntimeException("Failed load to Amazon S3 Client", e); + } } /** @@ -4036,4 +4062,40 @@ public static void getMMRegistantsSubmissionInfo(List