More work on perf improvements
This commit is contained in:
parent
08e5681d8b
commit
90a4e2def2
|
@ -1,5 +1,7 @@
|
||||||
package ca.uhn.fhir.rest.api;
|
package ca.uhn.fhir.rest.api;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* #%L
|
* #%L
|
||||||
* HAPI FHIR - Core Library
|
* HAPI FHIR - Core Library
|
||||||
|
@ -24,7 +26,9 @@ package ca.uhn.fhir.rest.api;
|
||||||
* Represents values for <a href="http://hl7.org/implement/standards/fhir/search.html#sort">sorting</a> resources
|
* Represents values for <a href="http://hl7.org/implement/standards/fhir/search.html#sort">sorting</a> resources
|
||||||
* returned by a server.
|
* returned by a server.
|
||||||
*/
|
*/
|
||||||
public class SortSpec {
|
public class SortSpec implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 2866833099879713467L;
|
||||||
|
|
||||||
private SortSpec myChain;
|
private SortSpec myChain;
|
||||||
private String myParamName;
|
private String myParamName;
|
||||||
|
|
|
@ -128,11 +128,11 @@ public class SearchBuilder {
|
||||||
|
|
||||||
RuntimeSearchParam left = theParamDef.getCompositeOf().get(0);
|
RuntimeSearchParam left = theParamDef.getCompositeOf().get(0);
|
||||||
IQueryParameterType leftValue = cp.getLeftValue();
|
IQueryParameterType leftValue = cp.getLeftValue();
|
||||||
myPredicates.add(createCompositeParamPart(myBuilder, myResourceTableRoot, left, leftValue));
|
myPredicates.add(createCompositeParamPart(myResourceTableRoot, left, leftValue));
|
||||||
|
|
||||||
RuntimeSearchParam right = theParamDef.getCompositeOf().get(1);
|
RuntimeSearchParam right = theParamDef.getCompositeOf().get(1);
|
||||||
IQueryParameterType rightValue = cp.getRightValue();
|
IQueryParameterType rightValue = cp.getRightValue();
|
||||||
myPredicates.add(createCompositeParamPart(myBuilder, myResourceTableRoot, right, rightValue));
|
myPredicates.add(createCompositeParamPart(myResourceTableRoot, right, rightValue));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,7 +148,7 @@ public class SearchBuilder {
|
||||||
List<Predicate> codePredicates = new ArrayList<Predicate>();
|
List<Predicate> codePredicates = new ArrayList<Predicate>();
|
||||||
for (IQueryParameterType nextOr : theList) {
|
for (IQueryParameterType nextOr : theList) {
|
||||||
IQueryParameterType params = nextOr;
|
IQueryParameterType params = nextOr;
|
||||||
Predicate p = createPredicateDate(myBuilder, join, params);
|
Predicate p = createPredicateDate(params, theParamName, myBuilder, join);
|
||||||
codePredicates.add(p);
|
codePredicates.add(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,7 +288,7 @@ public class SearchBuilder {
|
||||||
String invalidMessageName = "invalidNumberPrefix";
|
String invalidMessageName = "invalidNumberPrefix";
|
||||||
String valueAsString = param.getValue().toPlainString();
|
String valueAsString = param.getValue().toPlainString();
|
||||||
|
|
||||||
Predicate num = createPredicateNumeric(myBuilder, params, prefix, value, fromObj, invalidMessageName, valueAsString);
|
Predicate num = createPredicateNumeric(theParamName, join, myBuilder, params, prefix, value, fromObj, invalidMessageName, valueAsString);
|
||||||
codePredicates.add(num);
|
codePredicates.add(num);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -320,7 +320,7 @@ public class SearchBuilder {
|
||||||
List<Predicate> codePredicates = new ArrayList<Predicate>();
|
List<Predicate> codePredicates = new ArrayList<Predicate>();
|
||||||
for (IQueryParameterType nextOr : theList) {
|
for (IQueryParameterType nextOr : theList) {
|
||||||
|
|
||||||
Predicate singleCode = createPredicateQuantity(myBuilder, join, nextOr);
|
Predicate singleCode = createPredicateQuantity(nextOr, theParamName, myBuilder, join);
|
||||||
codePredicates.add(singleCode);
|
codePredicates.add(singleCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -679,10 +679,6 @@ public class SearchBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
Predicate singleCode = createPredicateToken(nextOr, theParamName, myBuilder, join);
|
Predicate singleCode = createPredicateToken(nextOr, theParamName, myBuilder, join);
|
||||||
if (singleCode == null) {
|
|
||||||
doSetPids(new ArrayList<Long>());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
codePredicates.add(singleCode);
|
codePredicates.add(singleCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -691,10 +687,7 @@ public class SearchBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
Predicate spPredicate = myBuilder.or(toArray(codePredicates));
|
Predicate spPredicate = myBuilder.or(toArray(codePredicates));
|
||||||
|
myPredicates.add(spPredicate);
|
||||||
Predicate paramNamePredicate = myBuilder.equal(join.get("myParamName"), theParamName);
|
|
||||||
Predicate outerPredicate = myBuilder.and(paramNamePredicate, spPredicate);
|
|
||||||
myPredicates.add(outerPredicate);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addPredicateUri(String theParamName, List<? extends IQueryParameterType> theList) {
|
private void addPredicateUri(String theParamName, List<? extends IQueryParameterType> theList) {
|
||||||
|
@ -777,27 +770,27 @@ public class SearchBuilder {
|
||||||
myPredicates.add(outerPredicate);
|
myPredicates.add(outerPredicate);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Predicate createCompositeParamPart(CriteriaBuilder builder, Root<ResourceTable> from, RuntimeSearchParam left, IQueryParameterType leftValue) {
|
private Predicate createCompositeParamPart(Root<ResourceTable> theRoot, RuntimeSearchParam theParam, IQueryParameterType leftValue) {
|
||||||
Predicate retVal = null;
|
Predicate retVal = null;
|
||||||
switch (left.getParamType()) {
|
switch (theParam.getParamType()) {
|
||||||
case STRING: {
|
case STRING: {
|
||||||
From<ResourceIndexedSearchParamString, ResourceIndexedSearchParamString> stringJoin = from.join("myParamsString", JoinType.INNER);
|
From<ResourceIndexedSearchParamString, ResourceIndexedSearchParamString> stringJoin = theRoot.join("myParamsString", JoinType.INNER);
|
||||||
retVal = createPredicateString(leftValue, left.getName(), builder, stringJoin);
|
retVal = createPredicateString(leftValue, theParam.getName(), myBuilder, stringJoin);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TOKEN: {
|
case TOKEN: {
|
||||||
From<ResourceIndexedSearchParamToken, ResourceIndexedSearchParamToken> tokenJoin = from.join("myParamsToken", JoinType.INNER);
|
From<ResourceIndexedSearchParamToken, ResourceIndexedSearchParamToken> tokenJoin = theRoot.join("myParamsToken", JoinType.INNER);
|
||||||
retVal = createPredicateToken(leftValue, left.getName(), builder, tokenJoin);
|
retVal = createPredicateToken(leftValue, theParam.getName(), myBuilder, tokenJoin);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DATE: {
|
case DATE: {
|
||||||
From<ResourceIndexedSearchParamDate, ResourceIndexedSearchParamDate> dateJoin = from.join("myParamsDate", JoinType.INNER);
|
From<ResourceIndexedSearchParamDate, ResourceIndexedSearchParamDate> dateJoin = theRoot.join("myParamsDate", JoinType.INNER);
|
||||||
retVal = createPredicateDate(builder, dateJoin, leftValue);
|
retVal = createPredicateDate(leftValue, theParam.getName(), myBuilder, dateJoin);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case QUANTITY: {
|
case QUANTITY: {
|
||||||
From<ResourceIndexedSearchParamQuantity, ResourceIndexedSearchParamQuantity> dateJoin = from.join("myParamsQuantity", JoinType.INNER);
|
From<ResourceIndexedSearchParamQuantity, ResourceIndexedSearchParamQuantity> dateJoin = theRoot.join("myParamsQuantity", JoinType.INNER);
|
||||||
retVal = createPredicateQuantity(builder, dateJoin, leftValue);
|
retVal = createPredicateQuantity(leftValue, theParam.getName(), myBuilder, dateJoin);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case COMPOSITE:
|
case COMPOSITE:
|
||||||
|
@ -809,13 +802,13 @@ public class SearchBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (retVal == null) {
|
if (retVal == null) {
|
||||||
throw new InvalidRequestException("Don't know how to handle composite parameter with type of " + left.getParamType());
|
throw new InvalidRequestException("Don't know how to handle composite parameter with type of " + theParam.getParamType());
|
||||||
}
|
}
|
||||||
|
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Predicate createPredicateDate(CriteriaBuilder theBuilder, From<?, ResourceIndexedSearchParamDate> theFrom, IQueryParameterType theParam) {
|
private Predicate createPredicateDate(IQueryParameterType theParam, String theParamName, CriteriaBuilder theBuilder, From<?, ResourceIndexedSearchParamDate> theFrom) {
|
||||||
Predicate p;
|
Predicate p;
|
||||||
if (theParam instanceof DateParam) {
|
if (theParam instanceof DateParam) {
|
||||||
DateParam date = (DateParam) theParam;
|
DateParam date = (DateParam) theParam;
|
||||||
|
@ -832,7 +825,8 @@ public class SearchBuilder {
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("Invalid token type: " + theParam.getClass());
|
throw new IllegalArgumentException("Invalid token type: " + theParam.getClass());
|
||||||
}
|
}
|
||||||
return p;
|
|
||||||
|
return combineParamIndexPredicateWithParamNamePredicate(theParamName, theFrom, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Predicate createPredicateDateFromRange(CriteriaBuilder theBuilder, From<?, ResourceIndexedSearchParamDate> theFrom, DateRangeParam theRange) {
|
private Predicate createPredicateDateFromRange(CriteriaBuilder theBuilder, From<?, ResourceIndexedSearchParamDate> theFrom, DateRangeParam theRange) {
|
||||||
|
@ -892,50 +886,54 @@ public class SearchBuilder {
|
||||||
predicates.addAll(createLastUpdatedPredicates(myParams.getLastUpdatedAndRemove(), builder, from));
|
predicates.addAll(createLastUpdatedPredicates(myParams.getLastUpdatedAndRemove(), builder, from));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Predicate createPredicateNumeric(CriteriaBuilder builder, IQueryParameterType params, ParamPrefixEnum cmpValue, BigDecimal valueValue, final Expression<BigDecimal> path,
|
private Predicate createPredicateNumeric(String theParamName, From<?, ? extends BaseResourceIndexedSearchParam> theFrom, CriteriaBuilder builder, IQueryParameterType theParam, ParamPrefixEnum thePrefix, BigDecimal theValue, final Expression<BigDecimal> thePath,
|
||||||
String invalidMessageName, String theValueString) {
|
String invalidMessageName, String theValueString) {
|
||||||
Predicate num;
|
Predicate num;
|
||||||
switch (cmpValue) {
|
switch (thePrefix) {
|
||||||
case GREATERTHAN:
|
case GREATERTHAN:
|
||||||
num = builder.gt(path, valueValue);
|
num = builder.gt(thePath, theValue);
|
||||||
break;
|
break;
|
||||||
case GREATERTHAN_OR_EQUALS:
|
case GREATERTHAN_OR_EQUALS:
|
||||||
num = builder.ge(path, valueValue);
|
num = builder.ge(thePath, theValue);
|
||||||
break;
|
break;
|
||||||
case LESSTHAN:
|
case LESSTHAN:
|
||||||
num = builder.lt(path, valueValue);
|
num = builder.lt(thePath, theValue);
|
||||||
break;
|
break;
|
||||||
case LESSTHAN_OR_EQUALS:
|
case LESSTHAN_OR_EQUALS:
|
||||||
num = builder.le(path, valueValue);
|
num = builder.le(thePath, theValue);
|
||||||
break;
|
break;
|
||||||
case APPROXIMATE:
|
case APPROXIMATE:
|
||||||
case EQUAL:
|
case EQUAL:
|
||||||
case NOT_EQUAL:
|
case NOT_EQUAL:
|
||||||
BigDecimal mul = calculateFuzzAmount(cmpValue, valueValue);
|
BigDecimal mul = calculateFuzzAmount(thePrefix, theValue);
|
||||||
BigDecimal low = valueValue.subtract(mul, MathContext.DECIMAL64);
|
BigDecimal low = theValue.subtract(mul, MathContext.DECIMAL64);
|
||||||
BigDecimal high = valueValue.add(mul, MathContext.DECIMAL64);
|
BigDecimal high = theValue.add(mul, MathContext.DECIMAL64);
|
||||||
Predicate lowPred;
|
Predicate lowPred;
|
||||||
Predicate highPred;
|
Predicate highPred;
|
||||||
if (cmpValue != ParamPrefixEnum.NOT_EQUAL) {
|
if (thePrefix != ParamPrefixEnum.NOT_EQUAL) {
|
||||||
lowPred = builder.ge(path.as(BigDecimal.class), low);
|
lowPred = builder.ge(thePath.as(BigDecimal.class), low);
|
||||||
highPred = builder.le(path.as(BigDecimal.class), high);
|
highPred = builder.le(thePath.as(BigDecimal.class), high);
|
||||||
num = builder.and(lowPred, highPred);
|
num = builder.and(lowPred, highPred);
|
||||||
ourLog.trace("Searching for {} <= val <= {}", low, high);
|
ourLog.trace("Searching for {} <= val <= {}", low, high);
|
||||||
} else {
|
} else {
|
||||||
// Prefix was "ne", so reverse it!
|
// Prefix was "ne", so reverse it!
|
||||||
lowPred = builder.lt(path.as(BigDecimal.class), low);
|
lowPred = builder.lt(thePath.as(BigDecimal.class), low);
|
||||||
highPred = builder.gt(path.as(BigDecimal.class), high);
|
highPred = builder.gt(thePath.as(BigDecimal.class), high);
|
||||||
num = builder.or(lowPred, highPred);
|
num = builder.or(lowPred, highPred);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
String msg = myContext.getLocalizer().getMessage(SearchBuilder.class, invalidMessageName, cmpValue.getValue(), params.getValueAsQueryToken(myContext));
|
String msg = myContext.getLocalizer().getMessage(SearchBuilder.class, invalidMessageName, thePrefix.getValue(), theParam.getValueAsQueryToken(myContext));
|
||||||
throw new InvalidRequestException(msg);
|
throw new InvalidRequestException(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (theParamName == null) {
|
||||||
return num;
|
return num;
|
||||||
}
|
}
|
||||||
|
return combineParamIndexPredicateWithParamNamePredicate(theParamName, theFrom, num);
|
||||||
|
}
|
||||||
|
|
||||||
private Predicate createPredicateQuantity(CriteriaBuilder theBuilder, From<?, ResourceIndexedSearchParamQuantity> theFrom, IQueryParameterType theParam) {
|
private Predicate createPredicateQuantity(IQueryParameterType theParam, String theParamName, CriteriaBuilder theBuilder, From<?, ResourceIndexedSearchParamQuantity> theFrom) {
|
||||||
String systemValue;
|
String systemValue;
|
||||||
String unitsValue;
|
String unitsValue;
|
||||||
ParamPrefixEnum cmpValue;
|
ParamPrefixEnum cmpValue;
|
||||||
|
@ -974,7 +972,7 @@ public class SearchBuilder {
|
||||||
final Expression<BigDecimal> path = theFrom.get("myValue");
|
final Expression<BigDecimal> path = theFrom.get("myValue");
|
||||||
String invalidMessageName = "invalidQuantityPrefix";
|
String invalidMessageName = "invalidQuantityPrefix";
|
||||||
|
|
||||||
Predicate num = createPredicateNumeric(theBuilder, theParam, cmpValue, valueValue, path, invalidMessageName, valueString);
|
Predicate num = createPredicateNumeric(null, theFrom, theBuilder, theParam, cmpValue, valueValue, path, invalidMessageName, valueString);
|
||||||
|
|
||||||
Predicate singleCode;
|
Predicate singleCode;
|
||||||
if (system == null && code == null) {
|
if (system == null && code == null) {
|
||||||
|
@ -987,7 +985,7 @@ public class SearchBuilder {
|
||||||
singleCode = theBuilder.and(system, code, num);
|
singleCode = theBuilder.and(system, code, num);
|
||||||
}
|
}
|
||||||
|
|
||||||
return singleCode;
|
return combineParamIndexPredicateWithParamNamePredicate(theParamName, theFrom, singleCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createPredicateResourceId(CriteriaBuilder builder, AbstractQuery<?> cq, List<Predicate> thePredicates, Expression<Long> theExpression) {
|
private void createPredicateResourceId(CriteriaBuilder builder, AbstractQuery<?> cq, List<Predicate> thePredicates, Expression<Long> theExpression) {
|
||||||
|
@ -1035,8 +1033,13 @@ public class SearchBuilder {
|
||||||
singleCode = theBuilder.and(singleCode, exactCode);
|
singleCode = theBuilder.and(singleCode, exactCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return combineParamIndexPredicateWithParamNamePredicate(theParamName, theFrom, singleCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Predicate combineParamIndexPredicateWithParamNamePredicate(String theParamName, From<?, ? extends BaseResourceIndexedSearchParam> theFrom, Predicate thePredicate) {
|
||||||
|
Predicate resourceTypePredicate = myBuilder.equal(theFrom.get("myResourceType"), myResourceName);
|
||||||
Predicate paramNamePredicate = myBuilder.equal(theFrom.get("myParamName"), theParamName);
|
Predicate paramNamePredicate = myBuilder.equal(theFrom.get("myParamName"), theParamName);
|
||||||
Predicate outerPredicate = myBuilder.and(paramNamePredicate, singleCode);
|
Predicate outerPredicate = myBuilder.and(resourceTypePredicate, paramNamePredicate, thePredicate);
|
||||||
return outerPredicate;
|
return outerPredicate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1103,10 +1106,17 @@ public class SearchBuilder {
|
||||||
codes = myTerminologySvc.findCodesBelow(system, code);
|
codes = myTerminologySvc.findCodesBelow(system, code);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ArrayList<Predicate> singleCodePredicates = (new ArrayList<Predicate>());
|
||||||
if (codes != null) {
|
if (codes != null) {
|
||||||
|
|
||||||
if (codes.isEmpty()) {
|
if (codes.isEmpty()) {
|
||||||
return null;
|
|
||||||
}
|
// This will never match anything
|
||||||
|
Predicate systemPredicate = theBuilder.isNull(theFrom.get("mySystem"));
|
||||||
|
Predicate codePredicate = theBuilder.isNull(theFrom.get("myValue"));
|
||||||
|
singleCodePredicates.add(theBuilder.and(systemPredicate, codePredicate));
|
||||||
|
|
||||||
|
} else {
|
||||||
List<Predicate> orPredicates = new ArrayList<Predicate>();
|
List<Predicate> orPredicates = new ArrayList<Predicate>();
|
||||||
for (VersionIndependentConcept nextCode : codes) {
|
for (VersionIndependentConcept nextCode : codes) {
|
||||||
Predicate systemPredicate = theBuilder.equal(theFrom.get("mySystem"), nextCode.getSystem());
|
Predicate systemPredicate = theBuilder.equal(theFrom.get("mySystem"), nextCode.getSystem());
|
||||||
|
@ -1114,14 +1124,15 @@ public class SearchBuilder {
|
||||||
orPredicates.add(theBuilder.and(systemPredicate, codePredicate));
|
orPredicates.add(theBuilder.and(systemPredicate, codePredicate));
|
||||||
}
|
}
|
||||||
|
|
||||||
return theBuilder.or(orPredicates.toArray(new Predicate[orPredicates.size()]));
|
singleCodePredicates.add(theBuilder.or(orPredicates.toArray(new Predicate[orPredicates.size()])));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ok, this is a normal query
|
* Ok, this is a normal query
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ArrayList<Predicate> singleCodePredicates = (new ArrayList<Predicate>());
|
|
||||||
if (StringUtils.isNotBlank(system)) {
|
if (StringUtils.isNotBlank(system)) {
|
||||||
singleCodePredicates.add(theBuilder.equal(theFrom.get("mySystem"), system));
|
singleCodePredicates.add(theBuilder.equal(theFrom.get("mySystem"), system));
|
||||||
} else if (system == null) {
|
} else if (system == null) {
|
||||||
|
@ -1142,9 +1153,10 @@ public class SearchBuilder {
|
||||||
*/
|
*/
|
||||||
// singleCodePredicates.add(theBuilder.isNull(theFrom.get("myValue")));
|
// singleCodePredicates.add(theBuilder.isNull(theFrom.get("myValue")));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Predicate singleCode = theBuilder.and(toArray(singleCodePredicates));
|
Predicate singleCode = theBuilder.and(toArray(singleCodePredicates));
|
||||||
return singleCode;
|
return combineParamIndexPredicateWithParamNamePredicate(theParamName, theFrom, singleCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Predicate createResourceLinkPathPredicate(String theParamName, From<?, ? extends ResourceLink> from) {
|
private Predicate createResourceLinkPathPredicate(String theParamName, From<?, ? extends ResourceLink> from) {
|
||||||
|
|
|
@ -58,7 +58,7 @@ public class TestDstu3Config extends BaseJavaConfigDstu3 {
|
||||||
private Properties jpaProperties() {
|
private Properties jpaProperties() {
|
||||||
Properties extraProperties = new Properties();
|
Properties extraProperties = new Properties();
|
||||||
extraProperties.put("hibernate.jdbc.batch_size", "50");
|
extraProperties.put("hibernate.jdbc.batch_size", "50");
|
||||||
extraProperties.put("hibernate.format_sql", "false");
|
extraProperties.put("hibernate.format_sql", "true");
|
||||||
extraProperties.put("hibernate.show_sql", "false");
|
extraProperties.put("hibernate.show_sql", "false");
|
||||||
extraProperties.put("hibernate.hbm2ddl.auto", "update");
|
extraProperties.put("hibernate.hbm2ddl.auto", "update");
|
||||||
extraProperties.put("hibernate.dialect", "org.hibernate.dialect.DerbyTenSevenDialect");
|
extraProperties.put("hibernate.dialect", "org.hibernate.dialect.DerbyTenSevenDialect");
|
||||||
|
|
|
@ -114,6 +114,9 @@ public abstract class BaseJpaDstu3Test extends BaseJpaTest {
|
||||||
@Autowired
|
@Autowired
|
||||||
@Qualifier("myImmunizationDaoDstu3")
|
@Qualifier("myImmunizationDaoDstu3")
|
||||||
protected IFhirResourceDao<Immunization> myImmunizationDao;
|
protected IFhirResourceDao<Immunization> myImmunizationDao;
|
||||||
|
@Autowired
|
||||||
|
@Qualifier("myImmunizationRecommendationDaoDstu3")
|
||||||
|
protected IFhirResourceDao<ImmunizationRecommendation> myImmunizationRecommendationDao;
|
||||||
protected IServerInterceptor myInterceptor;
|
protected IServerInterceptor myInterceptor;
|
||||||
@Autowired
|
@Autowired
|
||||||
private JpaValidationSupportChainDstu3 myJpaValidationSupportChainDstu3;
|
private JpaValidationSupportChainDstu3 myJpaValidationSupportChainDstu3;
|
||||||
|
|
|
@ -31,6 +31,7 @@ import org.hl7.fhir.dstu3.model.ContactPoint.ContactPointSystem;
|
||||||
import org.hl7.fhir.dstu3.model.Enumerations.AdministrativeGender;
|
import org.hl7.fhir.dstu3.model.Enumerations.AdministrativeGender;
|
||||||
import org.hl7.fhir.dstu3.model.Subscription.SubscriptionChannelType;
|
import org.hl7.fhir.dstu3.model.Subscription.SubscriptionChannelType;
|
||||||
import org.hl7.fhir.dstu3.model.Subscription.SubscriptionStatus;
|
import org.hl7.fhir.dstu3.model.Subscription.SubscriptionStatus;
|
||||||
|
import org.hl7.fhir.exceptions.FHIRException;
|
||||||
import org.hl7.fhir.instance.model.api.IAnyResource;
|
import org.hl7.fhir.instance.model.api.IAnyResource;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
import org.hl7.fhir.instance.model.api.IIdType;
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
|
@ -636,6 +637,10 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
|
||||||
map.put(Subscription.SP_TYPE, new TokenParam(null, SubscriptionChannelType.WEBSOCKET.toCode()));
|
map.put(Subscription.SP_TYPE, new TokenParam(null, SubscriptionChannelType.WEBSOCKET.toCode()));
|
||||||
map.put(Subscription.SP_STATUS, new TokenParam(null, SubscriptionStatus.ACTIVE.toCode() + "2"));
|
map.put(Subscription.SP_STATUS, new TokenParam(null, SubscriptionStatus.ACTIVE.toCode() + "2"));
|
||||||
assertThat(toUnqualifiedVersionlessIds(mySubscriptionDao.search(map)), empty());
|
assertThat(toUnqualifiedVersionlessIds(mySubscriptionDao.search(map)), empty());
|
||||||
|
|
||||||
|
// Wrong param
|
||||||
|
map.put(Subscription.SP_STATUS, new TokenParam(null, SubscriptionChannelType.WEBSOCKET.toCode()));
|
||||||
|
assertThat(toUnqualifiedVersionlessIds(mySubscriptionDao.search(map)), empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -733,8 +738,7 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
|
||||||
IIdType id2 = myObservationDao.create(o2, mySrd).getId().toUnqualifiedVersionless();
|
IIdType id2 = myObservationDao.create(o2, mySrd).getId().toUnqualifiedVersionless();
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
|
|
||||||
// Was Observation.SP_COMPONENT_CODE_VALUE_QUANTITY
|
String param = Observation.SP_COMPONENT_CODE_VALUE_QUANTITY;
|
||||||
String param = Observation.SP_CODE_VALUE_QUANTITY;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
TokenParam v0 = new TokenParam("http://foo", "code1");
|
TokenParam v0 = new TokenParam("http://foo", "code1");
|
||||||
|
@ -766,6 +770,29 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSearchDateWrongParam() {
|
||||||
|
Patient p1 = new Patient();
|
||||||
|
p1.getBirthDateElement().setValueAsString("1980-01-01");
|
||||||
|
String id1 = myPatientDao.create(p1).getId().toUnqualifiedVersionless().getValue();
|
||||||
|
|
||||||
|
Patient p2 = new Patient();
|
||||||
|
p2.setDeceased(new DateTimeType("1980-01-01"));
|
||||||
|
String id2 = myPatientDao.create(p2).getId().toUnqualifiedVersionless().getValue();
|
||||||
|
|
||||||
|
{
|
||||||
|
IBundleProvider found = myPatientDao.search(Patient.SP_BIRTHDATE, new DateParam("1980-01-01"));
|
||||||
|
assertThat(toUnqualifiedVersionlessIdValues(found), containsInAnyOrder(id1));
|
||||||
|
assertEquals(1, found.size());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
IBundleProvider found = myPatientDao.search(Patient.SP_DEATH_DATE, new DateParam("1980-01-01"));
|
||||||
|
assertThat(toUnqualifiedVersionlessIdValues(found), containsInAnyOrder(id2));
|
||||||
|
assertEquals(1, found.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* #222
|
* #222
|
||||||
*/
|
*/
|
||||||
|
@ -1170,6 +1197,54 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSearchNumberWrongParam() {
|
||||||
|
ImmunizationRecommendation ir1 = new ImmunizationRecommendation();
|
||||||
|
ir1.addRecommendation().setDoseNumber(1);
|
||||||
|
String id1 = myImmunizationRecommendationDao.create(ir1).getId().toUnqualifiedVersionless().getValue();
|
||||||
|
|
||||||
|
ImmunizationRecommendation ir2 = new ImmunizationRecommendation();
|
||||||
|
ir2.addRecommendation().setDoseNumber(2);
|
||||||
|
String id2 = myImmunizationRecommendationDao.create(ir2).getId().toUnqualifiedVersionless().getValue();
|
||||||
|
|
||||||
|
{
|
||||||
|
IBundleProvider found = myImmunizationRecommendationDao.search(ImmunizationRecommendation.SP_DOSE_NUMBER, new NumberParam("1"));
|
||||||
|
assertThat(toUnqualifiedVersionlessIdValues(found), containsInAnyOrder(id1));
|
||||||
|
assertEquals(1, found.size());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
IBundleProvider found = myImmunizationRecommendationDao.search(ImmunizationRecommendation.SP_DOSE_SEQUENCE, new NumberParam("1"));
|
||||||
|
assertThat(toUnqualifiedVersionlessIdValues(found), empty());
|
||||||
|
assertEquals(0, found.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When a valueset expansion returns no codes
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testSearchOnCodesWithNone() {
|
||||||
|
ValueSet vs = new ValueSet();
|
||||||
|
vs.setUrl("urn:testSearchOnCodesWithNone");
|
||||||
|
myValueSetDao.create(vs);
|
||||||
|
|
||||||
|
Patient p1 = new Patient();
|
||||||
|
p1.setGender(AdministrativeGender.MALE);
|
||||||
|
String id1 = myPatientDao.create(p1).getId().toUnqualifiedVersionless().getValue();
|
||||||
|
|
||||||
|
Patient p2 = new Patient();
|
||||||
|
p2.setGender(AdministrativeGender.FEMALE);
|
||||||
|
String id2 = myPatientDao.create(p2).getId().toUnqualifiedVersionless().getValue();
|
||||||
|
|
||||||
|
{
|
||||||
|
IBundleProvider found = myPatientDao.search(Patient.SP_GENDER, new TokenParam().setModifier(TokenParamModifier.IN).setValue("urn:testSearchOnCodesWithNone"));
|
||||||
|
assertThat(toUnqualifiedVersionlessIdValues(found), empty());
|
||||||
|
assertEquals(0, found.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSearchPagesExpiry() throws Exception {
|
public void testSearchPagesExpiry() throws Exception {
|
||||||
IIdType pid1;
|
IIdType pid1;
|
||||||
|
@ -1310,6 +1385,29 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSearchQuantityWrongParam() throws Exception {
|
||||||
|
Condition c1 = new Condition();
|
||||||
|
c1.setAbatement(new Range().setLow((SimpleQuantity) new SimpleQuantity().setValue(1L)).setHigh((SimpleQuantity) new SimpleQuantity().setValue(1L)));
|
||||||
|
String id1 = myConditionDao.create(c1).getId().toUnqualifiedVersionless().getValue();
|
||||||
|
|
||||||
|
Condition c2 = new Condition();
|
||||||
|
c2.setOnset(new Range().setLow((SimpleQuantity) new SimpleQuantity().setValue(1L)).setHigh((SimpleQuantity) new SimpleQuantity().setValue(1L)));
|
||||||
|
String id2 = myConditionDao.create(c2).getId().toUnqualifiedVersionless().getValue();
|
||||||
|
|
||||||
|
{
|
||||||
|
IBundleProvider found = myConditionDao.search(Condition.SP_ABATEMENT_AGE, new QuantityParam("1"));
|
||||||
|
assertThat(toUnqualifiedVersionlessIdValues(found), containsInAnyOrder(id1));
|
||||||
|
assertEquals(1, found.size());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
IBundleProvider found = myConditionDao.search(Condition.SP_ONSET_AGE, new QuantityParam("1"));
|
||||||
|
assertThat(toUnqualifiedVersionlessIdValues(found), containsInAnyOrder(id2));
|
||||||
|
assertEquals(1, found.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSearchResourceLinkWithChain() {
|
public void testSearchResourceLinkWithChain() {
|
||||||
Patient patient = new Patient();
|
Patient patient = new Patient();
|
||||||
|
@ -1610,6 +1708,29 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSearchStringWrongParam() throws Exception {
|
||||||
|
Patient p1 = new Patient();
|
||||||
|
p1.getNameFirstRep().setFamily("AAA");
|
||||||
|
String id1 = myPatientDao.create(p1).getId().toUnqualifiedVersionless().getValue();
|
||||||
|
|
||||||
|
Patient p2 = new Patient();
|
||||||
|
p2.getNameFirstRep().addGiven("AAA");
|
||||||
|
String id2 = myPatientDao.create(p2).getId().toUnqualifiedVersionless().getValue();
|
||||||
|
|
||||||
|
{
|
||||||
|
IBundleProvider found = myPatientDao.search(Patient.SP_FAMILY, new StringParam("AAA"));
|
||||||
|
assertThat(toUnqualifiedVersionlessIdValues(found), containsInAnyOrder(id1));
|
||||||
|
assertEquals(1, found.size());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
IBundleProvider found = myPatientDao.search(Patient.SP_GIVEN, new StringParam("AAA"));
|
||||||
|
assertThat(toUnqualifiedVersionlessIdValues(found), containsInAnyOrder(id2));
|
||||||
|
assertEquals(1, found.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSearchTokenParam() {
|
public void testSearchTokenParam() {
|
||||||
Patient patient = new Patient();
|
Patient patient = new Patient();
|
||||||
|
@ -1717,6 +1838,29 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSearchTokenWrongParam() throws Exception {
|
||||||
|
Patient p1 = new Patient();
|
||||||
|
p1.setGender(AdministrativeGender.MALE);
|
||||||
|
String id1 = myPatientDao.create(p1).getId().toUnqualifiedVersionless().getValue();
|
||||||
|
|
||||||
|
Patient p2 = new Patient();
|
||||||
|
p2.addIdentifier().setValue(AdministrativeGender.MALE.toCode());
|
||||||
|
String id2 = myPatientDao.create(p2).getId().toUnqualifiedVersionless().getValue();
|
||||||
|
|
||||||
|
{
|
||||||
|
IBundleProvider found = myPatientDao.search(Patient.SP_GENDER, new TokenParam(null, "male"));
|
||||||
|
assertThat(toUnqualifiedVersionlessIdValues(found), containsInAnyOrder(id1));
|
||||||
|
assertEquals(1, found.size());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
IBundleProvider found = myPatientDao.search(Patient.SP_IDENTIFIER, new TokenParam(null, "male"));
|
||||||
|
assertThat(toUnqualifiedVersionlessIdValues(found), containsInAnyOrder(id2));
|
||||||
|
assertEquals(1, found.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Ignore
|
@Ignore
|
||||||
public void testSearchUnknownContentParam() {
|
public void testSearchUnknownContentParam() {
|
||||||
|
@ -1743,6 +1887,29 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSearchUriWrongParam() throws Exception {
|
||||||
|
ValueSet v1 = new ValueSet();
|
||||||
|
v1.getUrlElement().setValue("http://foo");
|
||||||
|
String id1 = myValueSetDao.create(v1).getId().toUnqualifiedVersionless().getValue();
|
||||||
|
|
||||||
|
ValueSet v2 = new ValueSet();
|
||||||
|
v2.getExpansion().getIdentifierElement().setValue("http://foo");
|
||||||
|
String id2 = myValueSetDao.create(v2).getId().toUnqualifiedVersionless().getValue();
|
||||||
|
|
||||||
|
{
|
||||||
|
IBundleProvider found = myValueSetDao.search(ValueSet.SP_URL, new UriParam("http://foo"));
|
||||||
|
assertThat(toUnqualifiedVersionlessIdValues(found), containsInAnyOrder(id1));
|
||||||
|
assertEquals(1, found.size());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
IBundleProvider found = myValueSetDao.search(ValueSet.SP_EXPANSION, new UriParam("http://foo"));
|
||||||
|
assertThat(toUnqualifiedVersionlessIdValues(found), containsInAnyOrder(id2));
|
||||||
|
assertEquals(1, found.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSearchValueQuantity() {
|
public void testSearchValueQuantity() {
|
||||||
String methodName = "testSearchValueQuantity";
|
String methodName = "testSearchValueQuantity";
|
||||||
|
@ -1796,6 +1963,50 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSearchWithDate() {
|
||||||
|
IIdType orgId = myOrganizationDao.create(new Organization(), mySrd).getId();
|
||||||
|
IIdType id2;
|
||||||
|
IIdType id1;
|
||||||
|
{
|
||||||
|
Patient patient = new Patient();
|
||||||
|
patient.addIdentifier().setSystem("urn:system").setValue("001");
|
||||||
|
id1 = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Patient patient = new Patient();
|
||||||
|
patient.addIdentifier().setSystem("urn:system").setValue("002");
|
||||||
|
patient.addName().setFamily("Tester_testSearchStringParam").addGiven("John");
|
||||||
|
patient.setBirthDateElement(new DateType("2011-01-01"));
|
||||||
|
patient.getManagingOrganization().setReferenceElement(orgId);
|
||||||
|
id2 = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
}
|
||||||
|
{
|
||||||
|
HashMap<String, IQueryParameterType> params = new HashMap<String, IQueryParameterType>();
|
||||||
|
params.put(Patient.SP_BIRTHDATE, new DateParam("2011-01-01"));
|
||||||
|
List<IIdType> patients = toUnqualifiedVersionlessIds(myPatientDao.search(params));
|
||||||
|
assertThat(patients, contains(id2));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
HashMap<String, IQueryParameterType> params = new HashMap<String, IQueryParameterType>();
|
||||||
|
params.put(Patient.SP_BIRTHDATE, new DateParam("2011-01-03"));
|
||||||
|
List<IIdType> patients = toUnqualifiedVersionlessIds(myPatientDao.search(params));
|
||||||
|
assertThat(patients, empty());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
HashMap<String, IQueryParameterType> params = new HashMap<String, IQueryParameterType>();
|
||||||
|
params.put(Patient.SP_BIRTHDATE, new DateParam("2011-01-03").setPrefix(ParamPrefixEnum.LESSTHAN));
|
||||||
|
List<IIdType> patients = toUnqualifiedVersionlessIds(myPatientDao.search(params));
|
||||||
|
assertThat(patients, contains(id2));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
HashMap<String, IQueryParameterType> params = new HashMap<String, IQueryParameterType>();
|
||||||
|
params.put(Patient.SP_BIRTHDATE, new DateParam("2010-01-01").setPrefix(ParamPrefixEnum.LESSTHAN));
|
||||||
|
List<IIdType> patients = toUnqualifiedVersionlessIds(myPatientDao.search(params));
|
||||||
|
assertThat(patients, empty());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSearchWithEmptySort() {
|
public void testSearchWithEmptySort() {
|
||||||
SearchParameterMap criteriaUrl = new SearchParameterMap();
|
SearchParameterMap criteriaUrl = new SearchParameterMap();
|
||||||
|
@ -2169,50 +2380,6 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSearchWithDate() {
|
|
||||||
IIdType orgId = myOrganizationDao.create(new Organization(), mySrd).getId();
|
|
||||||
IIdType id2;
|
|
||||||
IIdType id1;
|
|
||||||
{
|
|
||||||
Patient patient = new Patient();
|
|
||||||
patient.addIdentifier().setSystem("urn:system").setValue("001");
|
|
||||||
id1 = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless();
|
|
||||||
}
|
|
||||||
{
|
|
||||||
Patient patient = new Patient();
|
|
||||||
patient.addIdentifier().setSystem("urn:system").setValue("002");
|
|
||||||
patient.addName().setFamily("Tester_testSearchStringParam").addGiven("John");
|
|
||||||
patient.setBirthDateElement(new DateType("2011-01-01"));
|
|
||||||
patient.getManagingOrganization().setReferenceElement(orgId);
|
|
||||||
id2 = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless();
|
|
||||||
}
|
|
||||||
{
|
|
||||||
HashMap<String, IQueryParameterType> params = new HashMap<String, IQueryParameterType>();
|
|
||||||
params.put(Patient.SP_BIRTHDATE, new DateParam("2011-01-01"));
|
|
||||||
List<IIdType> patients = toUnqualifiedVersionlessIds(myPatientDao.search(params));
|
|
||||||
assertThat(patients, contains(id2));
|
|
||||||
}
|
|
||||||
{
|
|
||||||
HashMap<String, IQueryParameterType> params = new HashMap<String, IQueryParameterType>();
|
|
||||||
params.put(Patient.SP_BIRTHDATE, new DateParam("2011-01-03"));
|
|
||||||
List<IIdType> patients = toUnqualifiedVersionlessIds(myPatientDao.search(params));
|
|
||||||
assertThat(patients, empty());
|
|
||||||
}
|
|
||||||
{
|
|
||||||
HashMap<String, IQueryParameterType> params = new HashMap<String, IQueryParameterType>();
|
|
||||||
params.put(Patient.SP_BIRTHDATE, new DateParam("2011-01-03").setPrefix(ParamPrefixEnum.LESSTHAN));
|
|
||||||
List<IIdType> patients = toUnqualifiedVersionlessIds(myPatientDao.search(params));
|
|
||||||
assertThat(patients, contains(id2));
|
|
||||||
}
|
|
||||||
{
|
|
||||||
HashMap<String, IQueryParameterType> params = new HashMap<String, IQueryParameterType>();
|
|
||||||
params.put(Patient.SP_BIRTHDATE, new DateParam("2010-01-01").setPrefix(ParamPrefixEnum.LESSTHAN));
|
|
||||||
List<IIdType> patients = toUnqualifiedVersionlessIds(myPatientDao.search(params));
|
|
||||||
assertThat(patients, empty());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSearchWithMissingQuantity() {
|
public void testSearchWithMissingQuantity() {
|
||||||
IIdType notMissing;
|
IIdType notMissing;
|
||||||
|
|
|
@ -34,11 +34,11 @@
|
||||||
</logger>
|
</logger>
|
||||||
|
|
||||||
<!-- Set to 'trace' to enable SQL logging -->
|
<!-- Set to 'trace' to enable SQL logging -->
|
||||||
<logger name="org.hibernate.SQL" additivity="false" level="info">
|
<logger name="org.hibernate.SQL" additivity="false" level="trace">
|
||||||
<appender-ref ref="STDOUT" />
|
<appender-ref ref="STDOUT" />
|
||||||
</logger>
|
</logger>
|
||||||
<!-- Set to 'trace' to enable SQL Value logging -->
|
<!-- Set to 'trace' to enable SQL Value logging -->
|
||||||
<logger name="org.hibernate.type" additivity="false" level="info">
|
<logger name="org.hibernate.type" additivity="false" level="trace">
|
||||||
<appender-ref ref="STDOUT" />
|
<appender-ref ref="STDOUT" />
|
||||||
</logger>
|
</logger>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue