Skip to content

Commit 7532313

Browse files
IanMMarshallianmarshall
andauthored
Change to not set ValueSet expansion component parameter id HibernateSearch not enabled. (#2178)
Co-authored-by: ianmarshall <[email protected]>
1 parent d15a300 commit 7532313

File tree

2 files changed

+257
-6
lines changed

2 files changed

+257
-6
lines changed

hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/BaseTermReadSvcImpl.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,6 @@
141141
import org.springframework.transaction.annotation.Transactional;
142142
import org.springframework.transaction.interceptor.NoRollbackRuleAttribute;
143143
import org.springframework.transaction.interceptor.RuleBasedTransactionAttribute;
144-
import org.springframework.transaction.support.TransactionCallback;
145144
import org.springframework.transaction.support.TransactionSynchronizationManager;
146145
import org.springframework.transaction.support.TransactionTemplate;
147146

@@ -173,7 +172,6 @@
173172
import java.util.Optional;
174173
import java.util.Set;
175174
import java.util.UUID;
176-
import java.util.concurrent.Callable;
177175
import java.util.concurrent.TimeUnit;
178176
import java.util.concurrent.atomic.AtomicInteger;
179177
import java.util.function.Supplier;
@@ -428,10 +426,8 @@ public ValueSet expandValueSet(ValueSetExpansionOptions theExpansionOptions, Val
428426
accumulator.setTimestamp(new Date());
429427
accumulator.setOffset(offset);
430428

431-
if (theExpansionOptions != null) {
429+
if (theExpansionOptions != null && isHibernateSearchEnabled()) {
432430
accumulator.addParameter().setName("offset").setValue(new IntegerType(offset));
433-
}
434-
if (theExpansionOptions != null) {
435431
accumulator.addParameter().setName("count").setValue(new IntegerType(count));
436432
}
437433

@@ -854,6 +850,10 @@ private Boolean expandValueSetHandleIncludeOrExclude(@Nullable ValueSetExpansion
854850

855851
}
856852

853+
private boolean isHibernateSearchEnabled() {
854+
return myFulltextSearchSvc != null;
855+
}
856+
857857
@Nonnull
858858
private Boolean expandValueSetHandleIncludeOrExcludeUsingDatabase(IValueSetConceptAccumulator theValueSetCodeAccumulator, Set<String> theAddedCodes, ValueSet.ConceptSetComponent theIncludeOrExclude, boolean theAdd, int theQueryIndex, @Nonnull ExpansionFilter theExpansionFilter, String theSystem, TermCodeSystem theCs) {
859859
String includeOrExcludeVersion = theIncludeOrExclude.getVersion();
@@ -869,7 +869,7 @@ private Boolean expandValueSetHandleIncludeOrExcludeUsingDatabase(IValueSetConce
869869
* If FullText searching is not enabled, we can handle only basic expansions
870870
* since we're going to do it without the database.
871871
*/
872-
if (myFulltextSearchSvc == null) {
872+
if (!isHibernateSearchEnabled()) {
873873
expandWithoutHibernateSearch(theValueSetCodeAccumulator, csv, theAddedCodes, theIncludeOrExclude, theSystem, theAdd);
874874
return false;
875875
}
Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
package ca.uhn.fhir.jpa.provider.r4;
2+
3+
import ca.uhn.fhir.context.FhirContext;
4+
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoCodeSystem;
5+
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoValueSet;
6+
import ca.uhn.fhir.jpa.config.TestR4WithLuceneDisabledConfig;
7+
import ca.uhn.fhir.jpa.dao.BaseJpaTest;
8+
import ca.uhn.fhir.jpa.dao.dstu2.FhirResourceDaoDstu2SearchNoFtTest;
9+
import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider;
10+
import ca.uhn.fhir.jpa.subscription.match.config.WebsocketDispatcherConfig;
11+
import ca.uhn.fhir.parser.IParser;
12+
import ca.uhn.fhir.parser.StrictErrorHandler;
13+
import ca.uhn.fhir.rest.api.EncodingEnum;
14+
import ca.uhn.fhir.rest.client.api.IGenericClient;
15+
import ca.uhn.fhir.rest.client.api.ServerValidationModeEnum;
16+
import ca.uhn.fhir.rest.server.RestfulServer;
17+
import ca.uhn.fhir.rest.server.interceptor.CorsInterceptor;
18+
import ca.uhn.fhir.rest.server.provider.ResourceProviderFactory;
19+
import ca.uhn.fhir.test.utilities.JettyUtil;
20+
import org.apache.commons.io.IOUtils;
21+
import org.eclipse.jetty.server.Server;
22+
import org.eclipse.jetty.servlet.ServletContextHandler;
23+
import org.eclipse.jetty.servlet.ServletHolder;
24+
import org.hl7.fhir.instance.model.api.IBaseResource;
25+
import org.hl7.fhir.instance.model.api.IIdType;
26+
import org.hl7.fhir.r4.model.CodeSystem;
27+
import org.hl7.fhir.r4.model.CodeableConcept;
28+
import org.hl7.fhir.r4.model.Coding;
29+
import org.hl7.fhir.r4.model.Parameters;
30+
import org.hl7.fhir.r4.model.ValueSet;
31+
import org.junit.jupiter.api.BeforeEach;
32+
import org.junit.jupiter.api.Test;
33+
import org.junit.jupiter.api.extension.ExtendWith;
34+
import org.springframework.beans.factory.annotation.Autowired;
35+
import org.springframework.beans.factory.annotation.Qualifier;
36+
import org.springframework.context.ApplicationContext;
37+
import org.springframework.test.context.ContextConfiguration;
38+
import org.springframework.test.context.junit.jupiter.SpringExtension;
39+
import org.springframework.transaction.PlatformTransactionManager;
40+
import org.springframework.transaction.TransactionStatus;
41+
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
42+
import org.springframework.transaction.support.TransactionTemplate;
43+
import org.springframework.web.context.ContextLoader;
44+
import org.springframework.web.context.WebApplicationContext;
45+
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
46+
import org.springframework.web.context.support.GenericWebApplicationContext;
47+
import org.springframework.web.cors.CorsConfiguration;
48+
import org.springframework.web.servlet.DispatcherServlet;
49+
50+
import javax.annotation.Nonnull;
51+
import java.io.IOException;
52+
import java.io.InputStream;
53+
import java.nio.charset.StandardCharsets;
54+
import java.util.Arrays;
55+
56+
import static org.hamcrest.MatcherAssert.assertThat;
57+
import static org.hamcrest.Matchers.containsString;
58+
import static org.junit.jupiter.api.Assertions.fail;
59+
60+
@ExtendWith(SpringExtension.class)
61+
@ContextConfiguration(classes = {TestR4WithLuceneDisabledConfig.class})
62+
public class ResourceProviderR4ValueSetLuceneDisabledTest extends BaseJpaTest {
63+
64+
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ResourceProviderR4ValueSetLuceneDisabledTest.class);
65+
66+
private static RestfulServer ourRestServer;
67+
private static String ourServerBase;
68+
private static Server ourServer;
69+
private static DatabaseBackedPagingProvider ourPagingProvider;
70+
71+
@Autowired
72+
private FhirContext myFhirCtx;
73+
@Autowired
74+
private PlatformTransactionManager myTxManager;
75+
@Autowired
76+
@Qualifier("myCodeSystemDaoR4")
77+
private IFhirResourceDaoCodeSystem<CodeSystem, Coding, CodeableConcept> myCodeSystemDao;
78+
@Autowired
79+
@Qualifier("myValueSetDaoR4")
80+
private IFhirResourceDaoValueSet<ValueSet, Coding, CodeableConcept> myValueSetDao;
81+
@Autowired
82+
@Qualifier("myResourceProvidersR4")
83+
private ResourceProviderFactory myResourceProviders;
84+
@Autowired
85+
private ApplicationContext myAppCtx;
86+
87+
88+
private IIdType myExtensionalCsId;
89+
private IIdType myExtensionalVsId;
90+
private IGenericClient myClient;
91+
92+
private void loadAndPersistCodeSystemAndValueSet() throws IOException {
93+
loadAndPersistCodeSystem();
94+
loadAndPersistValueSet();
95+
}
96+
97+
private <T extends IBaseResource> T loadResourceFromClasspath(Class<T> type, String resourceName) throws IOException {
98+
InputStream stream = FhirResourceDaoDstu2SearchNoFtTest.class.getResourceAsStream(resourceName);
99+
if (stream == null) {
100+
fail("Unable to load resource: " + resourceName);
101+
}
102+
String string = IOUtils.toString(stream, StandardCharsets.UTF_8);
103+
IParser newJsonParser = EncodingEnum.detectEncodingNoDefault(string).newParser(myFhirCtx);
104+
return newJsonParser.parseResource(type, string);
105+
}
106+
107+
private void loadAndPersistCodeSystem() throws IOException {
108+
CodeSystem codeSystem = loadResourceFromClasspath(CodeSystem.class, "/extensional-case-3-cs.xml");
109+
codeSystem.setId("CodeSystem/cs");
110+
persistCodeSystem(codeSystem);
111+
}
112+
113+
private void persistCodeSystem(CodeSystem theCodeSystem) {
114+
new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
115+
@Override
116+
protected void doInTransactionWithoutResult(@Nonnull TransactionStatus theStatus) {
117+
myExtensionalCsId = myCodeSystemDao.create(theCodeSystem, mySrd).getId().toUnqualifiedVersionless();
118+
}
119+
});
120+
myCodeSystemDao.readEntity(myExtensionalCsId, null).getId();
121+
}
122+
123+
private void loadAndPersistValueSet() throws IOException {
124+
ValueSet valueSet = loadResourceFromClasspath(ValueSet.class, "/extensional-case-3-vs.xml");
125+
valueSet.setId("ValueSet/vs");
126+
persistValueSet(valueSet);
127+
}
128+
129+
private void persistValueSet(ValueSet theValueSet) {
130+
new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
131+
@Override
132+
protected void doInTransactionWithoutResult(@Nonnull TransactionStatus theStatus) {
133+
myExtensionalVsId = myValueSetDao.create(theValueSet, mySrd).getId().toUnqualifiedVersionless();
134+
}
135+
});
136+
myValueSetDao.readEntity(myExtensionalVsId, null).getId();
137+
}
138+
139+
@Override
140+
protected FhirContext getContext() {
141+
return myFhirCtx;
142+
}
143+
144+
@Override
145+
protected PlatformTransactionManager getTxManager() {
146+
return myTxManager;
147+
}
148+
149+
150+
@Test
151+
public void testExpandById() throws Exception {
152+
loadAndPersistCodeSystemAndValueSet();
153+
154+
Parameters respParam = myClient
155+
.operation()
156+
.onInstance(myExtensionalVsId)
157+
.named("expand")
158+
.withNoParameters(Parameters.class)
159+
.execute();
160+
ValueSet expanded = (ValueSet) respParam.getParameter().get(0).getResource();
161+
162+
String resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(expanded);
163+
ourLog.info(resp);
164+
assertThat(resp, containsString("<ValueSet xmlns=\"http://hl7.org/fhir\">"));
165+
assertThat(resp, containsString("<expansion>"));
166+
assertThat(resp, containsString("<contains>"));
167+
assertThat(resp, containsString("<system value=\"http://acme.org\"/>"));
168+
assertThat(resp, containsString("<code value=\"8450-9\"/>"));
169+
assertThat(resp, containsString("<display value=\"Systolic blood pressure--expiration\"/>"));
170+
assertThat(resp, containsString("</contains>"));
171+
assertThat(resp, containsString("<contains>"));
172+
assertThat(resp, containsString("<system value=\"http://acme.org\"/>"));
173+
assertThat(resp, containsString("<code value=\"11378-7\"/>"));
174+
assertThat(resp, containsString("<display value=\"Systolic blood pressure at First encounter\"/>"));
175+
assertThat(resp, containsString("</contains>"));
176+
assertThat(resp, containsString("</expansion>"));
177+
178+
}
179+
180+
@BeforeEach
181+
public void before() throws Exception {
182+
myFhirCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER);
183+
myFhirCtx.getRestfulClientFactory().setSocketTimeout(1200 * 1000);
184+
myFhirCtx.setParserErrorHandler(new StrictErrorHandler());
185+
186+
if (ourServer == null) {
187+
ourRestServer = new RestfulServer(myFhirCtx);
188+
ourRestServer.registerProviders(myResourceProviders.createProviders());
189+
ourRestServer.setDefaultResponseEncoding(EncodingEnum.XML);
190+
191+
ourPagingProvider = myAppCtx.getBean(DatabaseBackedPagingProvider.class);
192+
193+
Server server = new Server(0);
194+
195+
ServletContextHandler proxyHandler = new ServletContextHandler();
196+
proxyHandler.setContextPath("/");
197+
198+
ServletHolder servletHolder = new ServletHolder();
199+
servletHolder.setServlet(ourRestServer);
200+
proxyHandler.addServlet(servletHolder, "/fhir/context/*");
201+
202+
GenericWebApplicationContext webApplicationContext = new GenericWebApplicationContext();
203+
webApplicationContext.setParent(myAppCtx);
204+
webApplicationContext.refresh();
205+
proxyHandler.getServletContext().setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, webApplicationContext);
206+
207+
DispatcherServlet dispatcherServlet = new DispatcherServlet();
208+
// dispatcherServlet.setApplicationContext(webApplicationContext);
209+
dispatcherServlet.setContextClass(AnnotationConfigWebApplicationContext.class);
210+
ServletHolder subsServletHolder = new ServletHolder();
211+
subsServletHolder.setServlet(dispatcherServlet);
212+
subsServletHolder.setInitParameter(
213+
ContextLoader.CONFIG_LOCATION_PARAM,
214+
WebsocketDispatcherConfig.class.getName());
215+
proxyHandler.addServlet(subsServletHolder, "/*");
216+
217+
// Register a CORS filter
218+
CorsConfiguration config = new CorsConfiguration();
219+
CorsInterceptor corsInterceptor = new CorsInterceptor(config);
220+
config.addAllowedHeader("x-fhir-starter");
221+
config.addAllowedHeader("Origin");
222+
config.addAllowedHeader("Accept");
223+
config.addAllowedHeader("X-Requested-With");
224+
config.addAllowedHeader("Content-Type");
225+
config.addAllowedHeader("Access-Control-Request-Method");
226+
config.addAllowedHeader("Access-Control-Request-Headers");
227+
config.addAllowedOrigin("*");
228+
config.addExposedHeader("Location");
229+
config.addExposedHeader("Content-Location");
230+
config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS"));
231+
ourRestServer.registerInterceptor(corsInterceptor);
232+
233+
server.setHandler(proxyHandler);
234+
JettyUtil.startServer(server);
235+
int port = JettyUtil.getPortForStartedServer(server);
236+
ourServerBase = "http://localhost:" + port + "/fhir/context";
237+
238+
myFhirCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER);
239+
myFhirCtx.getRestfulClientFactory().setSocketTimeout(20000);
240+
241+
ourServer = server;
242+
}
243+
244+
ourRestServer.setPagingProvider(ourPagingProvider);
245+
246+
myClient = myFhirCtx.newRestfulGenericClient(ourServerBase);
247+
}
248+
249+
250+
251+
}

0 commit comments

Comments
 (0)