testing complete. Now just need pre-review cleanup.

This commit is contained in:
Ken Stevens 2020-01-21 17:06:19 -05:00
parent 12dfac927e
commit 6cebb56f13
6 changed files with 111 additions and 87 deletions

View File

@ -2755,74 +2755,7 @@ public class SearchBuilder implements ISearchBuilder {
myParams.getEverythingMode() == null &&
myParams.isAllParametersHaveNoModifier();
if (couldBeEligibleForCompositeUniqueSpProcessing) {
// FIXME KHS method
// Since we're going to remove elements below
theParams.values().forEach(nextAndList -> ensureSubListsAreWritable(nextAndList));
List<JpaRuntimeSearchParam> activeUniqueSearchParams = mySearchParamRegistry.getActiveUniqueSearchParams(myResourceName, theParams.keySet());
if (activeUniqueSearchParams.size() > 0) {
StringBuilder sb = new StringBuilder();
sb.append(myResourceName);
sb.append("?");
boolean first = true;
ArrayList<String> keys = new ArrayList<>(theParams.keySet());
Collections.sort(keys);
for (String nextParamName : keys) {
List<List<IQueryParameterType>> nextValues = theParams.get(nextParamName);
nextParamName = UrlUtil.escapeUrlParam(nextParamName);
if (nextValues.get(0).size() != 1) {
sb = null;
break;
}
// Reference params are only eligible for using a composite index if they
// are qualified
RuntimeSearchParam nextParamDef = mySearchParamRegistry.getActiveSearchParam(myResourceName, nextParamName);
if (nextParamDef.getParamType() == RestSearchParameterTypeEnum.REFERENCE) {
ReferenceParam param = (ReferenceParam) nextValues.get(0).get(0);
if (isBlank(param.getResourceType())) {
sb = null;
break;
}
}
List<? extends IQueryParameterType> nextAnd = nextValues.remove(0);
IQueryParameterType nextOr = nextAnd.remove(0);
String nextOrValue = nextOr.getValueAsQueryToken(myContext);
nextOrValue = UrlUtil.escapeUrlParam(nextOrValue);
if (first) {
first = false;
} else {
sb.append('&');
}
sb.append(nextParamName).append('=').append(nextOrValue);
}
if (sb != null) {
String indexString = sb.toString();
ourLog.debug("Checking for unique index for query: {}", indexString);
// Interceptor broadcast: JPA_PERFTRACE_INFO
StorageProcessingMessage msg = new StorageProcessingMessage()
.setMessage("Using unique index for query for search: " + indexString);
HookParams params = new HookParams()
.add(RequestDetails.class, theRequest)
.addIfMatchesType(ServletRequestDetails.class, theRequest)
.add(StorageProcessingMessage.class, msg);
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequest, Pointcut.JPA_PERFTRACE_INFO, params);
addPredicateCompositeStringUnique(theParams, indexString);
}
}
attemptCompositeUniqueSpProcessing(theParams, theRequest);
}
// Handle each parameter
@ -2834,6 +2767,74 @@ public class SearchBuilder implements ISearchBuilder {
}
private void attemptCompositeUniqueSpProcessing(@Nonnull SearchParameterMap theParams, RequestDetails theRequest) {
// Since we're going to remove elements below
theParams.values().forEach(nextAndList -> ensureSubListsAreWritable(nextAndList));
List<JpaRuntimeSearchParam> activeUniqueSearchParams = mySearchParamRegistry.getActiveUniqueSearchParams(myResourceName, theParams.keySet());
if (activeUniqueSearchParams.size() > 0) {
StringBuilder sb = new StringBuilder();
sb.append(myResourceName);
sb.append("?");
boolean first = true;
ArrayList<String> keys = new ArrayList<>(theParams.keySet());
Collections.sort(keys);
for (String nextParamName : keys) {
List<List<IQueryParameterType>> nextValues = theParams.get(nextParamName);
nextParamName = UrlUtil.escapeUrlParam(nextParamName);
if (nextValues.get(0).size() != 1) {
sb = null;
break;
}
// Reference params are only eligible for using a composite index if they
// are qualified
RuntimeSearchParam nextParamDef = mySearchParamRegistry.getActiveSearchParam(myResourceName, nextParamName);
if (nextParamDef.getParamType() == RestSearchParameterTypeEnum.REFERENCE) {
ReferenceParam param = (ReferenceParam) nextValues.get(0).get(0);
if (isBlank(param.getResourceType())) {
sb = null;
break;
}
}
List<? extends IQueryParameterType> nextAnd = nextValues.remove(0);
IQueryParameterType nextOr = nextAnd.remove(0);
String nextOrValue = nextOr.getValueAsQueryToken(myContext);
nextOrValue = UrlUtil.escapeUrlParam(nextOrValue);
if (first) {
first = false;
} else {
sb.append('&');
}
sb.append(nextParamName).append('=').append(nextOrValue);
}
if (sb != null) {
String indexString = sb.toString();
ourLog.debug("Checking for unique index for query: {}", indexString);
// Interceptor broadcast: JPA_PERFTRACE_INFO
StorageProcessingMessage msg = new StorageProcessingMessage()
.setMessage("Using unique index for query for search: " + indexString);
HookParams params = new HookParams()
.add(RequestDetails.class, theRequest)
.addIfMatchesType(ServletRequestDetails.class, theRequest)
.add(StorageProcessingMessage.class, msg);
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequest, Pointcut.JPA_PERFTRACE_INFO, params);
addPredicateCompositeStringUnique(theParams, indexString);
}
}
}
private <T> void ensureSubListsAreWritable(List<List<T>> theListOfLists) {
for (int i = 0; i < theListOfLists.size(); i++) {
List<T> oldSubList = theListOfLists.get(i);

View File

@ -20,8 +20,8 @@ import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.PlatformTransactionManager;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.*;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
@ -49,7 +49,7 @@ public class MatchUrlServiceTest extends BaseJpaTest {
SearchParameterMap match = myMatchUrlService.translateMatchUrl("Condition?patient=304&_lastUpdated=>2011-01-01T11:12:21.0000Z", resourceDef);
assertEquals("2011-01-01T11:12:21.0000Z", match.getLastUpdated().getLowerBound().getValueAsString());
assertEquals(ReferenceParam.class, match.get("patient").get(0).get(0).getClass());
assertEquals("304", ((ReferenceParam)match.get("patient").get(0).get(0)).getIdPart());
assertEquals("304", ((ReferenceParam) match.get("patient").get(0).get(0)).getIdPart());
}
@Test
@ -68,10 +68,42 @@ public class MatchUrlServiceTest extends BaseJpaTest {
assertEquals(kmDistance, nearDistanceParam.getValue().doubleValue(), 0.0);
}
@Test
public void testTwoDistancesAnd() {
try {
SearchParameterMap map = myMatchUrlService.translateMatchUrl(
"Location?" +
Location.SP_NEAR_DISTANCE + "=1|http://unitsofmeasure.org|km" +
"&" +
Location.SP_NEAR_DISTANCE + "=2|http://unitsofmeasure.org|km",
ourCtx.getResourceDefinition("Location"));
fail();
} catch (IllegalArgumentException e) {
assertEquals("Only one " + Location.SP_NEAR_DISTANCE + " parameter may be present", e.getMessage());
}
}
@Test
public void testTwoDistancesOr() {
try {
SearchParameterMap map = myMatchUrlService.translateMatchUrl(
"Location?" +
Location.SP_NEAR_DISTANCE + "=1|http://unitsofmeasure.org|km" +
"," +
"2|http://unitsofmeasure.org|km",
ourCtx.getResourceDefinition("Location"));
map.setLoadSynchronous(true);
fail();
} catch (IllegalArgumentException e) {
assertEquals("Only one " + Location.SP_NEAR_DISTANCE + " parameter may be present", e.getMessage());
}
}
@Override
protected FhirContext getContext() {
return ourCtx;
}
@Override
protected PlatformTransactionManager getTxManager() {
return null;

View File

@ -118,7 +118,6 @@ public class MatchUrlService {
paramMap.add(nextParamName, param);
} else if (Location.SP_NEAR_DISTANCE.equals(nextParamName)) {
QuantityAndListParam nearDistanceAndListParam = (QuantityAndListParam) ParameterUtil.parseQueryParams(myContext, RestSearchParameterTypeEnum.QUANTITY, nextParamName, paramList);
// FIXME KHS
paramMap.setNearDistanceParam(nearDistanceAndListParam);
} else if (nextParamName.startsWith("_")) {
// ignore these since they aren't search params (e.g. _sort)

View File

@ -5,6 +5,7 @@ import ca.uhn.fhir.model.api.IQueryParameterAnd;
import ca.uhn.fhir.model.api.IQueryParameterOr;
import ca.uhn.fhir.model.api.IQueryParameterType;
import ca.uhn.fhir.model.api.Include;
import ca.uhn.fhir.model.dstu2.resource.Location;
import ca.uhn.fhir.rest.api.*;
import ca.uhn.fhir.rest.param.*;
import ca.uhn.fhir.util.ObjectUtil;
@ -499,13 +500,17 @@ public class SearchParameterMap implements Serializable {
if (orTokens.isEmpty()) {
return;
}
// FIXME KHS error if size > 0
if (orTokens.size() > 1) {
throw new IllegalArgumentException("Only one " + Location.SP_NEAR_DISTANCE + " parameter may be present");
}
QuantityOrListParam quantityOrListParam = orTokens.get(0);
List<QuantityParam> tokens = quantityOrListParam.getValuesAsQueryTokens();
if (tokens.isEmpty()) {
return;
}
// FIXME KHS error if size > 0
if (tokens.size() > 1) {
throw new IllegalArgumentException("Only one " + Location.SP_NEAR_DISTANCE + " parameter may be present");
}
myNearDistanceParam = tokens.get(0);
}

View File

@ -275,7 +275,6 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor
case "Consent.source":
// Consent#source-identifier has a path that isn't typed - This is a one-off to deal with that
return;
// FIXME KHS
case "Location.position":
addCoords_Position(resourceTypeName, params, searchParam, value);
return;
@ -414,12 +413,6 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor
public SearchParamSet<ResourceIndexedSearchParamQuantity> extractSearchParamQuantity(IBaseResource theResource) {
IExtractor<ResourceIndexedSearchParamQuantity> extractor = (params, searchParam, value, path) -> {
// FIXME KHS
// if (value.getClass().equals(myLocationPositionDefinition.getImplementingClass())) {
// ourLog.warn("Position search not currently supported, not indexing location");
// return;
// }
String nextType = toRootTypeName(value);
String resourceType = toRootTypeName(theResource);
switch (nextType) {
@ -723,7 +716,6 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor
}
// FIXME KHS split this class up
private void addCoords_Position(String theResourceType, SearchParamSet<BaseResourceIndexedSearchParam> theParams, RuntimeSearchParam theSearchParam, IBase theValue) {
BigDecimal latitude = null;
BigDecimal longitude = null;

View File

@ -178,11 +178,6 @@ public class SearchParamExtractorMegaTest {
ISearchParamExtractor.SearchParamSet<?> set;
// FIXME KHS
// set = theExtractor.extractSearchParamCoords(resource);
// assertEquals(0, set.getWarnings().size());
// theIndexesCounter.addAndGet(set.size());
set = theExtractor.extractSearchParamDates(resource);
assertEquals(0, set.getWarnings().size());
theIndexesCounter.addAndGet(set.size());