diff --git a/pom.xml b/pom.xml
index 71666f9..2ed045e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
org.springframework.boot
spring-boot-starter-parent
3.2.11
-
+
gov.cms.madie.terminologyservice
@@ -14,7 +14,7 @@
Terminology Service
Terminology Service for MADiE
- 7.4.5
+ 7.6.0
16
2.5.0
17
@@ -174,7 +174,7 @@
-
+
diff --git a/src/main/java/gov/cms/madie/terminology/TerminologyServiceApplication.java b/src/main/java/gov/cms/madie/terminology/TerminologyServiceApplication.java
index 0832521..2dfad47 100644
--- a/src/main/java/gov/cms/madie/terminology/TerminologyServiceApplication.java
+++ b/src/main/java/gov/cms/madie/terminology/TerminologyServiceApplication.java
@@ -25,7 +25,7 @@ public WebMvcConfigurer corsConfigurer() {
public void addCorsMappings(CorsRegistry registry) {
registry
.addMapping("/**")
- .allowedMethods("PUT", "POST", "GET")
+ .allowedMethods("PUT", "POST", "GET", "DELETE")
.allowedOrigins(
"http://localhost:9000",
"https://dev-madie.hcqis.org",
diff --git a/src/main/java/gov/cms/madie/terminology/controller/VsacController.java b/src/main/java/gov/cms/madie/terminology/controller/VsacController.java
index a73fc16..19b80a8 100644
--- a/src/main/java/gov/cms/madie/terminology/controller/VsacController.java
+++ b/src/main/java/gov/cms/madie/terminology/controller/VsacController.java
@@ -8,6 +8,7 @@
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
@@ -134,4 +135,12 @@ public ResponseEntity checkUserLogin(Principal principal) {
? ResponseEntity.ok().body(Boolean.TRUE)
: new ResponseEntity<>(HttpStatus.UNAUTHORIZED);
}
+
+ @DeleteMapping("/umls-credentials")
+ public ResponseEntity umlsLogout(Principal principal) {
+ log.info("Entering: umlsLogout(): username = " + principal.getName());
+ return vsacService.logoutUMLSUser(principal.getName())
+ ? ResponseEntity.ok().body(Boolean.TRUE)
+ : new ResponseEntity<>(HttpStatus.UNAUTHORIZED);
+ }
}
diff --git a/src/main/java/gov/cms/madie/terminology/dto/ValueSetsSearchCriteria.java b/src/main/java/gov/cms/madie/terminology/dto/ValueSetsSearchCriteria.java
index 2bdc1c3..43e99bc 100644
--- a/src/main/java/gov/cms/madie/terminology/dto/ValueSetsSearchCriteria.java
+++ b/src/main/java/gov/cms/madie/terminology/dto/ValueSetsSearchCriteria.java
@@ -12,6 +12,7 @@ public class ValueSetsSearchCriteria {
private String profile;
private String includeDraft;
+ private String activeOnly;
private ManifestExpansion manifestExpansion;
private List valueSetParams;
diff --git a/src/main/java/gov/cms/madie/terminology/repositories/UmlsUserRepository.java b/src/main/java/gov/cms/madie/terminology/repositories/UmlsUserRepository.java
index a13a69f..eb4aaf7 100644
--- a/src/main/java/gov/cms/madie/terminology/repositories/UmlsUserRepository.java
+++ b/src/main/java/gov/cms/madie/terminology/repositories/UmlsUserRepository.java
@@ -10,4 +10,6 @@ public interface UmlsUserRepository extends MongoRepository {
Optional findByHarpId(String harpId);
Optional findByHarpIdAndApiKey(String harpId, String apiKey);
+
+ Optional deleteByHarpId(String harpId);
}
diff --git a/src/main/java/gov/cms/madie/terminology/service/FhirTerminologyService.java b/src/main/java/gov/cms/madie/terminology/service/FhirTerminologyService.java
index 213253d..cc560d7 100644
--- a/src/main/java/gov/cms/madie/terminology/service/FhirTerminologyService.java
+++ b/src/main/java/gov/cms/madie/terminology/service/FhirTerminologyService.java
@@ -64,6 +64,7 @@ public List recursivelyRequestAllValueSetsExpansionsForQDM(
vsParam,
valueSetsSearchCriteria.getProfile(),
valueSetsSearchCriteria.getIncludeDraft(),
+ valueSetsSearchCriteria.getActiveOnly(),
valueSetsSearchCriteria.getManifestExpansion());
ValueSet valueSetResource = parser.parseResource(ValueSet.class, resource);
diff --git a/src/main/java/gov/cms/madie/terminology/service/VsacService.java b/src/main/java/gov/cms/madie/terminology/service/VsacService.java
index fa17250..07bab6d 100644
--- a/src/main/java/gov/cms/madie/terminology/service/VsacService.java
+++ b/src/main/java/gov/cms/madie/terminology/service/VsacService.java
@@ -358,4 +358,15 @@ private List getValueSetConcepts(DescribedValueSet valueSet
public Optional findByHarpId(String harpId) {
return umlsUserRepository.findByHarpId(harpId);
}
+
+ public boolean logoutUMLSUser(String userName) {
+ Optional deletedUser = umlsUserRepository.deleteByHarpId(userName);
+ boolean deleted = deletedUser.isPresent();
+ if (deleted) {
+ log.info("Successfully deleted UMLS information for User Name: {}", userName);
+ } else {
+ log.error("Error while deleting UMLS information for User Name: {}", userName);
+ }
+ return deleted;
+ }
}
diff --git a/src/main/java/gov/cms/madie/terminology/util/TerminologyServiceUtil.java b/src/main/java/gov/cms/madie/terminology/util/TerminologyServiceUtil.java
index 35f17e2..5ae3bb9 100644
--- a/src/main/java/gov/cms/madie/terminology/util/TerminologyServiceUtil.java
+++ b/src/main/java/gov/cms/madie/terminology/util/TerminologyServiceUtil.java
@@ -116,6 +116,7 @@ public static URI buildValueSetResourceUri(
ValueSetsSearchCriteria.ValueSetParams valueSetParams,
String profile,
String includeDraft,
+ String activeOnly,
ManifestExpansion manifestExpansion) {
MultiValueMap params = new LinkedMultiValueMap<>();
String expandValueSetUri = "/ValueSet/" + valueSetParams.getOid() + "/$expand";
@@ -134,8 +135,12 @@ public static URI buildValueSetResourceUri(
} else if (manifestExpansion != null
&& StringUtils.isNotBlank(manifestExpansion.getFullUrl())) {
params.put("manifest", List.of(manifestExpansion.getFullUrl()));
- } else if (StringUtils.isNotBlank(includeDraft)) {
- params.put("includeDraft", List.of("true"));
+ } else {
+ if (StringUtils.isNotBlank(includeDraft)) {
+ params.put("includeDraft", List.of("true"));
+ }
+
+ params.put("activeOnly", List.of(activeOnly));
}
return UriComponentsBuilder.fromPath(expandValueSetUri).queryParams(params).build().toUri();
diff --git a/src/main/java/gov/cms/madie/terminology/webclient/FhirTerminologyServiceWebClient.java b/src/main/java/gov/cms/madie/terminology/webclient/FhirTerminologyServiceWebClient.java
index 395054c..8ac2131 100644
--- a/src/main/java/gov/cms/madie/terminology/webclient/FhirTerminologyServiceWebClient.java
+++ b/src/main/java/gov/cms/madie/terminology/webclient/FhirTerminologyServiceWebClient.java
@@ -108,11 +108,12 @@ public String getValueSetResource(
ValueSetsSearchCriteria.ValueSetParams valueSetParams,
String profile,
String includeDraft,
+ String activeOnly,
ManifestExpansion manifestExpansion) {
profile = StringUtils.isNotBlank(profile) ? defaultProfile : profile;
URI uri =
TerminologyServiceUtil.buildValueSetResourceUri(
- valueSetParams, profile, includeDraft, manifestExpansion);
+ valueSetParams, profile, includeDraft, activeOnly, manifestExpansion);
return fetchResourceFromVsac(uri.toString(), apiKey, "ValueSet");
}
diff --git a/src/test/java/gov/cms/madie/terminology/controller/VsacControllerTest.java b/src/test/java/gov/cms/madie/terminology/controller/VsacControllerTest.java
index a155cd1..f2d9c50 100644
--- a/src/test/java/gov/cms/madie/terminology/controller/VsacControllerTest.java
+++ b/src/test/java/gov/cms/madie/terminology/controller/VsacControllerTest.java
@@ -133,4 +133,26 @@ void testInvalidUserUmlsLogin() {
assertEquals(response.getStatusCode(), HttpStatus.UNAUTHORIZED);
}
+
+ @Test
+ void testUserUmlsLogout() {
+ Principal principal = mock(Principal.class);
+ when(principal.getName()).thenReturn(TEST_USER);
+
+ when(vsacService.logoutUMLSUser(anyString())).thenReturn(true);
+ ResponseEntity response = vsacController.umlsLogout(principal);
+
+ assertEquals(response.getBody(), Boolean.TRUE);
+ }
+
+ @Test
+ void testUserUmlsLogoutFailed() {
+ Principal principal = mock(Principal.class);
+ when(principal.getName()).thenReturn(TEST_USER);
+
+ when(vsacService.logoutUMLSUser(anyString())).thenReturn(false);
+ ResponseEntity response = vsacController.umlsLogout(principal);
+
+ assertEquals(response.getStatusCode(), HttpStatus.UNAUTHORIZED);
+ }
}
diff --git a/src/test/java/gov/cms/madie/terminology/service/FhirTerminologyServiceTest.java b/src/test/java/gov/cms/madie/terminology/service/FhirTerminologyServiceTest.java
index 78a012d..1fd0f67 100644
--- a/src/test/java/gov/cms/madie/terminology/service/FhirTerminologyServiceTest.java
+++ b/src/test/java/gov/cms/madie/terminology/service/FhirTerminologyServiceTest.java
@@ -173,6 +173,7 @@ void getValueSetsExpansionsForQdm_When_ManifestExpansionIsProvided() {
.build()))
.profile("test-profile")
.includeDraft("false")
+ .activeOnly("true")
.manifestExpansion(
ManifestExpansion.builder()
.fullUrl("https://cts.nlm.nih.gov/fhir/Library/ecqm-update-2022-05-05")
@@ -180,7 +181,7 @@ void getValueSetsExpansionsForQdm_When_ManifestExpansionIsProvided() {
.build())
.build();
when(fhirTerminologyServiceWebClient.getValueSetResource(
- anyString(), any(), anyString(), anyString(), any()))
+ anyString(), any(), anyString(), anyString(), anyString(), any()))
.thenReturn(mockValueSetResourceWithCodes);
when(fhirContext.newJsonParser()).thenReturn(FhirContext.forR4().newJsonParser());
when(mappingService.getCodeSystemEntries()).thenReturn(codeSystemEntries);
@@ -209,6 +210,7 @@ void getsValueSetsExpansionsForQdm_withNoCodes_When_ManifestExpansionIsProvided(
.build()))
.profile("test-profile")
.includeDraft("false")
+ .activeOnly("false")
.manifestExpansion(
ManifestExpansion.builder()
.fullUrl("https://cts.nlm.nih.gov/fhir/Library/ecqm-update-2022-05-05")
@@ -221,6 +223,7 @@ void getsValueSetsExpansionsForQdm_withNoCodes_When_ManifestExpansionIsProvided(
any(ValueSetsSearchCriteria.ValueSetParams.class),
anyString(),
anyString(),
+ anyString(),
any(ManifestExpansion.class)))
.thenReturn(mockValueSetResourceWithNoCodes);
when(mappingService.getCodeSystemEntries()).thenReturn(codeSystemEntries);
diff --git a/src/test/java/gov/cms/madie/terminology/service/VsacServiceTest.java b/src/test/java/gov/cms/madie/terminology/service/VsacServiceTest.java
index b0148d9..45bc796 100644
--- a/src/test/java/gov/cms/madie/terminology/service/VsacServiceTest.java
+++ b/src/test/java/gov/cms/madie/terminology/service/VsacServiceTest.java
@@ -592,4 +592,18 @@ void testGetCodeStatusIfCodeNotFoundInSvs() {
CodeStatus status = vsacService.getCodeStatus(code, TEST_API_KEY);
assertThat(status, is(equalTo(CodeStatus.NA)));
}
+
+ @Test
+ void testUserUmlsLogout() {
+ when(umlsUserRepository.deleteByHarpId(anyString())).thenReturn(Optional.of(umlsUser));
+ boolean loggedOut = vsacService.logoutUMLSUser(umlsUser.getHarpId());
+ assertTrue(loggedOut);
+ }
+
+ @Test
+ void testUserUmlsLogoutFailed() {
+ when(umlsUserRepository.deleteByHarpId(anyString())).thenReturn(Optional.empty());
+ boolean loggedOut = vsacService.logoutUMLSUser(umlsUser.getHarpId());
+ assertFalse(loggedOut);
+ }
}
diff --git a/src/test/java/gov/cms/madie/terminology/webclient/FhirTerminologyServiceWebClientTest.java b/src/test/java/gov/cms/madie/terminology/webclient/FhirTerminologyServiceWebClientTest.java
index 10c84f2..06cc5c2 100644
--- a/src/test/java/gov/cms/madie/terminology/webclient/FhirTerminologyServiceWebClientTest.java
+++ b/src/test/java/gov/cms/madie/terminology/webclient/FhirTerminologyServiceWebClientTest.java
@@ -91,11 +91,11 @@ void getLatestValueSetResourceSuccessfully_when_noCustomSearchCriteriaIsProvided
.addHeader("Content-Type", "application/fhir+json"));
String actualResponse =
fhirTerminologyServiceWebClient.getValueSetResource(
- MOCK_API_KEY, testValueSetParams, null, null, new ManifestExpansion());
+ MOCK_API_KEY, testValueSetParams, null, null, "false", new ManifestExpansion());
assertNotNull(actualResponse);
assertEquals(MOCK_RESPONSE_STRING, actualResponse);
RecordedRequest recordedRequest = mockBackEnd.takeRequest();
- assertEquals("/ValueSet/test-vs-id/$expand", recordedRequest.getPath());
+ assertEquals("/ValueSet/test-vs-id/$expand?activeOnly=false", recordedRequest.getPath());
}
@Test
@@ -108,11 +108,13 @@ void getDraftValueSetResourceSuccessfully_when_noCustomSearchCriteriaIsProvided(
.addHeader("Content-Type", "application/fhir+json"));
String actualResponse =
fhirTerminologyServiceWebClient.getValueSetResource(
- MOCK_API_KEY, testValueSetParams, null, "yes", new ManifestExpansion());
+ MOCK_API_KEY, testValueSetParams, null, "yes", "false", new ManifestExpansion());
assertNotNull(actualResponse);
assertEquals(MOCK_RESPONSE_STRING, actualResponse);
RecordedRequest recordedRequest = mockBackEnd.takeRequest();
- assertEquals("/ValueSet/test-vs-id/$expand?includeDraft=true", recordedRequest.getPath());
+ assertEquals(
+ "/ValueSet/test-vs-id/$expand?includeDraft=true&activeOnly=false",
+ recordedRequest.getPath());
}
@Test
@@ -129,6 +131,7 @@ void getValueSetResourceSuccessfully_when_manifestExpansionIsProvided()
testValueSetParams,
null,
null,
+ "true",
ManifestExpansion.builder()
.id("test-manifest-456")
.fullUrl("https://cts.nlm.nih.gov/fhir/Library/test-manifest-456")
@@ -152,7 +155,7 @@ void getValueSetResourceSuccessfully_when_ValueSetVersionIsProvided()
testValueSetParams.setVersion("test-value-set-version-2024");
String actualResponse =
fhirTerminologyServiceWebClient.getValueSetResource(
- MOCK_API_KEY, testValueSetParams, null, null, new ManifestExpansion());
+ MOCK_API_KEY, testValueSetParams, null, null, "false", new ManifestExpansion());
assertNotNull(actualResponse);
assertEquals(MOCK_RESPONSE_STRING, actualResponse);
RecordedRequest recordedRequest = mockBackEnd.takeRequest();
@@ -169,9 +172,9 @@ void getValueSetResource_ReturnsException() throws InterruptedException {
WebClientResponseException.class,
() ->
fhirTerminologyServiceWebClient.getValueSetResource(
- MOCK_API_KEY, testValueSetParams, null, null, new ManifestExpansion()));
+ MOCK_API_KEY, testValueSetParams, null, null, "false", new ManifestExpansion()));
RecordedRequest recordedRequest = mockBackEnd.takeRequest();
- assertEquals("/ValueSet/test-vs-id/$expand", recordedRequest.getPath());
+ assertEquals("/ValueSet/test-vs-id/$expand?activeOnly=false", recordedRequest.getPath());
}
@Test