diff --git a/.circleci/config.yml b/.circleci/config.yml
index ac35f0cf5..c30ac9bde 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -24,24 +24,14 @@ jobs:
wget http://downloads.sourceforge.net/project/jboss/JBoss/JBoss-4.2.3.GA/jboss-4.2.3.GA-jdk6.zip
unzip jboss-4.2.3.GA-jdk6.zip
cd project
- - run:
- name: checking out build repo
- command: |
- git clone --branch master https://github.com/topcoder-platform/tc-deploy-scripts ../buildscript
- #git clone --branch master git@github.com:appirio-tech/ops.git ../direct-config-update
- #git clone --branch master https://$GITUSER:$GITPASSWD@github.com/appirio-tech/ops ../direct-config-update
- checkout
- - run:
- name: copying configuration file
- command: |
- cp ./../buildscript/direct/conf/dev/token.properties.enc .
- openssl enc -aes-256-cbc -d -in token.properties.enc -out token.properties -k $SECPASSWD
- run:
name: Installation of build dependencies.
command: |
javac -version
ant -version
aws --version
+ ./buildproperties.sh -e DEV -k directapp
ant package-direct package-static-direct
- store_artifacts:
path: ./direct.jar
@@ -148,24 +138,14 @@ jobs:
wget http://downloads.sourceforge.net/project/jboss/JBoss/JBoss-4.2.3.GA/jboss-4.2.3.GA-jdk6.zip
unzip jboss-4.2.3.GA-jdk6.zip
cd project
- - run:
- name: checking out build repo
- command: |
- git clone --branch master https://github.com/topcoder-platform/tc-deploy-scripts ../buildscript
- #git clone --branch master git@github.com:appirio-tech/ops.git ../direct-config-update
- #git clone --branch master https://$GITUSER:$GITPASSWD@github.com/appirio-tech/ops ../direct-config-update
- checkout
- - run:
- name: copying configuration file
- command: |
- cp ./../buildscript/direct/conf/prod/token.properties.enc .
- openssl enc -aes-256-cbc -d -in token.properties.enc -out token.properties -k $SECPASSWD
- run:
name: Installation of build dependencies.
command: |
javac -version
ant -version
aws --version
+ ./buildproperties.sh -e PROD -k directapp
ant package-direct package-static-direct
- store_artifacts:
path: ./direct.jar
diff --git a/README.md b/README.md
index 405610ab3..0551134a0 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@ direct-app
==========
## building
-To build, download the docker build container that has all of the build dependencies. You can then run the container to build your local source code.
+To build, download the docker build container that has all of the build dependencies. You can then run the container to build your local source code.
1. Clone the github source directory
2. Rename `token.properties.docker` to `token.properties` in the source directory
diff --git a/build-package.sh b/build-package.sh
index 33f4ce17a..665ecc682 100755
--- a/build-package.sh
+++ b/build-package.sh
@@ -8,6 +8,7 @@ then
fi
VER=`date "+%Y%m%d%H%M"`
+SCRIPTDIR="./scripts"
directapp_cdpacakge()
{
@@ -16,7 +17,7 @@ directapp_cdpacakge()
source $BUILD_VARIABLE_FILE_NAME
AWS_CD_PACKAGE_NAME="${APPNAME}-${PACKAGETYPE}-${VER}.zip"
PACAKAGE_LOCATION="dist-${PACKAGETYPE}"
- SCRIPTDIR="./../buildscript/direct/scripts"
+# SCRIPTDIR="./../buildscript/direct/scripts"
rm -rf $PACAKAGE_LOCATION
mkdir $PACAKAGE_LOCATION
#cd $PACAKAGE_LOCATION
diff --git a/build.xml b/build.xml
index a5db1b321..e6a622978 100644
--- a/build.xml
+++ b/build.xml
@@ -359,6 +359,7 @@
+ * 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