Skip to content
This repository was archived by the owner on Jan 23, 2025. It is now read-only.

Commit 5c14a93

Browse files
committed
improve group selection
1 parent d49c967 commit 5c14a93

File tree

7 files changed

+185
-153
lines changed

7 files changed

+185
-153
lines changed

conf/web/WEB-INF/applicationContext.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,7 @@
425425
<bean id="saveDraftContestAction"
426426
class="com.topcoder.direct.services.view.action.contest.launch.SaveDraftContestAction"
427427
parent="contestAction" scope="prototype">
428+
<property name="userGroupsApiEndpoint" value="@userGroupsApiEndpoint@"/>
428429
</bean>
429430

430431
<bean id="documentUploadAction" class="com.topcoder.direct.services.view.action.contest.launch.DocumentUploadAction"

src/java/main/com/topcoder/direct/services/view/action/contest/launch/CommonAction.java

Lines changed: 8 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,10 @@
33
*/
44
package com.topcoder.direct.services.view.action.contest.launch;
55

6-
import java.net.URI;
7-
import java.util.*;
8-
96
import com.topcoder.clients.model.Project;
107
import com.topcoder.clients.model.ProjectContestFee;
118
import com.topcoder.clients.model.ProjectContestFeePercentage;
12-
import com.topcoder.direct.services.configs.AlgorithmSubtypeContestFee;
139
import com.topcoder.direct.services.configs.ConfigUtils;
14-
import com.topcoder.direct.services.configs.ContestFee;
15-
import com.topcoder.direct.services.configs.StudioSubtypeContestFee;
1610
import com.topcoder.direct.services.project.metadata.entities.dao.DirectProjectAccess;
1711
import com.topcoder.direct.services.project.milestone.model.Milestone;
1812
import com.topcoder.direct.services.project.milestone.model.MilestoneStatus;
@@ -21,28 +15,20 @@
2115
import com.topcoder.direct.services.view.dto.IdNamePair;
2216
import com.topcoder.direct.services.view.dto.contest.ContestCopilotDTO;
2317
import com.topcoder.direct.services.view.dto.contest.ProblemDTO;
24-
import com.topcoder.direct.services.view.dto.contest.TypedContestBriefDTO;
2518
import com.topcoder.direct.services.view.dto.contest.ReviewScorecardDTO;
19+
import com.topcoder.direct.services.view.dto.contest.TypedContestBriefDTO;
2620
import com.topcoder.direct.services.view.util.AuthorizationProvider;
2721
import com.topcoder.direct.services.view.util.DataProvider;
2822
import com.topcoder.direct.services.view.util.DirectUtils;
29-
import com.topcoder.direct.services.view.util.JwtTokenUpdater;
3023
import com.topcoder.direct.services.view.util.challenge.CostCalculationService;
24+
import com.topcoder.management.project.ProjectGroup;
3125
import com.topcoder.security.TCSubject;
3226
import com.topcoder.service.facade.contest.ContestServiceException;
3327
import com.topcoder.service.facade.project.DAOFault;
34-
import com.topcoder.util.log.Level;
3528
import org.apache.commons.lang3.StringEscapeUtils;
36-
import org.apache.http.HttpEntity;
37-
import org.apache.http.HttpHeaders;
38-
import org.apache.http.HttpResponse;
39-
import org.apache.http.HttpStatus;
40-
import org.apache.http.client.methods.HttpGet;
41-
import org.apache.http.client.utils.URIBuilder;
42-
import org.apache.http.impl.client.DefaultHttpClient;
43-
import org.codehaus.jackson.JsonNode;
4429
import org.codehaus.jackson.map.ObjectMapper;
45-
import com.topcoder.management.project.ProjectGroup;
30+
31+
import java.util.*;
4632

4733
/**
4834
* <p>
@@ -137,15 +123,10 @@ public class CommonAction extends BaseContestFeeAction {
137123

138124
private long categoryId;
139125

140-
private String userGroupsApiEndpoint;
141-
142126
/**
143-
* The jackson object mapping which is used to deserialize json return from API to domain model.
127+
* Endpoint to group of a user
144128
*/
145-
protected static final ObjectMapper objectMapper;
146-
static {
147-
objectMapper = new ObjectMapper();
148-
}
129+
private String userGroupsApiEndpoint;
149130

150131
/**
151132
* <p>
@@ -577,40 +558,8 @@ public void setCategoryId(long categoryId) {
577558
public String getGroups() {
578559
try {
579560
TCSubject tcSubject = DirectUtils.getTCSubjectFromSession();
580-
URIBuilder uri = new URIBuilder(userGroupsApiEndpoint);
581-
582-
if (!DirectUtils.isCockpitAdmin(tcSubject) && !DirectUtils.isTcStaff(tcSubject)) {
583-
uri.setParameter("memberId", String.valueOf(tcSubject.getUserId()));
584-
}
585-
586-
DefaultHttpClient httpClient = new DefaultHttpClient();
587-
588-
HttpGet getRequest = new HttpGet(uri.build());
589-
getLogger().log(Level.INFO, "Getting Group with thi uri: " + uri.build().toString());
590-
591-
String v3Token = new JwtTokenUpdater().check().getToken();
592-
593-
getRequest.setHeader(HttpHeaders.AUTHORIZATION, "Bearer " + v3Token);
594-
595-
getRequest.addHeader(HttpHeaders.ACCEPT, "application/json");
596-
HttpResponse httpResponse = httpClient.execute(getRequest);
597-
598-
HttpEntity entity = httpResponse.getEntity();
599-
600-
if (httpResponse.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
601-
throw new Exception("Unable to get groups from the API:" + httpResponse.getStatusLine().getReasonPhrase());
602-
}
603-
604-
JsonNode result = objectMapper.readTree(entity.getContent());
605-
JsonNode groups = result.path("result").path("content");
606-
Set<Map<String, String>> groupResults = new HashSet<Map<String, String>>();
607-
for (JsonNode group : groups) {
608-
Map<String,String> gr = new HashMap<String, String>();
609-
gr.put("id", group.get("id").asText());
610-
gr.put("name", group.get("name").asText());
611-
groupResults.add(gr);
612-
}
613-
setResult(groupResults);
561+
Set<ProjectGroup> projectGroups = DirectUtils.getGroups(tcSubject, userGroupsApiEndpoint);
562+
setResult(projectGroups);
614563
} catch (Throwable e) {
615564
if (getModel() != null) {
616565
setResult(e);

src/java/main/com/topcoder/direct/services/view/action/contest/launch/SaveDraftContestAction.java

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -742,6 +742,11 @@ public class SaveDraftContestAction extends ContestAction {
742742
*/
743743
private Double customCopilotFee;
744744

745+
/**
746+
* Endpoint to group of a user
747+
*/
748+
private String userGroupsApiEndpoint;
749+
745750
/**
746751
* <p>
747752
* Creates a <code>SaveDraftContestAction</code> instance.
@@ -1066,25 +1071,15 @@ public boolean evaluate(Object object) {
10661071
populateSoftwareCompetition(softwareCompetition);
10671072
}
10681073

1069-
//set groups
1070-
List<ProjectGroup> groupsList = new ArrayList<ProjectGroup>();
1071-
//read-only group we need to set it with current group
1072-
if (!DirectUtils.isRole(getCurrentUser(), ADMIN_ROLE) && !DirectUtils.isRole(getCurrentUser(), TC_STAFF_ROLE) && projectId > 0) {
1073-
groupsList = getContestServiceFacadeWithISE().getGroupForContest(projectId, false);
1074-
groups = null;
1075-
}
1074+
//do backend validation for groups here
1075+
List<ProjectGroup> projectGroups = new ArrayList<ProjectGroup>();
10761076
if (groups != null && groups.size() > 0) {
1077-
// get the TCSubject from session
1078-
ProjectGroup[] allProjectGroups = getContestServiceFacade().getAllProjectGroups(DirectStrutsActionsHelper.getTCSubjectFromSession());
10791077
for (String groupId : groups) {
1080-
for (ProjectGroup projectGroup : allProjectGroups) {
1081-
if (Long.valueOf(groupId).equals(projectGroup.getId())) {
1082-
groupsList.add(projectGroup);
1083-
}
1084-
}
1078+
projectGroups.add(new ProjectGroup(Long.valueOf(groupId), ""));
10851079
}
10861080
}
1087-
softwareCompetition.getProjectHeader().setGroups(groupsList);
1081+
1082+
softwareCompetition.getProjectHeader().setGroups(projectGroups);
10881083

10891084
// remove the thurgood information if needed
10901085
if(softwareCompetition.getProjectHeader().getProperties().containsKey(THURGOOD_PLATFORM_KEY)) {
@@ -2565,6 +2560,14 @@ public void setPreRegisterUsers(String preRegisterUsers) {
25652560
this.preRegisterUsers = preRegisterUsers;
25662561
}
25672562

2563+
public String getUserGroupsApiEndpoint() {
2564+
return userGroupsApiEndpoint;
2565+
}
2566+
2567+
public void setUserGroupsApiEndpoint(String userGroupsApiEndpoint) {
2568+
this.userGroupsApiEndpoint = userGroupsApiEndpoint;
2569+
}
2570+
25682571
/**
25692572
* Pre-Register users to a given project
25702573
*

src/java/main/com/topcoder/direct/services/view/util/DirectUtils.java

Lines changed: 94 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,9 @@
1616
import com.topcoder.direct.services.project.metadata.entities.dao.DirectProjectMetadata;
1717
import com.topcoder.direct.services.view.action.AbstractAction;
1818
import com.topcoder.direct.services.view.action.BaseDirectStrutsAction;
19-
import com.topcoder.direct.services.view.dto.contest.TermOfUse;
2019
import com.topcoder.direct.services.view.action.specreview.ViewSpecificationReviewActionResultData;
2120
import com.topcoder.direct.services.view.dto.IdNamePair;
22-
import com.topcoder.direct.services.view.dto.contest.BaseContestCommonDTO;
23-
import com.topcoder.direct.services.view.dto.contest.ContestBriefDTO;
24-
import com.topcoder.direct.services.view.dto.contest.ContestDashboardDTO;
25-
import com.topcoder.direct.services.view.dto.contest.ContestRoundType;
26-
import com.topcoder.direct.services.view.dto.contest.ContestStatsDTO;
27-
import com.topcoder.direct.services.view.dto.contest.ContestStatus;
28-
import com.topcoder.direct.services.view.dto.contest.PhasedContestDTO;
29-
import com.topcoder.direct.services.view.dto.contest.ProjectPhaseDTO;
30-
import com.topcoder.direct.services.view.dto.contest.ProjectPhaseType;
21+
import com.topcoder.direct.services.view.dto.contest.*;
3122
import com.topcoder.direct.services.view.dto.cost.CostDTO;
3223
import com.topcoder.direct.services.view.dto.project.ProjectBriefDTO;
3324
import com.topcoder.direct.services.view.interceptor.SecurityGroupsAccessInterceptor;
@@ -73,15 +64,26 @@
7364
import com.topcoder.shared.util.DBMS;
7465
import com.topcoder.shared.util.dwload.CacheClearer;
7566
import com.topcoder.web.common.CachedDataAccess;
67+
import com.topcoder.web.common.cache.CacheClient;
68+
import com.topcoder.web.common.cache.CacheClientFactory;
7669
import com.topcoder.web.common.cache.MaxAge;
7770
import eu.medsea.mimeutil.MimeType;
7871
import eu.medsea.mimeutil.MimeUtil;
7972
import org.apache.axis.encoding.Base64;
8073
import org.apache.commons.io.FilenameUtils;
8174
import org.apache.commons.io.IOUtils;
75+
import org.apache.http.HttpEntity;
76+
import org.apache.http.HttpHeaders;
77+
import org.apache.http.HttpResponse;
78+
import org.apache.http.HttpStatus;
79+
import org.apache.http.client.methods.HttpGet;
80+
import org.apache.http.client.utils.URIBuilder;
81+
import org.apache.http.impl.client.DefaultHttpClient;
8282
import org.apache.log4j.Logger;
8383
import org.apache.struts2.ServletActionContext;
8484
import org.apache.struts2.util.TokenHelper;
85+
import org.codehaus.jackson.JsonNode;
86+
import org.codehaus.jackson.map.ObjectMapper;
8587
import org.springframework.web.context.WebApplicationContext;
8688
import org.springframework.web.context.support.WebApplicationContextUtils;
8789

@@ -95,38 +97,15 @@
9597
import javax.xml.datatype.DatatypeConfigurationException;
9698
import javax.xml.datatype.DatatypeFactory;
9799
import javax.xml.datatype.XMLGregorianCalendar;
98-
import java.io.BufferedInputStream;
99-
import java.io.ByteArrayInputStream;
100-
import java.io.ByteArrayOutputStream;
101-
import java.io.File;
102-
import java.io.FileInputStream;
103-
import java.io.FileOutputStream;
104-
import java.io.IOException;
105-
import java.io.InputStream;
100+
import java.io.*;
106101
import java.nio.channels.FileLock;
107102
import java.sql.Connection;
108103
import java.sql.PreparedStatement;
109104
import java.sql.ResultSet;
110105
import java.text.DateFormat;
111106
import java.text.ParseException;
112107
import java.text.SimpleDateFormat;
113-
import java.util.ArrayList;
114-
import java.util.Arrays;
115-
import java.util.Calendar;
116-
import java.util.Collection;
117-
import java.util.Collections;
118-
import java.util.Comparator;
119-
import java.util.Date;
120-
import java.util.GregorianCalendar;
121-
import java.util.HashMap;
122-
import java.util.HashSet;
123-
import java.util.Iterator;
124-
import java.util.LinkedHashMap;
125-
import java.util.LinkedList;
126-
import java.util.List;
127-
import java.util.Map;
128-
import java.util.Set;
129-
import java.util.TimeZone;
108+
import java.util.*;
130109
import java.util.zip.ZipEntry;
131110
import java.util.zip.ZipInputStream;
132111
import java.util.zip.ZipOutputStream;
@@ -952,6 +931,14 @@ public final class DirectUtils {
952931
private static final String QUERY_GET_SECURITY_GROUP_FROM_ID = "SELECT group_id, description FROM security_groups " +
953932
" WHERE group_id in (";
954933

934+
/**
935+
* The jackson object mapping which is used to deserialize json return from API to domain model.
936+
*/
937+
protected static final ObjectMapper objectMapper;
938+
static {
939+
objectMapper = new ObjectMapper();
940+
}
941+
955942
/**
956943
* <p>
957944
* Default Constructor.
@@ -3832,4 +3819,76 @@ public static List<ProjectGroup> getGroupIdAndName(List<ProjectGroup> projectGro
38323819
DatabaseUtils.close(con);
38333820
}
38343821
}
3822+
3823+
/**
3824+
* Get group from group API.
3825+
*
3826+
* @param tcSubject tcSubject of user
3827+
* @param endpoint endpoint url
3828+
* @return set of group
3829+
* @throws Exception
3830+
*/
3831+
public static Set<ProjectGroup> getGroupsFromApi(TCSubject tcSubject, String endpoint) throws Exception {
3832+
URIBuilder uri = new URIBuilder(endpoint);
3833+
3834+
if (!DirectUtils.isCockpitAdmin(tcSubject) && !DirectUtils.isTcStaff(tcSubject)) {
3835+
uri.setParameter("memberId", String.valueOf(tcSubject.getUserId()));
3836+
}
3837+
3838+
DefaultHttpClient httpClient = new DefaultHttpClient();
3839+
3840+
HttpGet getRequest = new HttpGet(uri.build());
3841+
logger.info("Getting Group with thi uri: " + uri.build().toString());
3842+
3843+
String v3Token = new JwtTokenUpdater().check().getToken();
3844+
3845+
getRequest.setHeader(HttpHeaders.AUTHORIZATION, "Bearer " + v3Token);
3846+
3847+
getRequest.addHeader(HttpHeaders.ACCEPT, "application/json");
3848+
HttpResponse httpResponse = httpClient.execute(getRequest);
3849+
3850+
HttpEntity entity = httpResponse.getEntity();
3851+
3852+
if (httpResponse.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
3853+
throw new Exception("Unable to get groups from the API:" + httpResponse.getStatusLine().getReasonPhrase());
3854+
}
3855+
3856+
JsonNode result = objectMapper.readTree(entity.getContent());
3857+
JsonNode groups = result.path("result").path("content");
3858+
Set<ProjectGroup> groupResults = new HashSet<ProjectGroup>();
3859+
for (JsonNode group : groups) {
3860+
ProjectGroup pg = new ProjectGroup(group.get("id").asLong(), group.get("name").asText());
3861+
groupResults.add(pg);
3862+
}
3863+
return groupResults;
3864+
}
3865+
3866+
/**
3867+
* Get groups. Get from cache first if none then get from api
3868+
*
3869+
* @param tcSubject tcSubject of user
3870+
* @param endpoint endpoint url
3871+
* @return set of groupfor user
3872+
* @throws Exception
3873+
*/
3874+
public static Set<ProjectGroup> getGroups(TCSubject tcSubject, String endpoint) throws Exception {
3875+
CacheClient cc = null;
3876+
Set<ProjectGroup> projectGroups = null;
3877+
SortedCacheAddress cacheAddress = new SortedCacheAddress(tcSubject.getUserId());
3878+
try {
3879+
cc = CacheClientFactory.create();
3880+
projectGroups = (Set<ProjectGroup>) cc.get(cacheAddress);
3881+
} catch (Exception e) {
3882+
logger.info("Can't get group for user " + tcSubject.getUserId() + " from cache");
3883+
}
3884+
if (projectGroups == null) {
3885+
projectGroups = DirectUtils.getGroupsFromApi(tcSubject, endpoint);
3886+
try {
3887+
cc.set(cacheAddress, projectGroups, MaxAge.HOUR);
3888+
} catch (Exception e) {
3889+
logger.error("Failed to put user group into cache ", e);
3890+
}
3891+
}
3892+
return projectGroups;
3893+
}
38353894
}

0 commit comments

Comments
 (0)