From 9fee360dbd948d5c67a717e96ec92ec64c27b65e Mon Sep 17 00:00:00 2001 From: Joseph Kotanchik Date: Tue, 16 Jul 2024 13:13:38 -0400 Subject: [PATCH] MAT-7471: Disable auto-encode on FhirTerminologyServiceWebClient with a custom UriBuilderFactory. Our config of the `FhirTerminologyServiceWebClient` enabled auto-encoding of String uri values by setting the `WebClient.Builder baseUrl()`. Effectively a shortcut to use the default `UriBuilderFactory`, which encodes uri Strings by default. When a URI object is passed to the WebClient request chain, the `UriBuilderFactory` is not used. Instead, the WebClient uses the supplied URI as is, which also means it doesn't use baseUrl configured on the WebClient builder as the underlying UriBuilderFactory is also not used. See: https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/reactive/function/client/WebClient.Builder.html#baseUrl(java.lang.String) See: https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/util/DefaultUriBuilderFactory.html#setEncodingMode(org.springframework.web.util.DefaultUriBuilderFactory.EncodingMode) --- .../madie/terminology/service/FhirTerminologyService.java | 5 ++++- .../webclient/FhirTerminologyServiceWebClient.java | 6 +++++- .../controller/VsacFhirTerminologyControllerTest.java | 3 ++- .../webclient/FhirTerminologyServiceWebClientTest.java | 3 +-- 4 files changed, 12 insertions(+), 5 deletions(-) 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 73ab8f3..79adfa6 100644 --- a/src/main/java/gov/cms/madie/terminology/service/FhirTerminologyService.java +++ b/src/main/java/gov/cms/madie/terminology/service/FhirTerminologyService.java @@ -177,7 +177,10 @@ public ValueSetSearchResult searchValueSets(String apiKey, Map q } log.info("valueSetList {}", valueSetList); }); - return ValueSetSearchResult.builder().valueSets(valueSetList).resultBundle(responseString).build(); + return ValueSetSearchResult.builder() + .valueSets(valueSetList) + .resultBundle(responseString) + .build(); } public List getAllCodeSystems() { 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 4e04c7d..cc4c439 100644 --- a/src/main/java/gov/cms/madie/terminology/webclient/FhirTerminologyServiceWebClient.java +++ b/src/main/java/gov/cms/madie/terminology/webclient/FhirTerminologyServiceWebClient.java @@ -14,6 +14,7 @@ import org.springframework.http.MediaType; import org.springframework.stereotype.Component; import org.springframework.web.reactive.function.client.WebClient; +import org.springframework.web.util.DefaultUriBuilderFactory; import org.springframework.web.util.UriComponentsBuilder; import reactor.core.publisher.Mono; @@ -42,9 +43,12 @@ public FhirTerminologyServiceWebClient( @Value("${client.fhir-terminology-service.code-lookups}") String codeLookupsUrl, @Value("${client.default_profile}") String defaultProfile, @Value("${client.search_value_set_endpoint}") String searchValueSetEndpoint) { + DefaultUriBuilderFactory uriBuilderFactory = + new DefaultUriBuilderFactory(fhirTerminologyServiceBaseUrl); + uriBuilderFactory.setEncodingMode(DefaultUriBuilderFactory.EncodingMode.NONE); fhirTerminologyWebClient = WebClient.builder() - .baseUrl(fhirTerminologyServiceBaseUrl) + .uriBuilderFactory(uriBuilderFactory) .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) .codecs( clientCodecConfigurer -> clientCodecConfigurer.defaultCodecs().maxInMemorySize(-1)) diff --git a/src/test/java/gov/cms/madie/terminology/controller/VsacFhirTerminologyControllerTest.java b/src/test/java/gov/cms/madie/terminology/controller/VsacFhirTerminologyControllerTest.java index 58d8579..7a41569 100644 --- a/src/test/java/gov/cms/madie/terminology/controller/VsacFhirTerminologyControllerTest.java +++ b/src/test/java/gov/cms/madie/terminology/controller/VsacFhirTerminologyControllerTest.java @@ -285,7 +285,8 @@ void testSearchValueSets() { Principal principal = mock(Principal.class); when(principal.getName()).thenReturn(TEST_USER); when(vsacService.verifyUmlsAccess(anyString())).thenReturn(umlsUser); - when(fhirTerminologyService.searchValueSets(any(), any())).thenReturn(ValueSetSearchResult.builder().valueSets(mockValueSets).build()); + when(fhirTerminologyService.searchValueSets(any(), any())) + .thenReturn(ValueSetSearchResult.builder().valueSets(mockValueSets).build()); Map queryParams = new HashMap<>(); queryParams.put("param1", "value1"); queryParams.put("param2", "value2"); 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 6ca58fd..10c84f2 100644 --- a/src/test/java/gov/cms/madie/terminology/webclient/FhirTerminologyServiceWebClientTest.java +++ b/src/test/java/gov/cms/madie/terminology/webclient/FhirTerminologyServiceWebClientTest.java @@ -8,7 +8,6 @@ import okhttp3.mockwebserver.RecordedRequest; import org.junit.jupiter.api.*; import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.http.HttpStatus; import org.springframework.web.reactive.function.client.WebClientResponseException; @@ -31,7 +30,7 @@ class FhirTerminologyServiceWebClientTest { private ValueSetsSearchCriteria.ValueSetParams testValueSetParams; - @InjectMocks FhirTerminologyServiceWebClient fhirTerminologyServiceWebClient; + FhirTerminologyServiceWebClient fhirTerminologyServiceWebClient; @BeforeAll static void setUp() throws IOException {