Merge branch 'master' of github.com:jamesagnew/hapi-fhir
This commit is contained in:
commit
8bdca012d6
|
@ -4,4 +4,4 @@ cache:
|
||||||
- C:\maven\
|
- C:\maven\
|
||||||
- C:\Users\appveyor\.m2\repository
|
- C:\Users\appveyor\.m2\repository
|
||||||
build_script:
|
build_script:
|
||||||
- cmd: mvn -P MINPARALLEL,ALLMODULES,ERRORPRONE_JDK8 install
|
- cmd: mvn -P MINPARALLEL,ALLMODULES clean install
|
||||||
|
|
|
@ -9,9 +9,9 @@ package ca.uhn.fhir.parser;
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -38,6 +38,7 @@ import java.util.*;
|
||||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||||
|
|
||||||
|
@SuppressWarnings("WeakerAccess")
|
||||||
public abstract class BaseParser implements IParser {
|
public abstract class BaseParser implements IParser {
|
||||||
|
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseParser.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseParser.class);
|
||||||
|
@ -156,7 +157,6 @@ public abstract class BaseParser implements IParser {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void containResourcesForEncoding(ContainedResources theContained, IBaseResource theResource, IBaseResource theTarget) {
|
private void containResourcesForEncoding(ContainedResources theContained, IBaseResource theResource, IBaseResource theTarget) {
|
||||||
Set<String> allIds = new HashSet<String>();
|
|
||||||
Map<String, IBaseResource> existingIdToContainedResource = null;
|
Map<String, IBaseResource> existingIdToContainedResource = null;
|
||||||
|
|
||||||
if (theTarget instanceof IResource) {
|
if (theTarget instanceof IResource) {
|
||||||
|
@ -167,9 +167,8 @@ public abstract class BaseParser implements IParser {
|
||||||
if (!nextId.startsWith("#")) {
|
if (!nextId.startsWith("#")) {
|
||||||
nextId = '#' + nextId;
|
nextId = '#' + nextId;
|
||||||
}
|
}
|
||||||
allIds.add(nextId);
|
|
||||||
if (existingIdToContainedResource == null) {
|
if (existingIdToContainedResource == null) {
|
||||||
existingIdToContainedResource = new HashMap<String, IBaseResource>();
|
existingIdToContainedResource = new HashMap<>();
|
||||||
}
|
}
|
||||||
existingIdToContainedResource.put(nextId, next);
|
existingIdToContainedResource.put(nextId, next);
|
||||||
}
|
}
|
||||||
|
@ -182,9 +181,8 @@ public abstract class BaseParser implements IParser {
|
||||||
if (!nextId.startsWith("#")) {
|
if (!nextId.startsWith("#")) {
|
||||||
nextId = '#' + nextId;
|
nextId = '#' + nextId;
|
||||||
}
|
}
|
||||||
allIds.add(nextId);
|
|
||||||
if (existingIdToContainedResource == null) {
|
if (existingIdToContainedResource == null) {
|
||||||
existingIdToContainedResource = new HashMap<String, IBaseResource>();
|
existingIdToContainedResource = new HashMap<>();
|
||||||
}
|
}
|
||||||
existingIdToContainedResource.put(nextId, next);
|
existingIdToContainedResource.put(nextId, next);
|
||||||
}
|
}
|
||||||
|
@ -480,7 +478,7 @@ public abstract class BaseParser implements IParser {
|
||||||
@Override
|
@Override
|
||||||
public void setPreferTypes(List<Class<? extends IBaseResource>> thePreferTypes) {
|
public void setPreferTypes(List<Class<? extends IBaseResource>> thePreferTypes) {
|
||||||
if (thePreferTypes != null) {
|
if (thePreferTypes != null) {
|
||||||
ArrayList<Class<? extends IBaseResource>> types = new ArrayList<Class<? extends IBaseResource>>();
|
ArrayList<Class<? extends IBaseResource>> types = new ArrayList<>();
|
||||||
for (Class<? extends IBaseResource> next : thePreferTypes) {
|
for (Class<? extends IBaseResource> next : thePreferTypes) {
|
||||||
if (Modifier.isAbstract(next.getModifiers()) == false) {
|
if (Modifier.isAbstract(next.getModifiers()) == false) {
|
||||||
types.add(next);
|
types.add(next);
|
||||||
|
@ -516,8 +514,7 @@ public abstract class BaseParser implements IParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<T> newList = new ArrayList<T>();
|
List<T> newList = new ArrayList<>(theProfiles);
|
||||||
newList.addAll(theProfiles);
|
|
||||||
|
|
||||||
BaseRuntimeElementDefinition<?> idElement = myContext.getElementDefinition("id");
|
BaseRuntimeElementDefinition<?> idElement = myContext.getElementDefinition("id");
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
@ -1183,8 +1180,10 @@ public abstract class BaseParser implements IParser {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addContained(IIdType theId, IBaseResource theResource) {
|
public void addContained(IIdType theId, IBaseResource theResource) {
|
||||||
myResourceToId.put(theResource, theId);
|
if (!hasId(theId)) {
|
||||||
myResources.add(theResource);
|
myResourceToId.put(theResource, theId);
|
||||||
|
myResources.add(theResource);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<IBaseResource> getContainedResources() {
|
public List<IBaseResource> getContainedResources() {
|
||||||
|
@ -1195,6 +1194,15 @@ public abstract class BaseParser implements IParser {
|
||||||
return myResourceToId.get(theNext);
|
return myResourceToId.get(theNext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasId(IIdType theId) {
|
||||||
|
for (IIdType next : myResourceToId.values()) {
|
||||||
|
if (Objects.equals(next.getValue(), theId.getValue())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isEmpty() {
|
public boolean isEmpty() {
|
||||||
return myResourceToId.isEmpty();
|
return myResourceToId.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,31 +65,31 @@ public interface IHttpResponse {
|
||||||
/**
|
/**
|
||||||
* Close the response
|
* Close the response
|
||||||
*/
|
*/
|
||||||
public void close();
|
void close();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returna reader for the response entity
|
* Returna reader for the response entity
|
||||||
*/
|
*/
|
||||||
public Reader createReader() throws IOException;
|
Reader createReader() throws IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get map of the response headers and corresponding string values.
|
* Get map of the response headers and corresponding string values.
|
||||||
*
|
*
|
||||||
* @return response headers as a map header keys and they values.
|
* @return response headers as a map header keys and they values.
|
||||||
*/
|
*/
|
||||||
public Map<String, List<String>> getAllHeaders();
|
Map<String, List<String>> getAllHeaders();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return all headers in the response with the given type
|
* Return all headers in the response with the given type
|
||||||
*/
|
*/
|
||||||
public List<String> getHeaders(String theName);
|
List<String> getHeaders(String theName);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extracts {@code Content-Type} value from the response exactly as
|
* Extracts {@code Content-Type} value from the response exactly as
|
||||||
* specified by the {@code Content-Type} header. Returns {@code null}
|
* specified by the {@code Content-Type} header. Returns {@code null}
|
||||||
* if not specified.
|
* if not specified.
|
||||||
*/
|
*/
|
||||||
public String getMimeType();
|
String getMimeType();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the native response, depending on the client library used
|
* @return the native response, depending on the client library used
|
||||||
|
@ -101,18 +101,18 @@ public interface IHttpResponse {
|
||||||
*
|
*
|
||||||
* @return the response status code.
|
* @return the response status code.
|
||||||
*/
|
*/
|
||||||
public int getStatus();
|
int getStatus();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the response status information reason phrase associated with the response.
|
* Get the response status information reason phrase associated with the response.
|
||||||
*
|
*
|
||||||
* @return the reason phrase.
|
* @return the reason phrase.
|
||||||
*/
|
*/
|
||||||
public String getStatusInfo();
|
String getStatusInfo();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read the message entity input stream as an InputStream.
|
* Read the message entity input stream as an InputStream.
|
||||||
*/
|
*/
|
||||||
public InputStream readEntity() throws IOException;
|
InputStream readEntity() throws IOException;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,5 +107,4 @@ public abstract class BaseParamWithPrefix<T extends BaseParam> extends BaseParam
|
||||||
myPrefix = thePrefix;
|
myPrefix = thePrefix;
|
||||||
return (T) this;
|
return (T) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,21 +20,26 @@ package ca.uhn.fhir.rest.param;
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
import ca.uhn.fhir.model.api.IQueryParameterOr;
|
||||||
import java.util.*;
|
import ca.uhn.fhir.model.api.TemporalPrecisionEnum;
|
||||||
|
import ca.uhn.fhir.model.primitive.BaseDateTimeDt;
|
||||||
|
import ca.uhn.fhir.model.primitive.DateDt;
|
||||||
|
import ca.uhn.fhir.model.primitive.DateTimeDt;
|
||||||
|
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||||
|
import ca.uhn.fhir.rest.api.QualifiedParamList;
|
||||||
|
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||||
|
import ca.uhn.fhir.util.ValidateUtil;
|
||||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||||
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import java.util.Collections;
|
||||||
import ca.uhn.fhir.model.api.IQueryParameterOr;
|
import java.util.Date;
|
||||||
import ca.uhn.fhir.model.api.TemporalPrecisionEnum;
|
import java.util.List;
|
||||||
import ca.uhn.fhir.model.primitive.*;
|
import java.util.Objects;
|
||||||
import ca.uhn.fhir.rest.api.QualifiedParamList;
|
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||||
import ca.uhn.fhir.util.ValidateUtil;
|
|
||||||
|
|
||||||
public class DateParam extends BaseParamWithPrefix<DateParam> implements /*IQueryParameterType , */IQueryParameterOr<DateParam> {
|
public class DateParam extends BaseParamWithPrefix<DateParam> implements /*IQueryParameterType , */IQueryParameterOr<DateParam> {
|
||||||
|
|
||||||
|
@ -222,6 +227,23 @@ public class DateParam extends BaseParamWithPrefix<DateParam> implements /*IQuer
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (obj == this) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!(obj instanceof DateParam)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
DateParam other = (DateParam) obj;
|
||||||
|
return Objects.equals(getValue(), other.getValue()) &&
|
||||||
|
Objects.equals(getPrefix(), other.getPrefix());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(getValue(), getPrefix());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
@ -241,8 +263,5 @@ public class DateParam extends BaseParamWithPrefix<DateParam> implements /*IQuer
|
||||||
protected boolean isPrecisionAllowed(TemporalPrecisionEnum thePrecision) {
|
protected boolean isPrecisionAllowed(TemporalPrecisionEnum thePrecision) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -413,6 +413,24 @@ public class DateRangeParam implements IQueryParameterAnd<DateParam> {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (obj == this) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!(obj instanceof DateRangeParam)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
DateRangeParam other = (DateRangeParam) obj;
|
||||||
|
return Objects.equals(myLowerBound, other.myLowerBound) &&
|
||||||
|
Objects.equals(myUpperBound, other.myUpperBound);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(myLowerBound, myUpperBound);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuilder b = new StringBuilder();
|
StringBuilder b = new StringBuilder();
|
||||||
|
@ -484,7 +502,5 @@ public class DateRangeParam implements IQueryParameterAnd<DateParam> {
|
||||||
throw new DataFormatException("Upper bound comparator must be < or <=, can not be " + myUpperBound.getPrefix().getValue());
|
throw new DataFormatException("Upper bound comparator must be < or <=, can not be " + myUpperBound.getPrefix().getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -463,7 +463,7 @@ public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao<Bundle, MetaDt> {
|
||||||
}
|
}
|
||||||
if (idSubstitutions.containsKey(nextId)) {
|
if (idSubstitutions.containsKey(nextId)) {
|
||||||
IdDt newId = idSubstitutions.get(nextId);
|
IdDt newId = idSubstitutions.get(nextId);
|
||||||
ourLog.info(" * Replacing resource ref {} with {}", nextId, newId);
|
ourLog.debug(" * Replacing resource ref {} with {}", nextId, newId);
|
||||||
nextRef.setReference(newId);
|
nextRef.setReference(newId);
|
||||||
} else {
|
} else {
|
||||||
ourLog.debug(" * Reference [{}] does not exist in bundle", nextId);
|
ourLog.debug(" * Reference [{}] does not exist in bundle", nextId);
|
||||||
|
@ -479,7 +479,7 @@ public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao<Bundle, MetaDt> {
|
||||||
IdDt nextUriString = new IdDt(nextRef.getValueAsString());
|
IdDt nextUriString = new IdDt(nextRef.getValueAsString());
|
||||||
if (idSubstitutions.containsKey(nextUriString)) {
|
if (idSubstitutions.containsKey(nextUriString)) {
|
||||||
IdDt newId = idSubstitutions.get(nextUriString);
|
IdDt newId = idSubstitutions.get(nextUriString);
|
||||||
ourLog.info(" * Replacing resource ref {} with {}", nextUriString, newId);
|
ourLog.debug(" * Replacing resource ref {} with {}", nextUriString, newId);
|
||||||
nextRef.setValue(newId.getValue());
|
nextRef.setValue(newId.getValue());
|
||||||
} else {
|
} else {
|
||||||
ourLog.debug(" * Reference [{}] does not exist in bundle", nextUriString);
|
ourLog.debug(" * Reference [{}] does not exist in bundle", nextUriString);
|
||||||
|
@ -522,7 +522,7 @@ public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao<Bundle, MetaDt> {
|
||||||
if (replacement.equals(next)) {
|
if (replacement.equals(next)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ourLog.info("Placeholder resource ID \"{}\" was replaced with permanent ID \"{}\"", next, replacement);
|
ourLog.debug("Placeholder resource ID \"{}\" was replaced with permanent ID \"{}\"", next, replacement);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -770,12 +770,11 @@ public class SearchBuilder implements ISearchBuilder {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Predicate> codePredicates = new ArrayList<Predicate>();
|
List<Predicate> codePredicates = new ArrayList<>();
|
||||||
for (IQueryParameterType nextOr : theList) {
|
for (IQueryParameterType nextOr : theList) {
|
||||||
IQueryParameterType params = nextOr;
|
|
||||||
|
|
||||||
if (params instanceof UriParam) {
|
if (nextOr instanceof UriParam) {
|
||||||
UriParam param = (UriParam) params;
|
UriParam param = (UriParam) nextOr;
|
||||||
|
|
||||||
String value = param.getValue();
|
String value = param.getValue();
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
|
@ -820,7 +819,7 @@ public class SearchBuilder implements ISearchBuilder {
|
||||||
}
|
}
|
||||||
codePredicates.add(predicate);
|
codePredicates.add(predicate);
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("Invalid URI type: " + params.getClass());
|
throw new IllegalArgumentException("Invalid URI type: " + nextOr.getClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1340,7 +1339,7 @@ public class SearchBuilder implements ISearchBuilder {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
myPredicates = new ArrayList<Predicate>();
|
myPredicates = new ArrayList<>();
|
||||||
|
|
||||||
if (myParams.getEverythingMode() != null) {
|
if (myParams.getEverythingMode() != null) {
|
||||||
Join<ResourceTable, ResourceLink> join = myResourceTableRoot.join("myResourceLinks", JoinType.LEFT);
|
Join<ResourceTable, ResourceLink> join = myResourceTableRoot.join("myResourceLinks", JoinType.LEFT);
|
||||||
|
@ -1349,7 +1348,7 @@ public class SearchBuilder implements ISearchBuilder {
|
||||||
StringParam idParm = (StringParam) myParams.get(BaseResource.SP_RES_ID).get(0).get(0);
|
StringParam idParm = (StringParam) myParams.get(BaseResource.SP_RES_ID).get(0).get(0);
|
||||||
Long pid = BaseHapiFhirDao.translateForcedIdToPid(myResourceName, idParm.getValue(), myForcedIdDao);
|
Long pid = BaseHapiFhirDao.translateForcedIdToPid(myResourceName, idParm.getValue(), myForcedIdDao);
|
||||||
if (myAlsoIncludePids == null) {
|
if (myAlsoIncludePids == null) {
|
||||||
myAlsoIncludePids = new ArrayList<Long>(1);
|
myAlsoIncludePids = new ArrayList<>(1);
|
||||||
}
|
}
|
||||||
myAlsoIncludePids.add(pid);
|
myAlsoIncludePids.add(pid);
|
||||||
myPredicates.add(myBuilder.equal(join.get("myTargetResourcePid").as(Long.class), pid));
|
myPredicates.add(myBuilder.equal(join.get("myTargetResourcePid").as(Long.class), pid));
|
||||||
|
|
|
@ -505,7 +505,7 @@ public class FhirSystemDaoDstu3 extends BaseHapiFhirSystemDao<Bundle, Meta> {
|
||||||
}
|
}
|
||||||
if (theIdSubstitutions.containsKey(nextId)) {
|
if (theIdSubstitutions.containsKey(nextId)) {
|
||||||
IdType newId = theIdSubstitutions.get(nextId);
|
IdType newId = theIdSubstitutions.get(nextId);
|
||||||
ourLog.info(" * Replacing resource ref {} with {}", nextId, newId);
|
ourLog.debug(" * Replacing resource ref {} with {}", nextId, newId);
|
||||||
nextRef.setReference(newId.getValue());
|
nextRef.setReference(newId.getValue());
|
||||||
} else if (nextId.getValue().startsWith("urn:")) {
|
} else if (nextId.getValue().startsWith("urn:")) {
|
||||||
throw new InvalidRequestException("Unable to satisfy placeholder ID: " + nextId.getValue());
|
throw new InvalidRequestException("Unable to satisfy placeholder ID: " + nextId.getValue());
|
||||||
|
@ -523,7 +523,7 @@ public class FhirSystemDaoDstu3 extends BaseHapiFhirSystemDao<Bundle, Meta> {
|
||||||
IdType nextUriString = new IdType(nextRef.getValueAsString());
|
IdType nextUriString = new IdType(nextRef.getValueAsString());
|
||||||
if (theIdSubstitutions.containsKey(nextUriString)) {
|
if (theIdSubstitutions.containsKey(nextUriString)) {
|
||||||
IdType newId = theIdSubstitutions.get(nextUriString);
|
IdType newId = theIdSubstitutions.get(nextUriString);
|
||||||
ourLog.info(" * Replacing resource ref {} with {}", nextUriString, newId);
|
ourLog.debug(" * Replacing resource ref {} with {}", nextUriString, newId);
|
||||||
nextRef.setValue(newId.getValue());
|
nextRef.setValue(newId.getValue());
|
||||||
} else {
|
} else {
|
||||||
ourLog.debug(" * Reference [{}] does not exist in bundle", nextUriString);
|
ourLog.debug(" * Reference [{}] does not exist in bundle", nextUriString);
|
||||||
|
@ -544,7 +544,7 @@ public class FhirSystemDaoDstu3 extends BaseHapiFhirSystemDao<Bundle, Meta> {
|
||||||
|
|
||||||
StopWatch sw = new StopWatch();
|
StopWatch sw = new StopWatch();
|
||||||
myEntityManager.flush();
|
myEntityManager.flush();
|
||||||
ourLog.info("Session flush took {}ms for {} inserts and {} updates", sw.getMillis(), insertionCount, updateCount);
|
ourLog.debug("Session flush took {}ms for {} inserts and {} updates", sw.getMillis(), insertionCount, updateCount);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Double check we didn't allow any duplicates we shouldn't have
|
* Double check we didn't allow any duplicates we shouldn't have
|
||||||
|
@ -570,7 +570,7 @@ public class FhirSystemDaoDstu3 extends BaseHapiFhirSystemDao<Bundle, Meta> {
|
||||||
if (replacement.equals(next)) {
|
if (replacement.equals(next)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ourLog.info("Placeholder resource ID \"{}\" was replaced with permanent ID \"{}\"", next, replacement);
|
ourLog.debug("Placeholder resource ID \"{}\" was replaced with permanent ID \"{}\"", next, replacement);
|
||||||
}
|
}
|
||||||
return entriesToProcess;
|
return entriesToProcess;
|
||||||
}
|
}
|
||||||
|
|
|
@ -514,7 +514,7 @@ public class FhirSystemDaoR4 extends BaseHapiFhirSystemDao<Bundle, Meta> {
|
||||||
}
|
}
|
||||||
if (theIdSubstitutions.containsKey(nextId)) {
|
if (theIdSubstitutions.containsKey(nextId)) {
|
||||||
IdType newId = theIdSubstitutions.get(nextId);
|
IdType newId = theIdSubstitutions.get(nextId);
|
||||||
ourLog.info(" * Replacing resource ref {} with {}", nextId, newId);
|
ourLog.debug(" * Replacing resource ref {} with {}", nextId, newId);
|
||||||
nextRef.setReference(newId.getValue());
|
nextRef.setReference(newId.getValue());
|
||||||
} else if (nextId.getValue().startsWith("urn:")) {
|
} else if (nextId.getValue().startsWith("urn:")) {
|
||||||
throw new InvalidRequestException("Unable to satisfy placeholder ID: " + nextId.getValue());
|
throw new InvalidRequestException("Unable to satisfy placeholder ID: " + nextId.getValue());
|
||||||
|
@ -532,7 +532,7 @@ public class FhirSystemDaoR4 extends BaseHapiFhirSystemDao<Bundle, Meta> {
|
||||||
IdType nextUriString = new IdType(nextRef.getValueAsString());
|
IdType nextUriString = new IdType(nextRef.getValueAsString());
|
||||||
if (theIdSubstitutions.containsKey(nextUriString)) {
|
if (theIdSubstitutions.containsKey(nextUriString)) {
|
||||||
IdType newId = theIdSubstitutions.get(nextUriString);
|
IdType newId = theIdSubstitutions.get(nextUriString);
|
||||||
ourLog.info(" * Replacing resource ref {} with {}", nextUriString, newId);
|
ourLog.debug(" * Replacing resource ref {} with {}", nextUriString, newId);
|
||||||
nextRef.setValue(newId.getValue());
|
nextRef.setValue(newId.getValue());
|
||||||
} else {
|
} else {
|
||||||
ourLog.debug(" * Reference [{}] does not exist in bundle", nextUriString);
|
ourLog.debug(" * Reference [{}] does not exist in bundle", nextUriString);
|
||||||
|
@ -548,6 +548,7 @@ public class FhirSystemDaoR4 extends BaseHapiFhirSystemDao<Bundle, Meta> {
|
||||||
}
|
}
|
||||||
|
|
||||||
myEntityManager.flush();
|
myEntityManager.flush();
|
||||||
|
ourLog.debug("Session flush took {}ms for {} inserts and {} updates", sw.getMillis(), insertionCount, updateCount);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Double check we didn't allow any duplicates we shouldn't have
|
* Double check we didn't allow any duplicates we shouldn't have
|
||||||
|
@ -573,7 +574,7 @@ public class FhirSystemDaoR4 extends BaseHapiFhirSystemDao<Bundle, Meta> {
|
||||||
if (replacement.equals(next)) {
|
if (replacement.equals(next)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ourLog.info("Placeholder resource ID \"{}\" was replaced with permanent ID \"{}\"", next, replacement);
|
ourLog.debug("Placeholder resource ID \"{}\" was replaced with permanent ID \"{}\"", next, replacement);
|
||||||
}
|
}
|
||||||
return entriesToProcess;
|
return entriesToProcess;
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,8 +44,13 @@ public abstract class BaseSubscriptionDeliverySubscriber extends BaseSubscriptio
|
||||||
ourLog.warn("Unexpected payload type: {}", theMessage.getPayload());
|
ourLog.warn("Unexpected payload type: {}", theMessage.getPayload());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String subscriptionId = "(unknown?)";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ResourceDeliveryMessage msg = (ResourceDeliveryMessage) theMessage.getPayload();
|
ResourceDeliveryMessage msg = (ResourceDeliveryMessage) theMessage.getPayload();
|
||||||
|
subscriptionId = msg.getPayload(getContext()).getIdElement().getValue();
|
||||||
|
|
||||||
if (!subscriptionTypeApplies(getContext(), msg.getSubscription().getBackingSubscription(getContext()))) {
|
if (!subscriptionTypeApplies(getContext(), msg.getSubscription().getBackingSubscription(getContext()))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -77,8 +82,9 @@ public abstract class BaseSubscriptionDeliverySubscriber extends BaseSubscriptio
|
||||||
|
|
||||||
handleMessage(msg);
|
handleMessage(msg);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
ourLog.error("Failure handling subscription payload", e);
|
String msg = "Failure handling subscription payload for subscription: " + subscriptionId;
|
||||||
throw new MessagingException(theMessage, "Failure handling subscription payload", e);
|
ourLog.error(msg, e);
|
||||||
|
throw new MessagingException(theMessage, msg, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
package ca.uhn.fhir.jpa.util;
|
package ca.uhn.fhir.jpa.util;
|
||||||
|
|
||||||
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import org.apache.commons.lang3.time.DateUtils;
|
import org.apache.commons.lang3.time.DateUtils;
|
||||||
|
|
||||||
import java.text.DecimalFormat;
|
import java.text.DecimalFormat;
|
||||||
|
import java.text.NumberFormat;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
@ -15,9 +17,9 @@ import java.util.concurrent.TimeUnit;
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -28,7 +30,10 @@ import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
public class StopWatch {
|
public class StopWatch {
|
||||||
|
|
||||||
private long myStarted = System.currentTimeMillis();
|
private static final NumberFormat DAY_FORMAT = new DecimalFormat("0.0");
|
||||||
|
private static final NumberFormat TEN_DAY_FORMAT = new DecimalFormat("0");
|
||||||
|
private static Long ourNowForUnitTest;
|
||||||
|
private long myStarted = now();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
|
@ -46,17 +51,42 @@ public class StopWatch {
|
||||||
myStarted = theStart.getTime();
|
myStarted = theStart.getTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getMillis() {
|
public String formatThroughput(int theNumOperations, TimeUnit theUnit) {
|
||||||
long now = System.currentTimeMillis();
|
double throughput = getThroughput(theNumOperations, theUnit);
|
||||||
return now - myStarted;
|
return new DecimalFormat("0.0").format(throughput);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given an amount of something completed so far, and a total amount, calculates how long it will take for something to complete
|
||||||
|
*
|
||||||
|
* @param theCompleteToDate The amount so far
|
||||||
|
* @param theTotal The total (must be higher than theCompleteToDate
|
||||||
|
* @return A formatted amount of time
|
||||||
|
*/
|
||||||
|
public String getEstimatedTimeRemaining(double theCompleteToDate, double theTotal) {
|
||||||
|
double completeSoFar = theCompleteToDate / theTotal;
|
||||||
|
double remaining;
|
||||||
|
if (completeSoFar > 0.5) {
|
||||||
|
remaining = (1.0 - completeSoFar);
|
||||||
|
} else {
|
||||||
|
remaining = (1.0 / completeSoFar);
|
||||||
|
}
|
||||||
|
double millis = getMillis();
|
||||||
|
long millisRemaining = (long) (millis * remaining);
|
||||||
|
return formatMillis(millisRemaining);
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getMillis(Date theNow) {
|
public long getMillis(Date theNow) {
|
||||||
return theNow.getTime() - myStarted;
|
return theNow.getTime() - myStarted;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public long getMillis() {
|
||||||
|
long now = now();
|
||||||
|
return now - myStarted;
|
||||||
|
}
|
||||||
|
|
||||||
public long getMillisAndRestart() {
|
public long getMillisAndRestart() {
|
||||||
long now = System.currentTimeMillis();
|
long now = now();
|
||||||
long retVal = now - myStarted;
|
long retVal = now - myStarted;
|
||||||
myStarted = now;
|
myStarted = now;
|
||||||
return retVal;
|
return retVal;
|
||||||
|
@ -82,18 +112,13 @@ public class StopWatch {
|
||||||
long periodMillis = theUnit.toMillis(1);
|
long periodMillis = theUnit.toMillis(1);
|
||||||
|
|
||||||
double numerator = theNumOperations;
|
double numerator = theNumOperations;
|
||||||
double denominator = ((double)millisElapsed)/((double)periodMillis);
|
double denominator = ((double) millisElapsed) / ((double) periodMillis);
|
||||||
|
|
||||||
return numerator / denominator;
|
return numerator / denominator;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String formatThroughput(int theNumOperations, TimeUnit theUnit) {
|
|
||||||
double throughput = getThroughput(theNumOperations, theUnit);
|
|
||||||
return new DecimalFormat("0.0").format(throughput);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void restart() {
|
public void restart() {
|
||||||
myStarted = System.currentTimeMillis();
|
myStarted = now();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -124,21 +149,38 @@ public class StopWatch {
|
||||||
static public String formatMillis(long val) {
|
static public String formatMillis(long val) {
|
||||||
StringBuilder buf = new StringBuilder(20);
|
StringBuilder buf = new StringBuilder(20);
|
||||||
if (val >= DateUtils.MILLIS_PER_DAY) {
|
if (val >= DateUtils.MILLIS_PER_DAY) {
|
||||||
long days = val / DateUtils.MILLIS_PER_DAY;
|
double days = (double) val / DateUtils.MILLIS_PER_DAY;
|
||||||
append(buf, "", 1, days);
|
if (days >= 10) {
|
||||||
if (days > 1) {
|
buf.append(TEN_DAY_FORMAT.format(days));
|
||||||
buf.append(" days ");
|
buf.append(" days");
|
||||||
} else if (days == 1) {
|
} else if (days != 1.0f) {
|
||||||
buf.append(" day ");
|
buf.append(DAY_FORMAT.format(days));
|
||||||
|
buf.append(" days");
|
||||||
|
} else {
|
||||||
|
buf.append(DAY_FORMAT.format(days));
|
||||||
|
buf.append(" day");
|
||||||
}
|
}
|
||||||
append(buf, "", 2, ((val % DateUtils.MILLIS_PER_DAY) / DateUtils.MILLIS_PER_HOUR));
|
|
||||||
} else {
|
} else {
|
||||||
append(buf, "", 2, ((val % DateUtils.MILLIS_PER_DAY) / DateUtils.MILLIS_PER_HOUR));
|
append(buf, "", 2, ((val % DateUtils.MILLIS_PER_DAY) / DateUtils.MILLIS_PER_HOUR));
|
||||||
|
append(buf, ":", 2, ((val % DateUtils.MILLIS_PER_HOUR) / DateUtils.MILLIS_PER_MINUTE));
|
||||||
|
append(buf, ":", 2, ((val % DateUtils.MILLIS_PER_MINUTE) / DateUtils.MILLIS_PER_SECOND));
|
||||||
|
if (val <= DateUtils.MILLIS_PER_MINUTE) {
|
||||||
|
append(buf, ".", 3, (val % DateUtils.MILLIS_PER_SECOND));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
append(buf, ":", 2, ((val % DateUtils.MILLIS_PER_HOUR) / DateUtils.MILLIS_PER_MINUTE));
|
|
||||||
append(buf, ":", 2, ((val % DateUtils.MILLIS_PER_MINUTE) / DateUtils.MILLIS_PER_SECOND));
|
|
||||||
append(buf, ".", 3, (val % DateUtils.MILLIS_PER_SECOND));
|
|
||||||
return buf.toString();
|
return buf.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static long now() {
|
||||||
|
if (ourNowForUnitTest != null) {
|
||||||
|
return ourNowForUnitTest;
|
||||||
|
}
|
||||||
|
return System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
static void setNowForUnitTestForUnitTest(Long theNowForUnitTest) {
|
||||||
|
ourNowForUnitTest = theNowForUnitTest;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -681,6 +681,27 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test {
|
||||||
assertThat(actual, contains(id));
|
assertThat(actual, contains(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReturnOnlyCorrectResourceType() {
|
||||||
|
ValueSet vsRes = new ValueSet();
|
||||||
|
vsRes.setUrl("http://foo");
|
||||||
|
String vsId = myValueSetDao.create(vsRes).getId().toUnqualifiedVersionless().getValue();
|
||||||
|
|
||||||
|
CodeSystem csRes = new CodeSystem();
|
||||||
|
csRes.setUrl("http://bar");
|
||||||
|
String csId = myCodeSystemDao.create(csRes).getId().toUnqualifiedVersionless().getValue();
|
||||||
|
|
||||||
|
SearchParameterMap map = new SearchParameterMap().setLoadSynchronous(true);
|
||||||
|
map.add(ValueSet.SP_URL, new UriParam("http://foo"));
|
||||||
|
List<String> actual = toUnqualifiedVersionlessIdValues(myValueSetDao.search(map));
|
||||||
|
assertThat(actual, contains(vsId));
|
||||||
|
|
||||||
|
map = new SearchParameterMap().setLoadSynchronous(true);
|
||||||
|
map.add(ValueSet.SP_URL, new UriParam("http://bar"));
|
||||||
|
actual = toUnqualifiedVersionlessIdValues(myCodeSystemDao.search(map));
|
||||||
|
assertThat(actual, contains(csId));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* #454
|
* #454
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1569,7 +1569,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
* See #872
|
* See #872
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testExtensionUrlWithHl7UrlPost() throws IOException {
|
public void testValidateExtensionUrlWithHl7UrlPost() throws IOException {
|
||||||
RequestValidatingInterceptor interceptor = new RequestValidatingInterceptor();
|
RequestValidatingInterceptor interceptor = new RequestValidatingInterceptor();
|
||||||
FhirInstanceValidator val = new FhirInstanceValidator(myValidationSupport);
|
FhirInstanceValidator val = new FhirInstanceValidator(myValidationSupport);
|
||||||
interceptor.addValidatorModule(val);
|
interceptor.addValidatorModule(val);
|
||||||
|
@ -1578,14 +1578,15 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
try {
|
try {
|
||||||
String input = IOUtils.toString(ResourceProviderR4Test.class.getResourceAsStream("/bug872-ext-with-hl7-url.json"), Charsets.UTF_8);
|
String input = IOUtils.toString(ResourceProviderR4Test.class.getResourceAsStream("/bug872-ext-with-hl7-url.json"), Charsets.UTF_8);
|
||||||
|
|
||||||
HttpPost post = new HttpPost(ourServerBase + "/Patient/aaa");
|
HttpPost post = new HttpPost(ourServerBase + "/Patient/$validate");
|
||||||
post.setEntity(new StringEntity(input, ContentType.APPLICATION_JSON));
|
post.setEntity(new StringEntity(input, ContentType.APPLICATION_JSON));
|
||||||
|
|
||||||
CloseableHttpResponse resp = ourHttpClient.execute(post);
|
CloseableHttpResponse resp = ourHttpClient.execute(post);
|
||||||
try {
|
try {
|
||||||
String respString = IOUtils.toString(resp.getEntity().getContent(), Charsets.UTF_8);
|
String respString = IOUtils.toString(resp.getEntity().getContent(), Charsets.UTF_8);
|
||||||
ourLog.info(respString);
|
ourLog.info(respString);
|
||||||
assertEquals(400, resp.getStatusLine().getStatusCode());
|
assertThat(respString, containsString("Unknown extension http://hl7.org/fhir/ValueSet/v3-ActInvoiceGroupCode"));
|
||||||
|
assertEquals(200, resp.getStatusLine().getStatusCode());
|
||||||
} finally {
|
} finally {
|
||||||
IOUtils.closeQuietly(resp);
|
IOUtils.closeQuietly(resp);
|
||||||
}
|
}
|
||||||
|
@ -1611,14 +1612,11 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
IIdType id2 = myObservationDao.create(obs2, mySrd).getId().toUnqualifiedVersionless();
|
IIdType id2 = myObservationDao.create(obs2, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
HttpGet get = new HttpGet(ourServerBase + "/Observation?_content=systolic&_pretty=true");
|
HttpGet get = new HttpGet(ourServerBase + "/Observation?_content=systolic&_pretty=true");
|
||||||
CloseableHttpResponse response = ourHttpClient.execute(get);
|
try (CloseableHttpResponse response = ourHttpClient.execute(get)) {
|
||||||
try {
|
|
||||||
assertEquals(200, response.getStatusLine().getStatusCode());
|
assertEquals(200, response.getStatusLine().getStatusCode());
|
||||||
String responseString = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
|
String responseString = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||||
ourLog.info(responseString);
|
ourLog.info(responseString);
|
||||||
assertThat(responseString, containsString(id1.getIdPart()));
|
assertThat(responseString, containsString(id1.getIdPart()));
|
||||||
} finally {
|
|
||||||
response.close();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,20 +1,118 @@
|
||||||
package ca.uhn.fhir.jpa.util;
|
package ca.uhn.fhir.jpa.util;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.*;
|
import org.apache.commons.lang3.time.DateUtils;
|
||||||
import static org.junit.Assert.assertEquals;
|
import org.hamcrest.Matchers;
|
||||||
import static org.junit.Assert.assertThat;
|
import org.junit.After;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.apache.commons.lang3.time.DateUtils;
|
import static org.hamcrest.Matchers.*;
|
||||||
import org.hamcrest.Matchers;
|
import static org.junit.Assert.*;
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
public class StopWatchTest {
|
public class StopWatchTest {
|
||||||
|
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(StopWatchTest.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(StopWatchTest.class);
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void after() {
|
||||||
|
StopWatch.setNowForUnitTestForUnitTest(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private double calculateThroughput(int theMinutesElapsed, int theNumOperations) {
|
||||||
|
StopWatch sw = new StopWatch(DateUtils.addMinutes(new Date(), -theMinutesElapsed));
|
||||||
|
double throughput = sw.getThroughput(theNumOperations, TimeUnit.MINUTES);
|
||||||
|
ourLog.info("{} operations in {}ms = {} ops / second", theNumOperations, sw.getMillis(), throughput);
|
||||||
|
return throughput;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEstimatedTimeRemaining() {
|
||||||
|
StopWatch.setNowForUnitTestForUnitTest(777777777L);
|
||||||
|
StopWatch sw = new StopWatch();
|
||||||
|
|
||||||
|
StopWatch.setNowForUnitTestForUnitTest(777777777L + DateUtils.MILLIS_PER_MINUTE);
|
||||||
|
assertEquals("00:00:00.600", sw.getEstimatedTimeRemaining(0.99, 1.0));
|
||||||
|
|
||||||
|
StopWatch.setNowForUnitTestForUnitTest(777777777L + DateUtils.MILLIS_PER_MINUTE);
|
||||||
|
assertEquals("00:10:00", sw.getEstimatedTimeRemaining(0.1, 1.0));
|
||||||
|
|
||||||
|
StopWatch.setNowForUnitTestForUnitTest(777777777L + DateUtils.MILLIS_PER_MINUTE + 100);
|
||||||
|
assertEquals("00:10:01", sw.getEstimatedTimeRemaining(0.1, 1.0));
|
||||||
|
|
||||||
|
StopWatch.setNowForUnitTestForUnitTest(777777777L + DateUtils.MILLIS_PER_MINUTE);
|
||||||
|
assertEquals("00:20:00", sw.getEstimatedTimeRemaining(0.05, 1.0));
|
||||||
|
|
||||||
|
StopWatch.setNowForUnitTestForUnitTest(777777777L + DateUtils.MILLIS_PER_MINUTE);
|
||||||
|
assertEquals("00:40:00", sw.getEstimatedTimeRemaining(0.025, 1.0));
|
||||||
|
|
||||||
|
StopWatch.setNowForUnitTestForUnitTest(777777777L + DateUtils.MILLIS_PER_MINUTE);
|
||||||
|
assertEquals("01:40:00", sw.getEstimatedTimeRemaining(0.01, 1.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFormatMillis() {
|
||||||
|
assertEquals("00:00:01.000", StopWatch.formatMillis(DateUtils.MILLIS_PER_SECOND));
|
||||||
|
assertEquals("00:01:00.000", StopWatch.formatMillis(DateUtils.MILLIS_PER_MINUTE));
|
||||||
|
assertEquals("00:01:01", StopWatch.formatMillis(DateUtils.MILLIS_PER_MINUTE + DateUtils.MILLIS_PER_SECOND));
|
||||||
|
assertEquals("01:00:00", StopWatch.formatMillis(DateUtils.MILLIS_PER_HOUR));
|
||||||
|
assertEquals("1.0 day", StopWatch.formatMillis(DateUtils.MILLIS_PER_DAY));
|
||||||
|
assertEquals("2.0 days", StopWatch.formatMillis(DateUtils.MILLIS_PER_DAY * 2));
|
||||||
|
assertEquals("2.0 days", StopWatch.formatMillis((DateUtils.MILLIS_PER_DAY * 2) + 1));
|
||||||
|
assertEquals("2.4 days", StopWatch.formatMillis((DateUtils.MILLIS_PER_DAY * 2) + (10 * DateUtils.MILLIS_PER_HOUR)));
|
||||||
|
assertEquals("11 days", StopWatch.formatMillis((DateUtils.MILLIS_PER_DAY * 11) + (10 * DateUtils.MILLIS_PER_HOUR)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFormatThroughput60Ops4Min() {
|
||||||
|
StopWatch sw = new StopWatch(DateUtils.addMinutes(new Date(), -4));
|
||||||
|
String throughput = sw.formatThroughput(60, TimeUnit.MINUTES);
|
||||||
|
ourLog.info("{} operations in {}ms = {} ops / second", 60, sw.getMillis(), throughput);
|
||||||
|
assertThat(throughput, oneOf("14.9", "15.0", "15.1", "14,9", "15,0", "15,1"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMillisPerOperation() {
|
||||||
|
int minutes = 60;
|
||||||
|
StopWatch sw = new StopWatch(DateUtils.addMinutes(new Date(), -minutes));
|
||||||
|
int numOperations = 60;
|
||||||
|
int millis = sw.getMillisPerOperation(numOperations);
|
||||||
|
ourLog.info("{} operations in {}ms = {}ms / operation", numOperations, minutes * DateUtils.MILLIS_PER_MINUTE, millis);
|
||||||
|
|
||||||
|
assertThat(millis, Matchers.lessThan(62000));
|
||||||
|
assertThat(millis, Matchers.greaterThan(58000));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOperationThroughput30Ops1Min() {
|
||||||
|
double throughput = calculateThroughput(1, 30);
|
||||||
|
assertThat(throughput, greaterThan(29.0));
|
||||||
|
assertThat(throughput, lessThan(31.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOperationThroughput60Ops1Min() {
|
||||||
|
double throughput = calculateThroughput(1, 60);
|
||||||
|
assertThat(throughput, greaterThan(59.0));
|
||||||
|
assertThat(throughput, lessThan(61.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOperationThroughput60Ops4Min() {
|
||||||
|
double throughput = calculateThroughput(4, 60);
|
||||||
|
assertThat(throughput, greaterThan(14.0));
|
||||||
|
assertThat(throughput, lessThan(16.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRestart() throws InterruptedException {
|
||||||
|
StopWatch sw = new StopWatch();
|
||||||
|
Thread.sleep(500);
|
||||||
|
sw.restart();
|
||||||
|
assertThat(sw.getMillis(), lessThan(100L));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testStopwatch() throws Exception {
|
public void testStopwatch() throws Exception {
|
||||||
StopWatch sw = new StopWatch();
|
StopWatch sw = new StopWatch();
|
||||||
|
@ -37,62 +135,6 @@ public class StopWatchTest {
|
||||||
assertThat(sw.getStartedDate().getTime(), lessThan(System.currentTimeMillis()));
|
assertThat(sw.getStartedDate().getTime(), lessThan(System.currentTimeMillis()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testRestart() throws InterruptedException {
|
|
||||||
StopWatch sw = new StopWatch();
|
|
||||||
Thread.sleep(500);
|
|
||||||
sw.restart();
|
|
||||||
assertThat(sw.getMillis(), lessThan(100L));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testMillisPerOperation() {
|
|
||||||
int minutes = 60;
|
|
||||||
StopWatch sw = new StopWatch(DateUtils.addMinutes(new Date(), -minutes));
|
|
||||||
int numOperations = 60;
|
|
||||||
int millis = sw.getMillisPerOperation(numOperations);
|
|
||||||
ourLog.info("{} operations in {}ms = {}ms / operation", numOperations, minutes*DateUtils.MILLIS_PER_MINUTE, millis);
|
|
||||||
|
|
||||||
assertThat(millis, Matchers.lessThan(62000));
|
|
||||||
assertThat(millis, Matchers.greaterThan(58000));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testOperationThroughput60Ops1Min() {
|
|
||||||
double throughput = calculateThroughput(1, 60);
|
|
||||||
assertThat(throughput, greaterThan(59.0));
|
|
||||||
assertThat(throughput, lessThan(61.0));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testOperationThroughput30Ops1Min() {
|
|
||||||
double throughput = calculateThroughput(1, 30);
|
|
||||||
assertThat(throughput, greaterThan(29.0));
|
|
||||||
assertThat(throughput, lessThan(31.0));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testOperationThroughput60Ops4Min() {
|
|
||||||
double throughput = calculateThroughput(4, 60);
|
|
||||||
assertThat(throughput, greaterThan(14.0));
|
|
||||||
assertThat(throughput, lessThan(16.0));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testFormatThroughput60Ops4Min() {
|
|
||||||
StopWatch sw = new StopWatch(DateUtils.addMinutes(new Date(), -4));
|
|
||||||
String throughput = sw.formatThroughput(60, TimeUnit.MINUTES);
|
|
||||||
ourLog.info("{} operations in {}ms = {} ops / second", 60, sw.getMillis(), throughput);
|
|
||||||
assertThat(throughput, oneOf("14.9", "15.0", "15.1", "14,9", "15,0", "15,1"));
|
|
||||||
}
|
|
||||||
|
|
||||||
private double calculateThroughput(int theMinutesElapsed, int theNumOperations) {
|
|
||||||
StopWatch sw = new StopWatch(DateUtils.addMinutes(new Date(), -theMinutesElapsed));
|
|
||||||
double throughput = sw.getThroughput(theNumOperations, TimeUnit.MINUTES);
|
|
||||||
ourLog.info("{} operations in {}ms = {} ops / second", theNumOperations, sw.getMillis(), throughput);
|
|
||||||
return throughput;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testToString() throws Exception {
|
public void testToString() throws Exception {
|
||||||
StopWatch sw = new StopWatch();
|
StopWatch sw = new StopWatch();
|
||||||
|
@ -104,14 +146,4 @@ public class StopWatchTest {
|
||||||
assertThat(string, startsWith("00:00"));
|
assertThat(string, startsWith("00:00"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testFormatMillis() throws Exception {
|
|
||||||
assertEquals("00:00:01.000", StopWatch.formatMillis(DateUtils.MILLIS_PER_SECOND));
|
|
||||||
assertEquals("00:01:00.000", StopWatch.formatMillis(DateUtils.MILLIS_PER_MINUTE));
|
|
||||||
assertEquals("01:00:00.000", StopWatch.formatMillis(DateUtils.MILLIS_PER_HOUR));
|
|
||||||
assertEquals("1 day 00:00:00.000", StopWatch.formatMillis(DateUtils.MILLIS_PER_DAY));
|
|
||||||
assertEquals("2 days 00:00:00.000", StopWatch.formatMillis(DateUtils.MILLIS_PER_DAY*2));
|
|
||||||
assertEquals("2 days 00:00:00.001", StopWatch.formatMillis((DateUtils.MILLIS_PER_DAY*2)+1));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -172,7 +172,11 @@
|
||||||
<artifactId>guava</artifactId>
|
<artifactId>guava</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.guava</groupId>
|
||||||
|
<artifactId>guava-testlib</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework</groupId>
|
<groupId>org.springframework</groupId>
|
||||||
<artifactId>spring-web</artifactId>
|
<artifactId>spring-web</artifactId>
|
||||||
|
|
|
@ -1,18 +1,23 @@
|
||||||
package ca.uhn.fhir.rest.param;
|
package ca.uhn.fhir.rest.param;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.model.primitive.DateTimeDt;
|
||||||
|
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||||
|
import com.google.common.testing.EqualsTester;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import static ca.uhn.fhir.rest.param.ParamPrefixEnum.APPROXIMATE;
|
||||||
|
import static ca.uhn.fhir.rest.param.ParamPrefixEnum.EQUAL;
|
||||||
|
import static ca.uhn.fhir.rest.param.ParamPrefixEnum.NOT_EQUAL;
|
||||||
|
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||||
import static org.hamcrest.Matchers.endsWith;
|
import static org.hamcrest.Matchers.endsWith;
|
||||||
import static org.hamcrest.Matchers.startsWith;
|
import static org.hamcrest.Matchers.startsWith;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertThat;
|
import static org.junit.Assert.assertThat;
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.TimeZone;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import ca.uhn.fhir.model.primitive.DateTimeDt;
|
|
||||||
import ca.uhn.fhir.model.primitive.InstantDt;
|
|
||||||
|
|
||||||
public class DateParamTest {
|
public class DateParamTest {
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(DateParamTest.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(DateParamTest.class);
|
||||||
|
|
||||||
|
@ -105,6 +110,21 @@ public class DateParamTest {
|
||||||
assertEquals(ParamPrefixEnum.LESSTHAN, new DateParam("lt2012").getPrefix());
|
assertEquals(ParamPrefixEnum.LESSTHAN, new DateParam("lt2012").getPrefix());
|
||||||
assertEquals(ParamPrefixEnum.LESSTHAN_OR_EQUALS, new DateParam("le2012").getPrefix());
|
assertEquals(ParamPrefixEnum.LESSTHAN_OR_EQUALS, new DateParam("le2012").getPrefix());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test()
|
||||||
|
public void testEqualsAndHashCode() {
|
||||||
|
Date now = new Date();
|
||||||
|
Date later = new Date(now.getTime() + SECONDS.toMillis(666));
|
||||||
|
new EqualsTester()
|
||||||
|
.addEqualityGroup(new DateParam(),
|
||||||
|
new DateParam(null))
|
||||||
|
.addEqualityGroup(new DateParam(NOT_EQUAL, now),
|
||||||
|
new DateParam(NOT_EQUAL, now.getTime()))
|
||||||
|
.addEqualityGroup(new DateParam(EQUAL, now),
|
||||||
|
new DateParam(EQUAL, now.getTime()))
|
||||||
|
.addEqualityGroup(new DateParam(EQUAL, later),
|
||||||
|
new DateParam(EQUAL, later.getTime()))
|
||||||
|
.addEqualityGroup(new DateParam(APPROXIMATE, "2011-11-11T11:11:11.111-11:11"))
|
||||||
|
.testEquals();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -261,7 +261,11 @@
|
||||||
<artifactId>guava</artifactId>
|
<artifactId>guava</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.guava</groupId>
|
||||||
|
<artifactId>guava-testlib</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework</groupId>
|
<groupId>org.springframework</groupId>
|
||||||
<artifactId>spring-web</artifactId>
|
<artifactId>spring-web</artifactId>
|
||||||
|
|
|
@ -1,12 +1,28 @@
|
||||||
package ca.uhn.fhir.rest.param;
|
package ca.uhn.fhir.rest.param;
|
||||||
|
|
||||||
|
import static ca.uhn.fhir.rest.param.ParamPrefixEnum.APPROXIMATE;
|
||||||
|
import static ca.uhn.fhir.rest.param.ParamPrefixEnum.EQUAL;
|
||||||
|
import static ca.uhn.fhir.rest.param.ParamPrefixEnum.GREATERTHAN;
|
||||||
|
import static ca.uhn.fhir.rest.param.ParamPrefixEnum.GREATERTHAN_OR_EQUALS;
|
||||||
|
import static ca.uhn.fhir.rest.param.ParamPrefixEnum.LESSTHAN;
|
||||||
|
import static ca.uhn.fhir.rest.param.ParamPrefixEnum.LESSTHAN_OR_EQUALS;
|
||||||
|
import static ca.uhn.fhir.rest.param.ParamPrefixEnum.NOT_EQUAL;
|
||||||
|
import static com.google.common.collect.Lists.newArrayList;
|
||||||
|
import static java.lang.System.currentTimeMillis;
|
||||||
|
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||||
|
import static org.hamcrest.core.Is.is;
|
||||||
|
import static org.hamcrest.core.IsEqual.equalTo;
|
||||||
|
import static org.hamcrest.core.IsNot.not;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
|
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import com.google.common.testing.EqualsTester;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
@ -183,7 +199,26 @@ public class DateRangeParamTest {
|
||||||
public static void afterClassClearContext() {
|
public static void afterClassClearContext() {
|
||||||
TestUtil.clearAllStaticFieldsForUnitTest();
|
TestUtil.clearAllStaticFieldsForUnitTest();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test()
|
||||||
|
public void testEqualsAndHashCode() {
|
||||||
|
Date lowerBound = new Date(currentTimeMillis());
|
||||||
|
Date upperBound = new Date(lowerBound.getTime() + SECONDS.toMillis(1));
|
||||||
|
new EqualsTester()
|
||||||
|
.addEqualityGroup(new DateRangeParam(),
|
||||||
|
new DateRangeParam((Date) null, (Date) null))
|
||||||
|
.addEqualityGroup(new DateRangeParam(lowerBound, upperBound),
|
||||||
|
new DateRangeParam(new DateParam(GREATERTHAN_OR_EQUALS, lowerBound), new DateParam(LESSTHAN_OR_EQUALS, upperBound)))
|
||||||
|
.addEqualityGroup(new DateRangeParam(new DateParam(EQUAL, lowerBound)),
|
||||||
|
new DateRangeParam(new DateParam(null, lowerBound)),
|
||||||
|
new DateRangeParam(new DateParam(EQUAL, lowerBound), new DateParam(EQUAL, lowerBound)))
|
||||||
|
.addEqualityGroup(new DateRangeParam(lowerBound, null),
|
||||||
|
new DateRangeParam(new DateParam(GREATERTHAN_OR_EQUALS, lowerBound), null))
|
||||||
|
.addEqualityGroup(new DateRangeParam(null, upperBound),
|
||||||
|
new DateRangeParam(null, new DateParam(LESSTHAN_OR_EQUALS, upperBound)))
|
||||||
|
.testEquals();
|
||||||
|
}
|
||||||
|
|
||||||
private static DateRangeParam create(String theLower, String theUpper) throws InvalidRequestException {
|
private static DateRangeParam create(String theLower, String theUpper) throws InvalidRequestException {
|
||||||
DateRangeParam p = new DateRangeParam();
|
DateRangeParam p = new DateRangeParam();
|
||||||
List<QualifiedParamList> tokens = new ArrayList<QualifiedParamList>();
|
List<QualifiedParamList> tokens = new ArrayList<QualifiedParamList>();
|
||||||
|
@ -202,5 +237,4 @@ public class DateRangeParamTest {
|
||||||
public static Date parseM1(String theString) throws ParseException {
|
public static Date parseM1(String theString) throws ParseException {
|
||||||
return new Date(ourFmt.parse(theString).getTime() - 1L);
|
return new Date(ourFmt.parse(theString).getTime() - 1L);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,6 +88,39 @@ public class JsonParserR4Test {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* See #814
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testDuplicateContainedResourcesNotOutputtedTwiceWithManualIdsAndManualAddition() {
|
||||||
|
MedicationDispense md = new MedicationDispense();
|
||||||
|
|
||||||
|
MedicationRequest mr = new MedicationRequest();
|
||||||
|
mr.setId("#MR");
|
||||||
|
md.addAuthorizingPrescription().setResource(mr);
|
||||||
|
|
||||||
|
Medication med = new Medication();
|
||||||
|
med.setId("#MED");
|
||||||
|
|
||||||
|
Reference medRef = new Reference();
|
||||||
|
medRef.setReference("#MED");
|
||||||
|
md.setMedication(medRef);
|
||||||
|
mr.setMedication(medRef);
|
||||||
|
|
||||||
|
md.getContained().add(mr);
|
||||||
|
md.getContained().add(med);
|
||||||
|
|
||||||
|
String encoded = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(md);
|
||||||
|
ourLog.info(encoded);
|
||||||
|
|
||||||
|
int idx = encoded.indexOf("\"Medication\"");
|
||||||
|
assertNotEquals(-1, idx);
|
||||||
|
|
||||||
|
idx = encoded.indexOf("\"Medication\"", idx + 1);
|
||||||
|
assertEquals(-1, idx);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEncodeAndParseUnicodeCharacterInNarrative() {
|
public void testEncodeAndParseUnicodeCharacterInNarrative() {
|
||||||
Patient p = new Patient();
|
Patient p = new Patient();
|
||||||
|
|
9
pom.xml
9
pom.xml
|
@ -386,6 +386,10 @@
|
||||||
<id>darktyko</id>
|
<id>darktyko</id>
|
||||||
<name>Kyle Meadows</name>
|
<name>Kyle Meadows</name>
|
||||||
</developer>
|
</developer>
|
||||||
|
<developer>
|
||||||
|
<id>Tastelezz</id>
|
||||||
|
<name>Gaetano Gallo</name>
|
||||||
|
</developer>
|
||||||
|
|
||||||
</developers>
|
</developers>
|
||||||
|
|
||||||
|
@ -510,6 +514,11 @@
|
||||||
<artifactId>guava</artifactId>
|
<artifactId>guava</artifactId>
|
||||||
<version>23.0</version>
|
<version>23.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.guava</groupId>
|
||||||
|
<artifactId>guava-testlib</artifactId>
|
||||||
|
<version>23.0</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.phloc</groupId>
|
<groupId>com.phloc</groupId>
|
||||||
<artifactId>phloc-schematron</artifactId>
|
<artifactId>phloc-schematron</artifactId>
|
||||||
|
|
|
@ -176,6 +176,24 @@
|
||||||
cam be useful for tests or for static servers with small amounts
|
cam be useful for tests or for static servers with small amounts
|
||||||
of data.
|
of data.
|
||||||
</action>
|
</action>
|
||||||
|
<action type="fix" issue="872">
|
||||||
|
An issue in the JPA server was corrected where searching using
|
||||||
|
URI search parameters would sometimes not include the resource type in the
|
||||||
|
criteria. This meant, for example, that a search for
|
||||||
|
<![CDATA[<code>ValueSet?url=http://foo</code>]]> would also
|
||||||
|
match any CodeSystem resource that happened to also have
|
||||||
|
that URL as the value for the "url" search parameter. Thanks
|
||||||
|
to Josh Mandel for reporting and supplying a test case!
|
||||||
|
</action>
|
||||||
|
<action type="add" issue="868">
|
||||||
|
DateParam class now has equals() and hashCode() implementations. Thanks
|
||||||
|
to Gaetano Gallo for the pull request!
|
||||||
|
</action>
|
||||||
|
<action type="fix" issue="814">
|
||||||
|
Fix a bug where under certain circumstances, duplicate contained resources
|
||||||
|
could be output by the parser's encode methods. Thanks to
|
||||||
|
Frank Tao for supplying a test case!
|
||||||
|
</action>
|
||||||
</release>
|
</release>
|
||||||
<release version="3.2.0" date="2018-01-13">
|
<release version="3.2.0" date="2018-01-13">
|
||||||
<action type="add">
|
<action type="add">
|
||||||
|
|
Loading…
Reference in New Issue