Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit c992e2a

Browse files
committedMay 10, 2024·
Refactor FENCE mapping methods to FenceMappingUtility class
This commit includes the extraction of FENCE mapping methods from FENCEAuthenticationService to a new singleton class named FenceMappingUtility. This is an attempt to reduce the overhead of the FENCEAuthenticationService upon a user's initial login.
1 parent 7e7d64a commit c992e2a

File tree

4 files changed

+98
-69
lines changed

4 files changed

+98
-69
lines changed
 

‎pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/rest/StudyAccessService.java

+5-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import edu.harvard.hms.dbmi.avillach.auth.data.entity.Role;
44
import edu.harvard.hms.dbmi.avillach.auth.data.repository.RoleRepository;
55
import edu.harvard.hms.dbmi.avillach.auth.service.auth.FENCEAuthenticationService;
6+
import edu.harvard.hms.dbmi.avillach.auth.utils.FenceMappingUtility;
67
import io.swagger.annotations.Api;
78
import io.swagger.annotations.ApiOperation;
89
import io.swagger.annotations.ApiParam;
@@ -40,6 +41,9 @@ public class StudyAccessService {
4041
@Inject
4142
FENCEAuthenticationService fenceAuthenticationService;
4243

44+
@Inject
45+
private FenceMappingUtility fenceMappingUtility;
46+
4347
@ApiOperation(value = "POST a single study and it creates the role, privs, and rules for it, requires SUPER_ADMIN role")
4448
@Transactional
4549
@POST
@@ -55,7 +59,7 @@ public Response addStudyAccess(@ApiParam(value="The Study Identifier of the new
5559
Map fenceMappingForStudy = null;
5660

5761
try {
58-
Map<String, Map> fenceMapping = fenceAuthenticationService.getFENCEMapping();
62+
Map<String, Map> fenceMapping = fenceMappingUtility.getFENCEMapping();
5963
if (fenceMapping == null) {
6064
throw new Exception("Fence mapping is null");
6165
}

‎pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/service/auth/FENCEAuthenticationService.java

+6-66
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import com.fasterxml.jackson.core.JsonProcessingException;
2222
import com.fasterxml.jackson.databind.node.ObjectNode;
23+
import edu.harvard.hms.dbmi.avillach.auth.utils.FenceMappingUtility;
2324
import org.apache.commons.lang3.StringUtils;
2425
import org.apache.http.Header;
2526
import org.apache.http.entity.StringEntity;
@@ -66,6 +67,9 @@ public class FENCEAuthenticationService {
6667
@Inject
6768
AuthUtils authUtil;
6869

70+
@Inject
71+
private FenceMappingUtility fenceMappingUtility;
72+
6973
private Application picSureApp;
7074
private Connection fenceConnection;
7175

@@ -242,7 +246,7 @@ public Response getFENCEProfile(String callback_url, Map<String, String> authReq
242246

243247
private void createAndUpsertRole(String access_role_name, User current_user) throws IOException {
244248
logger.debug("createAndUpsertRole() starting...");
245-
Map projectMetadata = getFenceMappingByAuthZ().get(access_role_name);
249+
Map projectMetadata = fenceMappingUtility.getFenceMappingByAuthZ().get(access_role_name);
246250

247251
if (projectMetadata == null) {
248252
logger.error("getFENCEProfile() -> createAndUpsertRole could not find study in FENCE mapping SKIPPING: {}", access_role_name);
@@ -1127,77 +1131,13 @@ private Map getFENCEMappingforProjectAndConsent(String projectId, String consent
11271131
String consentVal = (consent_group != null && consent_group != "") ? projectId + "." + consent_group : projectId;
11281132
logger.info("getFENCEMappingforProjectAndConsent() looking up {}", consentVal);
11291133

1130-
Object projectMetadata = getFENCEMapping().get(consentVal);
1134+
Object projectMetadata = fenceMappingUtility.getFENCEMapping().get(consentVal);
11311135
if( projectMetadata instanceof Map) {
11321136
return (Map)projectMetadata;
11331137
} else if (projectMetadata != null) {
11341138
logger.info("getFENCEMappingforProjectAndConsent() Obj instance of " + projectMetadata.getClass().getCanonicalName());
11351139
}
11361140
return null;
11371141
}
1138-
1139-
public Map<String, Map> getFENCEMapping(){
1140-
if(_projectMap == null || _projectMap.isEmpty()) {
1141-
try {
1142-
List<Map> projects = loadBioDataCatalystFenceMappingData();
1143-
_projectMap = new HashMap<String, Map>(projects.size());
1144-
for(Map project : projects) {
1145-
String consentVal = (project.get("consent_group_code") != null && project.get("consent_group_code") != "") ?
1146-
"" + project.get("study_identifier") + "." + project.get("consent_group_code") :
1147-
"" + project.get("study_identifier");
1148-
logger.debug("adding study " + consentVal);
1149-
_projectMap.put(consentVal, project);
1150-
}
1151-
1152-
} catch (Exception e) {
1153-
logger.error("getFENCEMapping: Non-fatal error parsing fence_mapping.json: "+JAXRSConfiguration.templatePath, e);
1154-
return new HashMap<String,Map>();
1155-
}
1156-
}
1157-
1158-
return _projectMap;
1159-
}
1160-
1161-
1162-
/**
1163-
* This method is used to improve the performance for looking up the FENCE project metadata by the authZ value.
1164-
*
1165-
* @return Map<String, Map> - a map of FENCE project metadata by the authZ value
1166-
* @throws IOException - if there is an issue parsing or finding the fence_mapping.json file
1167-
*/
1168-
private Map<String, Map> getFenceMappingByAuthZ() throws IOException {
1169-
if (fenceMappingByAuthZ == null || fenceMappingByAuthZ.isEmpty()) {
1170-
List<Map> projects = loadBioDataCatalystFenceMappingData();
1171-
fenceMappingByAuthZ = new HashMap<>(projects.size());
1172-
if (projects.size() == 1 && projects.get(0).isEmpty()) {
1173-
logger.error("getFENCEMapping: FENCE mapping data is empty");
1174-
throw new IOException("FENCE mapping data is empty");
1175-
}
1176-
1177-
for (Map project : projects) {
1178-
fenceMappingByAuthZ.put(project.get("authZ").toString().replace("\\/", "/"), project);
1179-
}
1180-
}
1181-
1182-
return fenceMappingByAuthZ;
1183-
}
1184-
1185-
private List<Map> loadBioDataCatalystFenceMappingData() {
1186-
Map fenceMapping = null;
1187-
List<Map> projects = null;
1188-
try {
1189-
fenceMapping = JAXRSConfiguration.objectMapper.readValue(
1190-
new File(String.join(File.separator,
1191-
new String[] {JAXRSConfiguration.templatePath ,"fence_mapping.json"}))
1192-
, Map.class);
1193-
1194-
projects = (List<Map>) fenceMapping.get("bio_data_catalyst");
1195-
logger.debug("getFENCEMapping: found FENCE mapping with {} entries", projects.size());
1196-
} catch (Exception e) {
1197-
logger.error("loadFenceMappingData: Non-fatal error parsing fence_mapping.json: {}", JAXRSConfiguration.templatePath, e);
1198-
return Collections.singletonList(new HashMap());
1199-
}
1200-
return projects;
1201-
}
12021142

12031143
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package edu.harvard.hms.dbmi.avillach.auth.utils;
2+
3+
import edu.harvard.hms.dbmi.avillach.auth.JAXRSConfiguration;
4+
import org.slf4j.Logger;
5+
import org.slf4j.LoggerFactory;
6+
7+
import javax.annotation.PostConstruct;
8+
import javax.ejb.Singleton;
9+
import javax.ejb.Startup;
10+
import java.io.File;
11+
import java.io.IOException;
12+
import java.util.Collections;
13+
import java.util.HashMap;
14+
import java.util.List;
15+
import java.util.Map;
16+
17+
@Singleton
18+
@Startup
19+
public class FenceMappingUtility {
20+
21+
private final Logger logger = LoggerFactory.getLogger(this.getClass());
22+
private Map<String, Map> _projectMap;
23+
private Map<String, Map> fenceMappingByAuthZ;
24+
25+
@PostConstruct
26+
public void init() {
27+
try {
28+
initializeFENCEMapping();
29+
initializeFenceMappingByAuthZ();
30+
} catch (IOException e) {
31+
// Handle exceptions appropriately
32+
logger.error("Error initializing FENCE mappings", e);
33+
}
34+
}
35+
36+
private void initializeFENCEMapping() throws IOException {
37+
List<Map> projects = loadBioDataCatalystFenceMappingData();
38+
_projectMap = new HashMap<>(projects.size());
39+
for (Map project : projects) {
40+
String consentVal = (project.get("consent_group_code") != null && project.get("consent_group_code") != "") ?
41+
project.get("study_identifier") + "." + project.get("consent_group_code") :
42+
project.get("study_identifier").toString();
43+
_projectMap.put(consentVal, project);
44+
}
45+
}
46+
47+
private void initializeFenceMappingByAuthZ() throws IOException {
48+
List<Map> projects = loadBioDataCatalystFenceMappingData();
49+
fenceMappingByAuthZ = new HashMap<>(projects.size());
50+
for (Map project : projects) {
51+
fenceMappingByAuthZ.put(project.get("authZ").toString().replace("\\/", "/"), project);
52+
}
53+
}
54+
55+
public Map<String, Map> getFENCEMapping() {
56+
return _projectMap;
57+
}
58+
59+
public Map<String, Map> getFenceMappingByAuthZ() {
60+
return fenceMappingByAuthZ;
61+
}
62+
63+
private List<Map> loadBioDataCatalystFenceMappingData() {
64+
Map fenceMapping = null;
65+
List<Map> projects = null;
66+
try {
67+
fenceMapping = JAXRSConfiguration.objectMapper.readValue(
68+
new File(String.join(File.separator,
69+
new String[] {JAXRSConfiguration.templatePath ,"fence_mapping.json"}))
70+
, Map.class);
71+
72+
projects = (List<Map>) fenceMapping.get("bio_data_catalyst");
73+
logger.debug("getFENCEMapping: found FENCE mapping with {} entries", projects.size());
74+
} catch (Exception e) {
75+
logger.error("loadFenceMappingData: Non-fatal error parsing fence_mapping.json: {}", JAXRSConfiguration.templatePath, e);
76+
return Collections.singletonList(new HashMap());
77+
}
78+
return projects;
79+
}
80+
81+
}

‎pic-sure-auth-services/src/test/java/edu/harvard/hms/dbmi/avillach/StudyAccessServiceTest.java

+6-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import edu.harvard.hms.dbmi.avillach.auth.data.repository.RoleRepository;
44
import edu.harvard.hms.dbmi.avillach.auth.rest.StudyAccessService;
55
import edu.harvard.hms.dbmi.avillach.auth.service.auth.FENCEAuthenticationService;
6+
import edu.harvard.hms.dbmi.avillach.auth.utils.FenceMappingUtility;
67
import org.junit.Before;
78
import org.junit.Test;
89
import org.mockito.InjectMocks;
@@ -25,6 +26,9 @@ public class StudyAccessServiceTest {
2526
@Mock
2627
private FENCEAuthenticationService fenceAuthenticationService;
2728

29+
@Mock
30+
private FenceMappingUtility fenceMappingUtility;
31+
2832
@Before
2933
public void init() {
3034
MockitoAnnotations.initMocks(this);
@@ -42,7 +46,7 @@ public void testAddStudyAccessWithBlankIdentifier() {
4246
@Test
4347
public void testAddStudyAccess() {
4448
String studyIdentifier = "testStudy";
45-
when(fenceAuthenticationService.getFENCEMapping()).thenReturn(Map.of(studyIdentifier, Map.of(StudyAccessService.STUDY_IDENTIFIER, studyIdentifier,StudyAccessService.CONSENT_GROUP_CODE, "")));
49+
when(fenceMappingUtility.getFENCEMapping()).thenReturn(Map.of(studyIdentifier, Map.of(StudyAccessService.STUDY_IDENTIFIER, studyIdentifier,StudyAccessService.CONSENT_GROUP_CODE, "")));
4650
when(fenceAuthenticationService.upsertRole(null, "MANUAL_testStudy", "MANUAL_ role MANUAL_testStudy")).thenReturn(true);
4751

4852
Response response = studyAccessService.addStudyAccess(studyIdentifier);
@@ -53,7 +57,7 @@ public void testAddStudyAccess() {
5357
@Test
5458
public void testAddStudyAccessWithConsent() {
5559
String studyIdentifier = "testStudy2.c2";
56-
when(fenceAuthenticationService.getFENCEMapping()).thenReturn(Map.of(studyIdentifier, Map.of(StudyAccessService.STUDY_IDENTIFIER, "testStudy2", StudyAccessService.CONSENT_GROUP_CODE, "c2")));
60+
when(fenceMappingUtility.getFENCEMapping()).thenReturn(Map.of(studyIdentifier, Map.of(StudyAccessService.STUDY_IDENTIFIER, "testStudy2", StudyAccessService.CONSENT_GROUP_CODE, "c2")));
5761
when(fenceAuthenticationService.upsertRole(null, "MANUAL_testStudy2_c2", "MANUAL_ role MANUAL_testStudy2_c2")).thenReturn(true);
5862
Response response = studyAccessService.addStudyAccess(studyIdentifier);
5963

0 commit comments

Comments
 (0)
Please sign in to comment.