diff --git a/.circleci/config.yml b/.circleci/config.yml index 3d337fabb..895955f0b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -8,10 +8,11 @@ install_dependency: &install_dependency command: | sed -i '/jessie-updates/d' /etc/apt/sources.list apt update - apt install -y openssl ant git zip jq + apt install -y --force-yes openssl ant git zip jq mkdir ~/awscli cd ~/awscli - curl "https://s3.amazonaws.com/aws-cli/awscli-bundle.zip" -o "awscli-bundle.zip" + #curl "https://s3.amazonaws.com/aws-cli/awscli-bundle.zip" -o "awscli-bundle.zip" + curl https://s3.amazonaws.com/aws-cli/awscli-bundle-1.16.188.zip -o awscli-bundle.zip unzip awscli-bundle.zip ./awscli-bundle/install -i /usr/local/aws -b /usr/local/bin/aws cd /usr/share/ant/lib @@ -24,7 +25,7 @@ install_dependency: &install_dependency install_deploysuite: &install_deploysuite name: Installation of install_deploysuite. command: | - git clone --branch v1.3 https://github.com/topcoder-platform/tc-deploy-scripts ../buildscript + git clone --branch v1.4.14 https://github.com/topcoder-platform/tc-deploy-scripts ../buildscript cp ./../buildscript/master_deploy.sh . cp ./../buildscript/buildenv.sh . cp ./../buildscript/awsconfiguration.sh . diff --git a/components/project_management/src/java/main/com/topcoder/management/project/ProjectGroup.java b/components/project_management/src/java/main/com/topcoder/management/project/ProjectGroup.java index 6f6566e7a..286bec052 100644 --- a/components/project_management/src/java/main/com/topcoder/management/project/ProjectGroup.java +++ b/components/project_management/src/java/main/com/topcoder/management/project/ProjectGroup.java @@ -22,12 +22,20 @@ *

* Changes related to v5-groups-api *

- * - * @author dushyantb - * @version 1.1 + * Version 1.2 (Fixing serilization error for ProjectGroup): + * + * @author dushyantb, vikasrohit + * @version 1.2 */ public class ProjectGroup implements Serializable { + /** + * Unique seriliazation version id + */ + private static final long serialVersionUID = 652485342267757690L; + /** * Represents group id */ diff --git a/components/project_management/src/java/main/com/topcoder/management/project/persistence/AbstractInformixProjectPersistence.java b/components/project_management/src/java/main/com/topcoder/management/project/persistence/AbstractInformixProjectPersistence.java index 24fc73082..8a49ed21a 100644 --- a/components/project_management/src/java/main/com/topcoder/management/project/persistence/AbstractInformixProjectPersistence.java +++ b/components/project_management/src/java/main/com/topcoder/management/project/persistence/AbstractInformixProjectPersistence.java @@ -502,7 +502,7 @@ public abstract class AbstractInformixProjectPersistence implements ProjectPersi * * @since 1.1.2 */ - public static final long PUBLIC_SUBMITTER_TERMS_ID = 21303; // 21193 // 21173 + public static final long PUBLIC_SUBMITTER_TERMS_ID = 21373; //21303 // 21193 // 21173 /** *

@@ -532,7 +532,7 @@ public abstract class AbstractInformixProjectPersistence implements ProjectPersi * * @since 1.1.2 */ - public static final long STANDARD_CCA_TERMS_ID = 21343; //21153; //21113; //20713; + public static final long STANDARD_CCA_TERMS_ID = 21374; //21343; //21153; //21113; //20713; diff --git a/conf/ApplicationServer.properties b/conf/ApplicationServer.properties index eb2ea5f6b..3ea626d8b 100644 --- a/conf/ApplicationServer.properties +++ b/conf/ApplicationServer.properties @@ -45,4 +45,7 @@ SSO_HASH_SECRET = @ApplicationServer.SSO_HASH_SECRET@ SSO_DOMAIN = @ApplicationServer.SSO_DOMAIN@ JWT_V3_COOKIE_KEY = @ApplicationServer.JWT_V3_COOKIE_KEY@ -JWT_COOKIE_KEY = @ApplicationServer.JWT_COOKIE_KEY@ \ No newline at end of file +JWT_COOKIE_KEY = @ApplicationServer.JWT_COOKIE_KEY@ + +TOPCODER_CONNECT_URL=@TopcoderConnectUrl@ +TOPCODER_NEW_AUTH_URL=@TopcoderNewAuthUrl@ diff --git a/conf/phase_templates/TCSTemplate_Studio.xml b/conf/phase_templates/TCSTemplate_Studio.xml index c249bc867..bb5320763 100644 --- a/conf/phase_templates/TCSTemplate_Studio.xml +++ b/conf/phase_templates/TCSTemplate_Studio.xml @@ -8,8 +8,6 @@ - - @@ -17,14 +15,7 @@ - - - - - - - diff --git a/services/contest_service_facade/build.version b/services/contest_service_facade/build.version index c10ca44fe..e08a51751 100644 --- a/services/contest_service_facade/build.version +++ b/services/contest_service_facade/build.version @@ -4,6 +4,6 @@ component.distfilename=contest_service_facade component.package=com.topcoder.service.facade.contest component.packagedir=com/topcoder/service/facade/contest component.version.major=1 -component.version.minor=1 +component.version.minor=2 component.version.micro=0 component.version.build=1 diff --git a/services/contest_service_facade/src/java/main/com/topcoder/service/facade/contest/ContestServiceFacade.java b/services/contest_service_facade/src/java/main/com/topcoder/service/facade/contest/ContestServiceFacade.java index 70d9ce871..6002cbbf4 100644 --- a/services/contest_service_facade/src/java/main/com/topcoder/service/facade/contest/ContestServiceFacade.java +++ b/services/contest_service_facade/src/java/main/com/topcoder/service/facade/contest/ContestServiceFacade.java @@ -595,7 +595,33 @@ public SoftwareCompetition createSoftwareContest(TCSubject tcSubject,SoftwareCom */ public SoftwareCompetition createSoftwareContest(TCSubject tcSubject, SoftwareCompetition contest, long tcDirectProjectId, Date multiRoundEndDate, Date endDate) throws ContestServiceException, PermissionServiceException; - + + /** + *

+ * Creates a new SoftwareCompetition in the persistence. + *

+ * Updated for Version 1.0.1 - BUGR-2185: For development contests, if asset (or component) exists from design + * contests then that is used to create a new contest. Otherwise a new asset is also created. Updated for Version1.5 + * the code is refactored by the logic: 1. check the permission 2. update or create the asset 3. set default + * resources 4. create project 5. prepare the return value 6. persist the eligility + *

+ * Update in v1.5.1: add parameter TCSubject which contains the security info for current user. + *

+ * @param tcSubject TCSubject instance contains the login security info for the current user + * @param contest the SoftwareCompetition to create as a contest + * @param tcDirectProjectId the TC direct project id. a long providing the ID of a client the new + * competition belongs to. + * @param multiRoundEndDate the end date for the multiround phase. No multiround if it's null. + * @param endDate the end date for submission phase. Can be null if to use default. + * @param skipForum true if skip forum creation + * @return the created SoftwareCompetition as a contest + * @throws IllegalArgumentException if the input argument is invalid. + * @throws ContestServiceException if an error occurs when interacting with the service layer. + * @since 1.6.4 + */ + public SoftwareCompetition createSoftwareContest(TCSubject tcSubject, SoftwareCompetition contest, + long tcDirectProjectId, Date multiRoundEndDate, Date endDate, boolean skipForum) throws ContestServiceException, PermissionServiceException; + /** *

* Creates a new SoftwareCompetition in the persistence. @@ -614,7 +640,28 @@ public SoftwareCompetition createSoftwareContest(TCSubject tcSubject, SoftwareCo */ public SoftwareCompetition createSoftwareContest(TCSubject tcSubject, SoftwareCompetition contest, long tcDirectProjectId, Date regEndDate, Date multiRoundEndDate, Date endDate) throws ContestServiceException, PermissionServiceException; - + + /** + *

+ * Creates a new SoftwareCompetition in the persistence. + *

+ * + * @param tcSubject TCSubject instance contains the login security info for the current user + * @param contest the SoftwareCompetition to create as a contest + * @param tcDirectProjectId the TC direct project id. a long providing the ID of a client the new + * competition belongs to. + * @param regEndDate the registration end date + * @param multiRoundEndDate the end date for the multiround phase. No multiround if it's null. + * @param endDate the end date for submission phase. Can be null if to use default. + * @param skipForum true if no need to create the forum + * @return the created SoftwareCompetition as a contest + * @throws IllegalArgumentException if the input argument is invalid. + * @throws ContestServiceException if an error occurs when interacting with the service layer. + */ + public SoftwareCompetition createSoftwareContest(TCSubject tcSubject, SoftwareCompetition contest, + long tcDirectProjectId, Date regEndDate, Date multiRoundEndDate, Date endDate, boolean skipForum) throws ContestServiceException, PermissionServiceException; + + /** *

* BURG-1716: We need to add a method to get software contest by project id, @@ -685,7 +732,7 @@ public SoftwareCompetition updateSoftwareContest(TCSubject tcSubject, */ public SoftwareCompetition updateSoftwareContest(TCSubject tcSubject, SoftwareCompetition contest, long tcDirectProjectId, Date multiRoundEndDate, Date endDate) throws ContestServiceException, PermissionServiceException; - + /** *

* Updates a SoftwareCompetition in the persistence. diff --git a/services/contest_service_facade/src/java/main/com/topcoder/service/facade/contest/ejb/ContestServiceFacadeBean.java b/services/contest_service_facade/src/java/main/com/topcoder/service/facade/contest/ejb/ContestServiceFacadeBean.java index a955bcd94..49928ae8d 100644 --- a/services/contest_service_facade/src/java/main/com/topcoder/service/facade/contest/ejb/ContestServiceFacadeBean.java +++ b/services/contest_service_facade/src/java/main/com/topcoder/service/facade/contest/ejb/ContestServiceFacadeBean.java @@ -2354,6 +2354,22 @@ private XMLGregorianCalendar getXMLGregorianCalendar(Date date) { } } + /** + *

+ * Adds the specified number of minutes to the given date and returns the result. + *

+ * + * @param date The Date to which to add the given minutes amount + * @param minutes The number of minutes to add to the given date (Can be negative) + * @return The resulting date = input date + number of minutes + */ + private Date addMinutesToDate(Date date, int minutes) { + Calendar cal = Calendar.getInstance(); + cal.setTime(date); + cal.add(Calendar.MINUTE, minutes); + return cal.getTime(); + } + /** *

* Processes the contest sale. @@ -3619,7 +3635,56 @@ private void checkContestBillingAccount(long billingAccountId, long directProjec public SoftwareCompetition createSoftwareContest(TCSubject tcSubject, SoftwareCompetition contest, long tcDirectProjectId, Date multiRoundEndDate, Date endDate) throws ContestServiceException, PermissionServiceException { - return createSoftwareContest(tcSubject, contest, tcDirectProjectId, null, null, null); + return createSoftwareContest(tcSubject, contest, tcDirectProjectId, null, null, false); + } + + /** + *

+ * Creates a new SoftwareCompetition in the persistence. + *

+ * Updated for Version 1.0.1 - BUGR-2185: For development contests, if asset (or + * component) exists from design contests then that is used to create a new + * contest. Otherwise a new asset is also created. Updated for Version1.5 the + * code is refactored by the logic: 1. check the permission 2. update or create + * the asset 3. set default resources 4. create project 5. prepare the return + * value 6. persist the eligility + *

+ * Update in v1.5.1: add parameter TCSubject which contains the security info + * for current user. + *

+ * + *

+ * Update in v1.8.3: Add handling of auto creation of bug hunt for assembly + * competition. If the assembly contest has bugHuntProjectHeader set and the + * properties not empty in bugHuntProjectHeader. A bug hunt contest is + * automatically created. The bug hunt contest will - have copilot inserted as + * reviewer (if exists) - use the start date of approval date as the start date + * and producation date of bug hunt contest. - add a "Bug Race For" link between + * the bug race contest and assembly contest + *

+ * + * @param tcSubject TCSubject instance contains the login security info + * for the current user + * @param contest the SoftwareCompetition to create as a + * contest + * @param tcDirectProjectId the TC direct project id. a long + * providing the ID of a client the new competition + * belongs to. + * @param multiRoundEndDate the end date for the multiround phase. No multiround + * if it's null. + * @param endDate the end date for submission phase. Can be null if to + * use default. + * @param skipForum true if no need to create the forum + * @return the created SoftwareCompetition as a contest + * @throws IllegalArgumentException if the input argument is invalid. + * @throws ContestServiceException if an error occurs when interacting with the + * service layer. + * @since 1.6.6 + */ + public SoftwareCompetition createSoftwareContest(TCSubject tcSubject, SoftwareCompetition contest, + long tcDirectProjectId, Date multiRoundEndDate, Date endDate, boolean skipForum) + throws ContestServiceException, PermissionServiceException { + return createSoftwareContest(tcSubject, contest, tcDirectProjectId, null, null, null, skipForum); } /** @@ -3647,8 +3712,41 @@ public SoftwareCompetition createSoftwareContest(TCSubject tcSubject, SoftwareCo public SoftwareCompetition createSoftwareContest(TCSubject tcSubject, SoftwareCompetition contest, long tcDirectProjectId, Date regEndDate, Date multiRoundEndDate, Date endDate) throws ContestServiceException, PermissionServiceException { - logger.debug("createSoftwareContest with information : [tcSubject = " + tcSubject.getUserId() - + ", tcDirectProjectId =" + tcDirectProjectId + ", multiRoundEndDate = " + multiRoundEndDate + "]"); + return createSoftwareContest( + tcSubject, contest, tcDirectProjectId, regEndDate, multiRoundEndDate, endDate, false); + } + + /** + *

+ * Creates a new SoftwareCompetition in the persistence. + *

+ * + * @param tcSubject TCSubject instance contains the login security info + * for the current user + * @param contest the SoftwareCompetition to create as a + * contest + * @param tcDirectProjectId the TC direct project id. a long + * providing the ID of a client the new competition + * belongs to. + * @param regEndDate the registration end date + * @param multiRoundEndDate the end date for the multiround phase. No multiround + * if it's null. + * @param endDate the end date for submission phase. Can be null if to + * use default. + * @param skipForum true if no need to create the forum + * + * @return the created SoftwareCompetition as a contest + * @throws IllegalArgumentException if the input argument is invalid. + * @throws ContestServiceException if an error occurs when interacting with the + * service layer. + */ + public SoftwareCompetition createSoftwareContest(TCSubject tcSubject, SoftwareCompetition contest, + long tcDirectProjectId, Date regEndDate, Date multiRoundEndDate, Date endDate, boolean skipForum) + throws ContestServiceException, PermissionServiceException { + logger.info("createSoftwareContest with information : [tcSubject = " + tcSubject.getUserId() + + ", tcDirectProjectId =" + tcDirectProjectId + + ", multiRoundEndDate = " + multiRoundEndDate + + ", skipForum = " + String.valueOf(skipForum) + "]"); try { ExceptionUtils.checkNull(contest, null, null, "The contest to create is null."); @@ -3699,7 +3797,7 @@ public SoftwareCompetition createSoftwareContest(TCSubject tcSubject, SoftwareCo checkBillingProjectCCA(contest); // update the AssetDTO and update corresponding properties - createUpdateAssetDTO(tcSubject, contest); + createUpdateAssetDTO(tcSubject, contest, skipForum); com.topcoder.management.resource.Resource[] contestResources = createContestResources(tcSubject, contest, billingProjectId, requireApproval); @@ -3999,10 +4097,11 @@ private boolean shouldAutoCreateBugHuntContest(SoftwareCompetition contest) { * @param tcSubject TCSubject instance contains the login security info for the * current user * @param contest the contest + * @param skipForum true if no need to create forum * @throws EntityNotFoundException if any error occurs * @throws com.topcoder.catalog.service.PersistenceException if any error occurs */ - private void createUpdateAssetDTO(TCSubject tcSubject, SoftwareCompetition contest) throws EntityNotFoundException, + private void createUpdateAssetDTO(TCSubject tcSubject, SoftwareCompetition contest, boolean skipForum) throws EntityNotFoundException, com.topcoder.catalog.service.PersistenceException, DAOException, ConfigManagerException { // check if it is going to create development contest boolean isDevContest = isDevContest(contest); @@ -4039,19 +4138,25 @@ else if (isDevContest) { } long forumId = 0; // create forum - if (createForum) { + if (createForum && !skipForum) { if (useExistingAsset && assetDTO.getForum() != null) { forumId = assetDTO.getForum().getJiveCategoryId(); } else { - if (!isStudio(contest)) { - // software contest - forumId = createForum(tcSubject, assetDTO, tcSubject.getUserId(), - contest.getProjectHeader().getProjectCategory().getId()); + if(isPrivateProject(contest)) { // no forum to be created for private tasks + logger.debug("Skip forum creation for private task: "+assetDTO.getName()); } else { - // studio contest - forumId = createStudioForum(assetDTO.getName(), tcSubject.getUserId()); + if (!isStudio(contest)) { + // software contest + forumId = createForum(tcSubject, assetDTO, tcSubject.getUserId(), + contest.getProjectHeader().getProjectCategory().getId()); + } else { + // studio contest + forumId = createStudioForum(assetDTO.getName(), tcSubject.getUserId()); + } } } + } else { + logger.info("Skip forum creation"); } // if forum created @@ -4203,10 +4308,8 @@ else if (isDevContest) { // "0"); // } - if (forumId > 0) { - contest.getProjectHeader().setProperty(ProjectPropertyType.DEVELOPER_FORUM_ID_PROJECT_PROPERTY_KEY, + contest.getProjectHeader().setProperty(ProjectPropertyType.DEVELOPER_FORUM_ID_PROJECT_PROPERTY_KEY, String.valueOf(forumId)); - } contest.getProjectPhases().setStartDate(getDate(productionDate)); } @@ -5516,8 +5619,9 @@ public Set updatePreRegister(TCSubject tcSubject, SoftwareCompetition cont removedUsers = uploadExternalServices.removeSubmitters(contest.getId(), removedUsers, String.valueOf(tcSubject.getUserId())); - // remove forum - if (createForum) { + // remove forum user permissions for public projects. + // private tasks do not have forums created + if (createForum && !isPrivateProject(contest)) { try { forumId = contest.getAssetDTO().getForum().getJiveCategoryId(); forum = getSoftwareForums(); @@ -5536,7 +5640,7 @@ public Set updatePreRegister(TCSubject tcSubject, SoftwareCompetition cont for (Long member : preRegisterMembers) { try { this.addSubmitter(tcSubject, contest.getId(), member); - if (createForum) { + if (createForum && !isPrivateProject(contest)) { forum.assignRole(member, userRoleId); } addedUsers.add(member); @@ -5966,7 +6070,7 @@ private long createStudioForum(String name, long userId) { logger.error("*** Could not create a studio forum for " + name); logger.error(e); } - return -1; + return 0; } /** @@ -6014,7 +6118,7 @@ public long createForum(TCSubject tcSubject, AssetDTO asset, long userId, long p logger.error("*** Could not create a forum for " + asset.getName()); logger.error(e); - return forumId; + return 0; } } @@ -7737,10 +7841,8 @@ else if (autoDevCreating && isDevContest) { dto.getForum().setCompVersion(null); } - if (forumId > 0) { - contest.getProjectHeader().setProperty(ProjectPropertyType.DEVELOPER_FORUM_ID_PROJECT_PROPERTY_KEY, + contest.getProjectHeader().setProperty(ProjectPropertyType.DEVELOPER_FORUM_ID_PROJECT_PROPERTY_KEY, String.valueOf(forumId)); - } contest.setStartDate(getDate(startDate)); // 3.create the project @@ -9862,25 +9964,30 @@ public void closeSoftwareContest(TCSubject tcSubject, long projectId, long winne DataHandler dataHandler = new DataHandler(new FileDataSource(mockSubmissionFilePath + mockSubmissionFileName)); long submissionId = uploadSubmission(winnerId, contest.getId(), mockSubmissionFileName, dataHandler); - // close submission and review phase + Date currentDate = new Date(); + // subtract one minute from the current date + // this will be used to set the registration start/end dates + Date oneMinuteEarlier = addMinutesToDate(currentDate, -1); + + // close registration, submission and review phases com.topcoder.project.phases.Phase submissionPhase = null; com.topcoder.project.phases.Phase reviewPhase = null; for (com.topcoder.project.phases.Phase phase : phases) { if (PROJECT_SUBMISSION_PHASE_NAME.equals(phase.getPhaseType().getName())) { if (phaseNeedToUpdate && !phaseHasClosed) { // submission is scheduled - phase.setActualStartDate(new Date()); - phase.setActualEndDate(new Date()); + phase.setActualStartDate(currentDate); + phase.setActualEndDate(currentDate); } else if (!phaseNeedToUpdate) { // phase already open - phase.setActualEndDate(new Date()); + phase.setActualEndDate(currentDate); } phase.setPhaseStatus(PhaseStatus.CLOSED); submissionPhase = phase; } else if (PROJECT_REVIEW_PHASE_NAME.equals(phase.getPhaseType().getName()) || PROJECT_ITERATIVE_REVIEW_PHASE_NAME.equals(phase.getPhaseType().getName())) { if (phase.getPhaseStatus().getId() == PhaseStatus.SCHEDULED.getId()) { - phase.setActualStartDate(new Date()); + phase.setActualStartDate(currentDate); phase.setScheduledEndDate(null); phase.setScheduledStartDate(phase.calcStartDate()); phase.setScheduledEndDate(phase.calcEndDate()); @@ -9890,6 +9997,21 @@ public void closeSoftwareContest(TCSubject tcSubject, long projectId, long winne // skiping closed iterative review reviewPhase = phase; } + } else if (PROJECT_REGISTRATION_PHASE_NAME.equals(phase.getPhaseType().getName())) { + if (phase.getActualStartDate() != null) { + // The registration phase is already started, we only need to set the end date if not set already + // The actual end date is set to one minute earlier than the submission phase + // This will ensure that the phases are shown in the correct order in Online Review + if(phase.getActualEndDate() == null ) { + phase.setActualEndDate(oneMinuteEarlier); + } + } else { + // The registration phase is not opened yet (start date is in the future) + phase.setActualStartDate(oneMinuteEarlier); + phase.setActualEndDate(oneMinuteEarlier); + } + // Set the registration status to closed + phase.setPhaseStatus(PhaseStatus.CLOSED); } } projectPhases.setPhases(new HashSet(Arrays.asList(phases))); diff --git a/src/java/main/com/topcoder/direct/services/configs/ServerConfiguration.java b/src/java/main/com/topcoder/direct/services/configs/ServerConfiguration.java index b678e1b92..79e146711 100644 --- a/src/java/main/com/topcoder/direct/services/configs/ServerConfiguration.java +++ b/src/java/main/com/topcoder/direct/services/configs/ServerConfiguration.java @@ -58,4 +58,14 @@ public class ServerConfiguration extends ApplicationServer { public static String JWT_V3_COOKIE_KEY = bundle.getProperty("JWT_V3_COOKIE_KEY", "v3jwt"); public static String JWT_COOKIE_KEY = bundle.getProperty("JWT_COOKIE_KEY", "tcjwt"); + + /** + * The Topcoder Connect URL + */ + public static String TOPCODER_CONNECT_URL = bundle.getProperty("TOPCODER_CONNECT_URL", "https://connect.topcoder.com"); + + /** + * Topcoder - New Auth URL to refresh token + */ + public static String TOPCODER_NEW_AUTH_URL = bundle.getProperty("TOPCODER_NEW_AUTH_URL", ""); } diff --git a/src/java/main/com/topcoder/direct/services/view/action/contest/launch/GetContestAction.java b/src/java/main/com/topcoder/direct/services/view/action/contest/launch/GetContestAction.java index d1c95484a..6d2430238 100644 --- a/src/java/main/com/topcoder/direct/services/view/action/contest/launch/GetContestAction.java +++ b/src/java/main/com/topcoder/direct/services/view/action/contest/launch/GetContestAction.java @@ -474,7 +474,7 @@ protected void executeAction() throws Exception { List projectGroups = DirectUtils.getGroupIdAndName( softwareCompetition.getProjectHeader().getGroups()); - if (this.type == TYPE.CONTEST_JSON) { + if (projectGroups != null && this.type == TYPE.CONTEST_JSON) { // get v5 id of groups Set> projectGroupUser = DirectUtils.getGroups(DirectUtils.getTCSubjectFromSession(), userGroupsApiEndpoint); diff --git a/src/java/main/com/topcoder/direct/services/view/action/contest/launch/GetGroupMemberAction.java b/src/java/main/com/topcoder/direct/services/view/action/contest/launch/GetGroupMemberAction.java index dc31dc0bc..49ee4f78c 100644 --- a/src/java/main/com/topcoder/direct/services/view/action/contest/launch/GetGroupMemberAction.java +++ b/src/java/main/com/topcoder/direct/services/view/action/contest/launch/GetGroupMemberAction.java @@ -232,7 +232,7 @@ private List getGroupMemberByGid(String gid) throws Exception { } jsonNode = objectMapper.readTree(entity.getContent()); - List groupMembers = objectMapper.readValue(jsonNode.path("result"), + List groupMembers = objectMapper.readValue(jsonNode, new TypeReference>(){}); for (GroupMember groupMember : groupMembers) { result.add(groupMember); diff --git a/src/java/main/com/topcoder/direct/services/view/ajax/CustomFormatAJAXResult.java b/src/java/main/com/topcoder/direct/services/view/ajax/CustomFormatAJAXResult.java index 2cf7da282..35fbadda6 100644 --- a/src/java/main/com/topcoder/direct/services/view/ajax/CustomFormatAJAXResult.java +++ b/src/java/main/com/topcoder/direct/services/view/ajax/CustomFormatAJAXResult.java @@ -8,6 +8,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.net.SocketException; import java.nio.charset.Charset; import java.nio.charset.IllegalCharsetNameException; import java.util.zip.GZIPOutputStream; @@ -24,6 +25,7 @@ import com.topcoder.direct.services.view.action.contest.launch.AggregateDataModel; import com.topcoder.direct.services.view.ajax.processors.DefaultAJAXResultPreProcessor; import com.topcoder.direct.services.view.ajax.serializers.JSONDataSerializer; +import org.apache.log4j.Logger; /** *

@@ -81,6 +83,13 @@ *

* *

+ * Version 1.2 + *

    + *
  • Fixed crash - java.net.SocketException: Broken pipe
  • + *
+ *

+ * + *

* Thread safety: Technically this class is NOT thread safe since it has mutable states, but the intended * usage of the mutators is for IoC injection and thus we expect for these values not to be changed after * initialization. Thus this class can be considered as thread-safe conditional in an IoC injection usage of @@ -88,7 +97,7 @@ *

* * @author AleaActaEst, TCSDEVELOPER, duxiaoyang - * @version 1.1 + * @version 1.2 */ @SuppressWarnings("serial") public class CustomFormatAJAXResult implements Result { @@ -177,6 +186,8 @@ public class CustomFormatAJAXResult implements Result { */ private boolean enabledGzip = false; + private Logger logger = Logger.getLogger(CustomFormatAJAXResult.class); + /** *

* Default constructor. @@ -290,7 +301,7 @@ public void execute(ActionInvocation invocation) throws AJAXDataPreProcessingExc * @throws IOException * if any io error happens */ - private static void writeDataAndClose(InputStream in, OutputStream out) throws IOException { + private void writeDataAndClose(InputStream in, OutputStream out) throws IOException { try { // Write input stream to output stream byte[] buf = new byte[BUFFER_SIZE]; @@ -300,11 +311,14 @@ private static void writeDataAndClose(InputStream in, OutputStream out) throws I } // flush output stream out.flush(); + } catch (IOException e) { + // The client side has aborted or closed connection + logger.error("The client side has aborted or closed connection", e); } finally { // close the input stream closeStream(in); // close the output stream - out.close(); + closeStream(out); } } 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 7d7a46ecb..85c3aaba7 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 @@ -1041,7 +1041,7 @@ public final class DirectUtils { /** * Default value url parameter perPage */ - private static final String PER_PAGE_VALUE = "1000"; + private static final String PER_PAGE_VALUE = "2000"; /** * The jackson object mapping which is used to deserialize json return from API to domain model. @@ -3876,6 +3876,7 @@ public static Set> getGroupsFromApi(TCSubject tcSubject, Str if (!DirectUtils.isCockpitAdmin(tcSubject) && !DirectUtils.isTcStaff(tcSubject)) { uri.setParameter("memberId", String.valueOf(tcSubject.getUserId())); + uri.setParameter("membershipType", "user"); } uri.setParameter(PER_PAGE, PER_PAGE_VALUE); diff --git a/src/web/WEB-INF/includes/footerScripts.jsp b/src/web/WEB-INF/includes/footerScripts.jsp index eefc32d38..9cd4e069f 100644 --- a/src/web/WEB-INF/includes/footerScripts.jsp +++ b/src/web/WEB-INF/includes/footerScripts.jsp @@ -10,6 +10,7 @@ <%@ page import="com.topcoder.direct.services.view.util.DirectUtils" %> <%@ page import="com.topcoder.direct.services.view.util.SessionData" %> <%@ page import="javax.servlet.http.HttpServletRequest" %> +<%@ page import="com.topcoder.direct.services.configs.ServerConfiguration" %> <% String handle = (String) request.getSession().getAttribute("userHandle"); @@ -21,9 +22,8 @@ %> - + + + + diff --git a/src/web/WEB-INF/includes/launch/contestSelection.jsp b/src/web/WEB-INF/includes/launch/contestSelection.jsp index 2ed3b18fb..cf3893ff6 100644 --- a/src/web/WEB-INF/includes/launch/contestSelection.jsp +++ b/src/web/WEB-INF/includes/launch/contestSelection.jsp @@ -133,9 +133,11 @@ + diff --git a/src/web/WEB-INF/includes/newHeader.jsp b/src/web/WEB-INF/includes/newHeader.jsp index d7d66878f..d818ec6fc 100644 --- a/src/web/WEB-INF/includes/newHeader.jsp +++ b/src/web/WEB-INF/includes/newHeader.jsp @@ -25,15 +25,17 @@ - - Version 1.7 (TOPCODER - REMOVE TASKS TAB IN DIRECT APP) - - Remove tasks tab - - - - Version 1.4 (Quick72Hrs!! Topcoder - Remove VM Management Feature In Direct App version 1.0) - - remove the vm related things + - + - Version 1.4 (Quick72Hrs!! Topcoder - Remove VM Management Feature In Direct App version 1.0) + - remove the vm related things - - Description: The new cockpit header and navigation. --%> <%@ page import="com.topcoder.direct.services.configs.ServerConfiguration" %> <%@ include file="/WEB-INF/includes/taglibs.jsp" %> + +

@@ -132,7 +134,7 @@
  • - ">Start New + Start New
  • @@ -422,7 +424,7 @@ diff --git a/src/web/WEB-INF/includes/right.jsp b/src/web/WEB-INF/includes/right.jsp index 7dc8e8bbe..527e71ac6 100644 --- a/src/web/WEB-INF/includes/right.jsp +++ b/src/web/WEB-INF/includes/right.jsp @@ -32,16 +32,18 @@ - the data via ajax. - --%> +<%@ page import="com.topcoder.direct.services.configs.ServerConfiguration" %> <%@ include file="/WEB-INF/includes/taglibs.jsp" %> + +
    diff --git a/src/web/WEB-INF/launch-contest.jsp b/src/web/WEB-INF/launch-contest.jsp index 454f0bfb2..ea351bae2 100644 --- a/src/web/WEB-INF/launch-contest.jsp +++ b/src/web/WEB-INF/launch-contest.jsp @@ -339,7 +339,7 @@
    -

    In some cases, when clients would like to hold a "private" competition that has confidentiality terms in addition to the usual click-through terms, the competition will require a Non-Disclosure Agreement or "NDA" document to be completed prior to participation in the competition. https://www.topcoder.com/
    challenge-details/terms/
    detail/21343/

    +

    In some cases, when clients would like to hold a "private" competition that has confidentiality terms in addition to the usual click-through terms, the competition will require a Non-Disclosure Agreement or "NDA" document to be completed prior to participation in the competition. https://www.topcoder.com/
    challenge-details/terms/
    detail/21374/

diff --git a/src/web/scripts/launch/entity.js b/src/web/scripts/launch/entity.js index aae91c77f..ee1c2efee 100644 --- a/src/web/scripts/launch/entity.js +++ b/src/web/scripts/launch/entity.js @@ -214,16 +214,16 @@ var ESTIMATE_EFFORT_ONSITE = "Estimate Efforts Days Onsite"; var projectCategoryArray = [ {id:32, name:'Application Front-End Design', label:'Application Front-End Design', typeId:3, typeName:'Studio', hasMulti:true, hideInDropdown: false}, - {id:STUDIO_CATEGORY_ID_DESIGN_F2F, name:'Design First2Finish', label:'Design First2Finish', typeId:3, typeName:'Studio', hasMulti:false, hideInDropdown: false}, - {id:22, name:'Idea Generation', label:'Idea Generation', typeId:3, typeName:'Studio', hasMulti:true, hideInDropdown: false}, + {id:STUDIO_CATEGORY_ID_DESIGN_F2F, name:'Design First2Finish', label:'Design First2Finish', typeId:3, typeName:'Studio', hasMulti:false, hideInDropdown: true}, + {id:22, name:'Idea Generation', label:'Idea Generation', typeId:3, typeName:'Studio', hasMulti:true, hideInDropdown: true}, {id:21, name:'Print/Presentation', label:'Print/Presentation', typeId:3, typeName:'Studio', hasMulti:true, hideInDropdown: false}, {id:17, name:'Web Design', label:'Web Design', typeId:3, typeName:'Studio', hasMulti:true, hideInDropdown: false}, {id:30, name:'Widget or Mobile Screen Design', label:'Widget or Mobile Screen Design', typeId:3, typeName:'Studio', hasMulti:true, hideInDropdown: false}, {id:18, name:'Wireframes', label:'Wireframes', typeId:3, typeName:'Studio', hasMulti:true, hideInDropdown: false}, - {id:SOFTWARE_CATEGORY_ID_BUG_HUNT, name:'Bug Hunt', label:'Bug Hunt', typeId:2, typeName:'Application', hasMulti:false, hideInDropdown: false}, - {id:SOFTWARE_CATEGORY_ID_CODE, name:'Code', label:'Code', typeId:2, typeName:'Application', hasMulti:false, hideInDropdown: false}, - {id:SOFTWARE_CATEGORY_ID_F2F, name:'First2Finish', label:'First2Finish', typeId:2, typeName:'Application', hasMulti:false, hideInDropdown: false}, - {id:13, name:'TESTSUITES', label:'Test Suites', typeId:2, typeName:'Application', hasMulti:true, hideInDropdown: false}, + {id:SOFTWARE_CATEGORY_ID_BUG_HUNT, name:'Bug Hunt', label:'Bug Hunt', typeId:2, typeName:'Application', hasMulti:false, hideInDropdown: true}, + {id:SOFTWARE_CATEGORY_ID_CODE, name:'Code', label:'Code', typeId:2, typeName:'Application', hasMulti:false, hideInDropdown: true}, + {id:SOFTWARE_CATEGORY_ID_F2F, name:'First2Finish', label:'First2Finish', typeId:2, typeName:'Application', hasMulti:false, hideInDropdown: true}, + {id:13, name:'TESTSUITES', label:'Test Suites', typeId:2, typeName:'Application', hasMulti:true, hideInDropdown: true}, {id:SOFTWARE_CATEGORY_ID_CONCEPT, name:'CONCEPTUALIZATION', label:'Software Conceptualization', typeId:2, typeName:'Application', hasMulti:true, hideInDropdown: true}, {id:SOFTWARE_CATEGORY_ID_SPEC, name:'SPECIFICATION', label:'Software Specification', typeId:2, typeName:'Application', hasMulti:true, hideInDropdown: true}, {id:7, name:'ARCHITECTURE', label:'Architecture', typeId:2, typeName:'Application', hasMulti:true, hideInDropdown: true}, diff --git a/src/web/scripts/launchcontest.js b/src/web/scripts/launchcontest.js index e28894093..00f21a13d 100644 --- a/src/web/scripts/launchcontest.js +++ b/src/web/scripts/launchcontest.js @@ -467,7 +467,8 @@ $(document).ready(function() { // populate the select option for software group $.each(projectCategoryArray, function(i, projectCategory) { if (projectCategory.hideInDropdown) { - return; + //Commented out on Aug 11, 2021 to help hide challenge types from the create dropdown in entity.js + //return; } // not show copilot contest type if (projectCategory.id != 29 && projectCategory.id != ALGORITHM_CATEGORY_ID_MARATHON && projectCategory.typeId != 3) { diff --git a/token.properties.docker b/token.properties.docker index a4cbc11d0..b455eed37 100644 --- a/token.properties.docker +++ b/token.properties.docker @@ -105,7 +105,7 @@ @payFlowPartner@=PayPal @payFlowVendor@=tcTestAccount2 @payFlowPassword@=password123 -@createForum@=false +@createForum@=true @userBeanProviderUrl@=jnp://localhost:1199 @projectBeanProviderUrl@=jnp://localhost:1199 @@ -322,7 +322,7 @@ @DOMAIN_AUTH0@ = sma.auth0.com @CLIENT_ID_AUTH0@ = @CLIENT_SECRET_AUTH0@ = -@JWT_V3_SECRET@ = +@JWT_V3_SECRET@ = secret @REG_SERVER_NAME@= tc.cloud.topcoder.com @LDAP_AUTH0_CONNECTION_NAME@=vm-ldap-connection @JWT_VALID_ISSUERS@ = https://api.topcoder.com, https://sma.auth0.com, https://newtc.auth0.com, https://topcoder-newauth.auth0.com/ @@ -337,16 +337,19 @@ @ApplicationServer.JWT_COOKIE_KEY@=tcjwt_vm @ApplicationServer.JWT_V3_COOKIE_KEY@=v3jwt -@memberSearchApiUrl@=https://tc-api.cloud.topcoder.com:8443/v3/members/_suggest/ +@memberSearchApiUrl@=http://cockpit.cloud.topcoder.com:8443/v3/members/_suggest/ @groupMemberSearchApiUrl@=https://cockpit.cloud.topcoder.com/direct/group/member?handle= -@groupMemberApiUrl@=http://tc-api.cloud.topcoder.com:8080/v3/groups/%d/members +@groupMemberApiUrl@=http://192.168.1.3:4000/v5/groups/%s/members @directChallengeServicesApiUrl@=http://api.topcoder-dev.com/v3/direct/challenges @authorizationUrl@=https://api.topcoder-dev.com/v3/authorizations -@userGroupsApiEndpoint@=http://tc-api.cloud.topcoder.com:3000/api/v5/groups +@userGroupsApiEndpoint@=http://192.168.1.3:4000/v5/groups @aws_s3_bucket@=topcoder-dev-submissions @aws_s3_access_key@= @aws_s3_secret_key@= @trialBillingId@ = -@defaultGroupIdForTrial@ = \ No newline at end of file +@defaultGroupIdForTrial@ = + +# The Topcoder Connect Url to which the projects creation will redirect +@TopcoderConnectUrl@=https://connect.topcoder-dev.com \ No newline at end of file diff --git a/token.properties.example b/token.properties.example index 9a6daba85..465d84f89 100644 --- a/token.properties.example +++ b/token.properties.example @@ -397,4 +397,7 @@ @authorizationUrl@=http://api.topcoder-dev.com/v3/authorizations @userGroupsApiEndpoint@=http://172.18.0.1:8080/v3/groups @trialBillingId@ = 3 -@defaultGroupIdForTrial@ = 12347 \ No newline at end of file +@defaultGroupIdForTrial@ = 12347 + +# The Topcoder Connect Url to which the projects creation will redirect +@TopcoderConnectUrl@=https://connect.topcoder.com \ No newline at end of file diff --git a/topcoder_global.properties.docker b/topcoder_global.properties.docker index 049b17b4e..ec3b90ef4 100644 --- a/topcoder_global.properties.docker +++ b/topcoder_global.properties.docker @@ -1,20 +1,20 @@ -base=/root/direct -libdir=${base}/lib -tcs_libdir=${libdir}/tcs -direct_service_libdir=${libdir}/tcs/ejb -jar_tcs_libdir=${libdir}/tcs -cronos_libdir=${libdir}/tcs -ext_libdir=${libdir}/third_party -jar_ext_libdir==${libdir}/third_party -jboss.home=/data/jboss-4.2.3.GA -jboss_home=${jboss.home} -server.name=default -jboss.config.name=${server.name} -jboss_config_name=${server.name} -jboss_lib=${jboss.home}/server/${server.name}/lib -apache_tcdocs=/mnt/apache/tcdocs - -# The svn user, it is optional, then the cached username/password will be used. -# Uncomment and configure these settings if you want to use predefined svn credentials. -#svn.username=xxx -#svn.password=xxx +base=/data +libdir=${base}/lib +tcs_libdir=${libdir}/tcs +direct_service_libdir=${libdir}/tcs/ejb +jar_tcs_libdir=${libdir}/tcs +cronos_libdir=${libdir}/tcs +ext_libdir=${libdir}/third_party +jar_ext_libdir==${libdir}/third_party +jboss.home=/data/jboss-4.2.3.GA +jboss_home=${jboss.home} +server.name=default +jboss.config.name=${server.name} +jboss_config_name=${server.name} +jboss_lib=${jboss.home}/server/${server.name}/lib +apache_tcdocs=/mnt/apache/tcdocs + +# The svn user, it is optional, then the cached username/password will be used. +# Uncomment and configure these settings if you want to use predefined svn credentials. +#svn.username=xxx +#svn.password=xxx