FIx up tests
This commit is contained in:
parent
abf76a778f
commit
7e2459fbdc
|
@ -1,6 +1,24 @@
|
|||
package ca.uhn.fhir.model.primitive;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.defaultString;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.api.annotation.DatatypeDef;
|
||||
import ca.uhn.fhir.model.api.annotation.SimpleSetter;
|
||||
import ca.uhn.fhir.parser.DataFormatException;
|
||||
import ca.uhn.fhir.rest.api.Constants;
|
||||
import ca.uhn.fhir.util.UrlUtil;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.apache.commons.lang3.builder.HashCodeBuilder;
|
||||
import org.hl7.fhir.instance.model.api.IAnyResource;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.*;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
|
@ -10,9 +28,9 @@ import static org.apache.commons.lang3.StringUtils.defaultString;
|
|||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
@ -20,26 +38,10 @@ import static org.apache.commons.lang3.StringUtils.defaultString;
|
|||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.apache.commons.lang3.*;
|
||||
import org.apache.commons.lang3.builder.HashCodeBuilder;
|
||||
import org.hl7.fhir.instance.model.api.*;
|
||||
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.api.annotation.DatatypeDef;
|
||||
import ca.uhn.fhir.model.api.annotation.SimpleSetter;
|
||||
import ca.uhn.fhir.parser.DataFormatException;
|
||||
import ca.uhn.fhir.rest.api.Constants;
|
||||
import ca.uhn.fhir.util.UrlUtil;
|
||||
|
||||
/**
|
||||
* Represents the FHIR ID type. This is the actual resource ID, meaning the ID that will be used in RESTful URLs, Resource References, etc. to represent a specific instance of a resource.
|
||||
*
|
||||
* <p>
|
||||
* <p>
|
||||
* <b>Description</b>: A whole number in the range 0 to 2^64-1 (optionally represented in hex), a uuid, an oid, or any other combination of lowercase letters, numerals, "-" and ".", with a length
|
||||
* limit of 36 characters.
|
||||
|
@ -84,7 +86,7 @@ public class IdDt extends UriDt implements /*IPrimitiveDatatype<String>, */IIdTy
|
|||
|
||||
/**
|
||||
* Create a new ID using a string. This String may contain a simple ID (e.g. "1234") or it may contain a complete URL (http://example.com/fhir/Patient/1234).
|
||||
*
|
||||
* <p>
|
||||
* <p>
|
||||
* <b>Description</b>: A whole number in the range 0 to 2^64-1 (optionally represented in hex), a uuid, an oid, or any other combination of lowercase letters, numerals, "-" and ".", with a length
|
||||
* limit of 36 characters.
|
||||
|
@ -100,11 +102,9 @@ public class IdDt extends UriDt implements /*IPrimitiveDatatype<String>, */IIdTy
|
|||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param theResourceType
|
||||
* The resource type (e.g. "Patient")
|
||||
* @param theIdPart
|
||||
* The ID (e.g. "123")
|
||||
*
|
||||
* @param theResourceType The resource type (e.g. "Patient")
|
||||
* @param theIdPart The ID (e.g. "123")
|
||||
*/
|
||||
public IdDt(String theResourceType, BigDecimal theIdPart) {
|
||||
this(theResourceType, toPlainStringWithNpeThrowIfNeeded(theIdPart));
|
||||
|
@ -112,11 +112,9 @@ public class IdDt extends UriDt implements /*IPrimitiveDatatype<String>, */IIdTy
|
|||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param theResourceType
|
||||
* The resource type (e.g. "Patient")
|
||||
* @param theIdPart
|
||||
* The ID (e.g. "123")
|
||||
*
|
||||
* @param theResourceType The resource type (e.g. "Patient")
|
||||
* @param theIdPart The ID (e.g. "123")
|
||||
*/
|
||||
public IdDt(String theResourceType, Long theIdPart) {
|
||||
this(theResourceType, toPlainStringWithNpeThrowIfNeeded(theIdPart));
|
||||
|
@ -125,10 +123,8 @@ public class IdDt extends UriDt implements /*IPrimitiveDatatype<String>, */IIdTy
|
|||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param theResourceType
|
||||
* The resource type (e.g. "Patient")
|
||||
* @param theId
|
||||
* The ID (e.g. "123")
|
||||
* @param theResourceType The resource type (e.g. "Patient")
|
||||
* @param theId The ID (e.g. "123")
|
||||
*/
|
||||
public IdDt(String theResourceType, String theId) {
|
||||
this(theResourceType, theId, null);
|
||||
|
@ -136,13 +132,10 @@ public class IdDt extends UriDt implements /*IPrimitiveDatatype<String>, */IIdTy
|
|||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param theResourceType
|
||||
* The resource type (e.g. "Patient")
|
||||
* @param theId
|
||||
* The ID (e.g. "123")
|
||||
* @param theVersionId
|
||||
* The version ID ("e.g. "456")
|
||||
*
|
||||
* @param theResourceType The resource type (e.g. "Patient")
|
||||
* @param theId The ID (e.g. "123")
|
||||
* @param theVersionId The version ID ("e.g. "456")
|
||||
*/
|
||||
public IdDt(String theResourceType, String theId, String theVersionId) {
|
||||
this(null, theResourceType, theId, theVersionId);
|
||||
|
@ -150,15 +143,11 @@ public class IdDt extends UriDt implements /*IPrimitiveDatatype<String>, */IIdTy
|
|||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param theBaseUrl
|
||||
* The server base URL (e.g. "http://example.com/fhir")
|
||||
* @param theResourceType
|
||||
* The resource type (e.g. "Patient")
|
||||
* @param theId
|
||||
* The ID (e.g. "123")
|
||||
* @param theVersionId
|
||||
* The version ID ("e.g. "456")
|
||||
*
|
||||
* @param theBaseUrl The server base URL (e.g. "http://example.com/fhir")
|
||||
* @param theResourceType The resource type (e.g. "Patient")
|
||||
* @param theId The ID (e.g. "123")
|
||||
* @param theVersionId The version ID ("e.g. "456")
|
||||
*/
|
||||
public IdDt(String theBaseUrl, String theResourceType, String theId, String theVersionId) {
|
||||
myBaseUrl = theBaseUrl;
|
||||
|
@ -244,9 +233,8 @@ public class IdDt extends UriDt implements /*IPrimitiveDatatype<String>, */IIdTy
|
|||
|
||||
/**
|
||||
* Returns the unqualified portion of this ID as a big decimal, or <code>null</code> if the value is null
|
||||
*
|
||||
* @throws NumberFormatException
|
||||
* If the value is not a valid BigDecimal
|
||||
*
|
||||
* @throws NumberFormatException If the value is not a valid BigDecimal
|
||||
*/
|
||||
public BigDecimal getIdPartAsBigDecimal() {
|
||||
String val = getIdPart();
|
||||
|
@ -258,9 +246,8 @@ public class IdDt extends UriDt implements /*IPrimitiveDatatype<String>, */IIdTy
|
|||
|
||||
/**
|
||||
* Returns the unqualified portion of this ID as a {@link Long}, or <code>null</code> if the value is null
|
||||
*
|
||||
* @throws NumberFormatException
|
||||
* If the value is not a valid Long
|
||||
*
|
||||
* @throws NumberFormatException If the value is not a valid Long
|
||||
*/
|
||||
@Override
|
||||
public Long getIdPartAsLong() {
|
||||
|
@ -278,7 +265,7 @@ public class IdDt extends UriDt implements /*IPrimitiveDatatype<String>, */IIdTy
|
|||
|
||||
/**
|
||||
* Returns the value of this ID. Note that this value may be a fully qualified URL, a relative/partial URL, or a simple ID. Use {@link #getIdPart()} to get just the ID portion.
|
||||
*
|
||||
*
|
||||
* @see #getIdPart()
|
||||
*/
|
||||
@Override
|
||||
|
@ -323,157 +310,9 @@ public class IdDt extends UriDt implements /*IPrimitiveDatatype<String>, */IIdTy
|
|||
return super.getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValueAsString() {
|
||||
return getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVersionIdPart() {
|
||||
return myUnqualifiedVersionId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getVersionIdPartAsLong() {
|
||||
if (!hasVersionIdPart()) {
|
||||
return null;
|
||||
}
|
||||
return Long.parseLong(getVersionIdPart());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this ID has a base url
|
||||
*
|
||||
* @see #getBaseUrl()
|
||||
*/
|
||||
@Override
|
||||
public boolean hasBaseUrl() {
|
||||
return isNotBlank(myBaseUrl);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
HashCodeBuilder b = new HashCodeBuilder();
|
||||
b.append(getValueAsString());
|
||||
return b.toHashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasIdPart() {
|
||||
return isNotBlank(getIdPart());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasResourceType() {
|
||||
return isNotBlank(myResourceType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasVersionIdPart() {
|
||||
return isNotBlank(getVersionIdPart());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if this ID contains an absolute URL (in other words, a URL starting with "http://" or "https://"
|
||||
*/
|
||||
@Override
|
||||
public boolean isAbsolute() {
|
||||
if (StringUtils.isBlank(getValue())) {
|
||||
return false;
|
||||
}
|
||||
return UrlUtil.isAbsolute(getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return super.isBaseEmpty() && isBlank(getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isIdPartValid() {
|
||||
String id = getIdPart();
|
||||
if (StringUtils.isBlank(id)) {
|
||||
return false;
|
||||
}
|
||||
if (id.length() > 64) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < id.length(); i++) {
|
||||
char nextChar = id.charAt(i);
|
||||
if (nextChar >= 'a' && nextChar <= 'z') {
|
||||
continue;
|
||||
}
|
||||
if (nextChar >= 'A' && nextChar <= 'Z') {
|
||||
continue;
|
||||
}
|
||||
if (nextChar >= '0' && nextChar <= '9') {
|
||||
continue;
|
||||
}
|
||||
if (nextChar == '-' || nextChar == '.') {
|
||||
continue;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isIdPartValidLong() {
|
||||
return isValidLong(getIdPart());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if the ID is a local reference (in other words,
|
||||
* it begins with the '#' character)
|
||||
*/
|
||||
@Override
|
||||
public boolean isLocal() {
|
||||
return defaultString(myUnqualifiedId).startsWith("#");
|
||||
}
|
||||
|
||||
private boolean isUrn() {
|
||||
return defaultString(myUnqualifiedId).startsWith("urn:");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVersionIdPartValidLong() {
|
||||
return isValidLong(getVersionIdPart());
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the value from the given IdDt to <code>this</code> IdDt. It is generally not neccesary to use this method but it is provided for consistency with the rest of the API.
|
||||
* @deprecated
|
||||
*/
|
||||
@Deprecated //override deprecated method
|
||||
@Override
|
||||
public void setId(IdDt theId) {
|
||||
setValue(theId.getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public IIdType setParts(String theBaseUrl, String theResourceType, String theIdPart, String theVersionIdPart) {
|
||||
if (isNotBlank(theVersionIdPart)) {
|
||||
Validate.notBlank(theResourceType, "If theVersionIdPart is populated, theResourceType and theIdPart must be populated");
|
||||
Validate.notBlank(theIdPart, "If theVersionIdPart is populated, theResourceType and theIdPart must be populated");
|
||||
}
|
||||
if (isNotBlank(theBaseUrl) && isNotBlank(theIdPart)) {
|
||||
Validate.notBlank(theResourceType, "If theBaseUrl is populated and theIdPart is populated, theResourceType must be populated");
|
||||
}
|
||||
|
||||
setValue(null);
|
||||
|
||||
myBaseUrl = theBaseUrl;
|
||||
myResourceType = theResourceType;
|
||||
myUnqualifiedId = theIdPart;
|
||||
myUnqualifiedVersionId = StringUtils.defaultIfBlank(theVersionIdPart, null);
|
||||
myHaveComponentParts = true;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value
|
||||
*
|
||||
* <p>
|
||||
* <p>
|
||||
* <b>Description</b>: A whole number in the range 0 to 2^64-1 (optionally represented in hex), a uuid, an oid, or any other combination of lowercase letters, numerals, "-" and ".", with a length
|
||||
* limit of 36 characters.
|
||||
|
@ -555,9 +394,14 @@ public class IdDt extends UriDt implements /*IPrimitiveDatatype<String>, */IIdTy
|
|||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValueAsString() {
|
||||
return getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value
|
||||
*
|
||||
* <p>
|
||||
* <p>
|
||||
* <b>Description</b>: A whole number in the range 0 to 2^64-1 (optionally represented in hex), a uuid, an oid, or any other combination of lowercase letters, numerals, "-" and ".", with a length
|
||||
* limit of 36 characters.
|
||||
|
@ -571,6 +415,150 @@ public class IdDt extends UriDt implements /*IPrimitiveDatatype<String>, */IIdTy
|
|||
setValue(theValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVersionIdPart() {
|
||||
return myUnqualifiedVersionId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getVersionIdPartAsLong() {
|
||||
if (!hasVersionIdPart()) {
|
||||
return null;
|
||||
}
|
||||
return Long.parseLong(getVersionIdPart());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this ID has a base url
|
||||
*
|
||||
* @see #getBaseUrl()
|
||||
*/
|
||||
@Override
|
||||
public boolean hasBaseUrl() {
|
||||
return isNotBlank(myBaseUrl);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasIdPart() {
|
||||
return isNotBlank(getIdPart());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasResourceType() {
|
||||
return isNotBlank(myResourceType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasVersionIdPart() {
|
||||
return isNotBlank(getVersionIdPart());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
HashCodeBuilder b = new HashCodeBuilder();
|
||||
b.append(getValueAsString());
|
||||
return b.toHashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if this ID contains an absolute URL (in other words, a URL starting with "http://" or "https://"
|
||||
*/
|
||||
@Override
|
||||
public boolean isAbsolute() {
|
||||
if (StringUtils.isBlank(getValue())) {
|
||||
return false;
|
||||
}
|
||||
return UrlUtil.isAbsolute(getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return super.isBaseEmpty() && isBlank(getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isIdPartValid() {
|
||||
String id = getIdPart();
|
||||
if (StringUtils.isBlank(id)) {
|
||||
return false;
|
||||
}
|
||||
if (id.length() > 64) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < id.length(); i++) {
|
||||
char nextChar = id.charAt(i);
|
||||
if (nextChar >= 'a' && nextChar <= 'z') {
|
||||
continue;
|
||||
}
|
||||
if (nextChar >= 'A' && nextChar <= 'Z') {
|
||||
continue;
|
||||
}
|
||||
if (nextChar >= '0' && nextChar <= '9') {
|
||||
continue;
|
||||
}
|
||||
if (nextChar == '-' || nextChar == '.') {
|
||||
continue;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isIdPartValidLong() {
|
||||
return isValidLong(getIdPart());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if the ID is a local reference (in other words,
|
||||
* it begins with the '#' character)
|
||||
*/
|
||||
@Override
|
||||
public boolean isLocal() {
|
||||
return defaultString(myUnqualifiedId).startsWith("#");
|
||||
}
|
||||
|
||||
private boolean isUrn() {
|
||||
return defaultString(myUnqualifiedId).startsWith("urn:");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVersionIdPartValidLong() {
|
||||
return isValidLong(getVersionIdPart());
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the value from the given IdDt to <code>this</code> IdDt. It is generally not neccesary to use this method but it is provided for consistency with the rest of the API.
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
@Deprecated //override deprecated method
|
||||
@Override
|
||||
public void setId(IdDt theId) {
|
||||
setValue(theId.getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public IIdType setParts(String theBaseUrl, String theResourceType, String theIdPart, String theVersionIdPart) {
|
||||
if (isNotBlank(theVersionIdPart)) {
|
||||
Validate.notBlank(theResourceType, "If theVersionIdPart is populated, theResourceType and theIdPart must be populated");
|
||||
Validate.notBlank(theIdPart, "If theVersionIdPart is populated, theResourceType and theIdPart must be populated");
|
||||
}
|
||||
if (isNotBlank(theBaseUrl) && isNotBlank(theIdPart)) {
|
||||
Validate.notBlank(theResourceType, "If theBaseUrl is populated and theIdPart is populated, theResourceType must be populated");
|
||||
}
|
||||
|
||||
setValue(null);
|
||||
|
||||
myBaseUrl = theBaseUrl;
|
||||
myResourceType = theResourceType;
|
||||
myUnqualifiedId = theIdPart;
|
||||
myUnqualifiedVersionId = StringUtils.defaultIfBlank(theVersionIdPart, null);
|
||||
myHaveComponentParts = true;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getValue();
|
||||
|
@ -615,11 +603,9 @@ public class IdDt extends UriDt implements /*IPrimitiveDatatype<String>, */IIdTy
|
|||
/**
|
||||
* Returns a view of this ID as a fully qualified URL, given a server base and resource name (which will only be used if the ID does not already contain those respective parts). Essentially,
|
||||
* because IdDt can contain either a complete URL or a partial one (or even jut a simple ID), this method may be used to translate into a complete URL.
|
||||
*
|
||||
* @param theServerBase
|
||||
* The server base (e.g. "http://example.com/fhir")
|
||||
* @param theResourceType
|
||||
* The resource name (e.g. "Patient")
|
||||
*
|
||||
* @param theServerBase The server base (e.g. "http://example.com/fhir")
|
||||
* @param theResourceType The resource name (e.g. "Patient")
|
||||
* @return A fully qualified URL for this ID (e.g. "http://example.com/fhir/Patient/1")
|
||||
*/
|
||||
@Override
|
||||
|
@ -632,9 +618,8 @@ public class IdDt extends UriDt implements /*IPrimitiveDatatype<String>, */IIdTy
|
|||
|
||||
/**
|
||||
* Creates a new instance of this ID which is identical, but refers to the specific version of this resource ID noted by theVersion.
|
||||
*
|
||||
* @param theVersion
|
||||
* The actual version string, e.g. "1"
|
||||
*
|
||||
* @param theVersion The actual version string, e.g. "1"
|
||||
* @return A new instance of IdDt which is identical, but refers to the specific version of this resource ID noted by theVersion.
|
||||
*/
|
||||
@Override
|
||||
|
|
|
@ -1534,7 +1534,6 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
theEntity.setParamsUriPopulated(uriParams.isEmpty() == false);
|
||||
theEntity.setParamsCoords(coordsParams);
|
||||
theEntity.setParamsCoordsPopulated(coordsParams.isEmpty() == false);
|
||||
// theEntity.setParamsCompositeStringUnique(compositeStringUniques);
|
||||
theEntity.setParamsCompositeStringUniquePresent(compositeStringUniques.isEmpty() == false);
|
||||
theEntity.setResourceLinks(links);
|
||||
theEntity.setHasLinks(links.isEmpty() == false);
|
||||
|
@ -1697,7 +1696,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
if (getConfig().isUniqueIndexesEnabled()) {
|
||||
for (ResourceIndexedCompositeStringUnique next : existingCompositeStringUniques) {
|
||||
if (!compositeStringUniques.contains(next)) {
|
||||
ourLog.info("Removing unique index: {}", next);
|
||||
ourLog.debug("Removing unique index: {}", next);
|
||||
myEntityManager.remove(next);
|
||||
}
|
||||
}
|
||||
|
@ -1709,7 +1708,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
throw new PreconditionFailedException("Can not create resource of type " + theEntity.getResourceType() + " as it would create a duplicate index matching query: " + next.getIndexString() + " (existing index belongs to " + existing.getResource().getIdDt().toUnqualifiedVersionless().getValue() + ")");
|
||||
}
|
||||
}
|
||||
ourLog.info("Persisting unique index: {}", next);
|
||||
ourLog.debug("Persisting unique index: {}", next);
|
||||
myEntityManager.persist(next);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -68,7 +68,6 @@ public class ResourceIndexedCompositeStringUnique implements Comparable<Resource
|
|||
@Override
|
||||
public int compareTo(ResourceIndexedCompositeStringUnique theO) {
|
||||
CompareToBuilder b = new CompareToBuilder();
|
||||
b.append(myResource, theO.getResource());
|
||||
b.append(myIndexString, theO.getIndexString());
|
||||
return b.toComparison();
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import ca.uhn.fhir.jpa.subscription.email.IEmailSender;
|
|||
import ca.uhn.fhir.jpa.subscription.email.JavaMailEmailSender;
|
||||
import ca.uhn.fhir.rest.server.interceptor.RequestValidatingInterceptor;
|
||||
import ca.uhn.fhir.validation.ResultSeverityEnum;
|
||||
import net.ttddyy.dsproxy.listener.logging.SLF4JLogLevel;
|
||||
import net.ttddyy.dsproxy.support.ProxyDataSourceBuilder;
|
||||
import org.apache.commons.dbcp2.BasicDataSource;
|
||||
import org.hibernate.jpa.HibernatePersistenceProvider;
|
||||
|
@ -116,7 +117,7 @@ public class TestDstu3Config extends BaseJavaConfigDstu3 {
|
|||
|
||||
DataSource dataSource = ProxyDataSourceBuilder
|
||||
.create(basicDataSource())
|
||||
// .logQueryBySlf4j(SLF4JLogLevel.INFO, "SQL")
|
||||
// .logQueryBySlf4j(SLF4JLogLevel.INFO, "SQL")
|
||||
.logSlowQueryBySlf4j(1000, TimeUnit.MILLISECONDS)
|
||||
.countQuery()
|
||||
.build();
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package ca.uhn.fhir.jpa.dao.r4;
|
||||
|
||||
import ca.uhn.fhir.jpa.dao.DaoConfig;
|
||||
import ca.uhn.fhir.jpa.dao.DaoMethodOutcome;
|
||||
import ca.uhn.fhir.jpa.dao.SearchBuilder;
|
||||
import ca.uhn.fhir.jpa.dao.SearchParameterMap;
|
||||
import ca.uhn.fhir.jpa.entity.ResourceIndexedCompositeStringUnique;
|
||||
|
@ -48,32 +47,6 @@ public class FhirResourceDaoR4UniqueSearchParamTest extends BaseJpaR4Test {
|
|||
myDaoConfig.setDefaultSearchParamsCanBeOverridden(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNonTransaction() {
|
||||
createUniqueBirthdateAndGenderSps();
|
||||
|
||||
Patient p = new Patient();
|
||||
p.setGender(Enumerations.AdministrativeGender.MALE);
|
||||
p.setBirthDateElement(new DateType("2001-01-01"));
|
||||
|
||||
Bundle input = new Bundle();
|
||||
input.setType(Bundle.BundleType.TRANSACTION);
|
||||
input.addEntry()
|
||||
.setResource(p)
|
||||
.setFullUrl("Patient")
|
||||
.getRequest()
|
||||
.setMethod(Bundle.HTTPVerb.POST)
|
||||
.setUrl("/Patient")
|
||||
.setIfNoneExist("Patient?gender=http%3A%2F%2Fhl7.org%2Ffhir%2Fadministrative-gender%7Cmale&birthdate=2001-01-01");
|
||||
|
||||
Bundle output0 = mySystemDao.transaction(mySrd, input);
|
||||
Bundle output1 = mySystemDao.transaction(mySrd, input);
|
||||
assertEquals(output1.getEntry().get(0).getFullUrl(), output0.getEntry().get(0).getFullUrl());
|
||||
Bundle output2 = mySystemDao.transaction(mySrd, input);
|
||||
assertEquals(output2.getEntry().get(0).getFullUrl(), output0.getEntry().get(0).getFullUrl());
|
||||
|
||||
}
|
||||
|
||||
private void createUniqueBirthdateAndGenderSps() {
|
||||
SearchParameter sp = new SearchParameter();
|
||||
sp.setId("SearchParameter/patient-gender");
|
||||
|
@ -112,6 +85,129 @@ public class FhirResourceDaoR4UniqueSearchParamTest extends BaseJpaR4Test {
|
|||
mySearchParamRegsitry.forceRefresh();
|
||||
}
|
||||
|
||||
private void createUniqueIndexCoverageBeneficiary() {
|
||||
SearchParameter sp = new SearchParameter();
|
||||
sp.setId("SearchParameter/coverage-beneficiary");
|
||||
sp.setCode("beneficiary");
|
||||
sp.setExpression("Coverage.beneficiary");
|
||||
sp.setType(Enumerations.SearchParamType.REFERENCE);
|
||||
sp.setStatus(PublicationStatus.ACTIVE);
|
||||
sp.addBase("Coverage");
|
||||
mySearchParameterDao.update(sp);
|
||||
|
||||
sp = new SearchParameter();
|
||||
sp.setId("SearchParameter/coverage-identifier");
|
||||
sp.setCode("identifier");
|
||||
sp.setExpression("Coverage.identifier");
|
||||
sp.setType(Enumerations.SearchParamType.TOKEN);
|
||||
sp.setStatus(PublicationStatus.ACTIVE);
|
||||
sp.addBase("Coverage");
|
||||
mySearchParameterDao.update(sp);
|
||||
|
||||
sp = new SearchParameter();
|
||||
sp.setId("SearchParameter/coverage-beneficiary-identifier");
|
||||
sp.setCode("coverage-beneficiary-identifier");
|
||||
sp.setExpression("Coverage.beneficiary");
|
||||
sp.setType(Enumerations.SearchParamType.COMPOSITE);
|
||||
sp.setStatus(PublicationStatus.ACTIVE);
|
||||
sp.addBase("Coverage");
|
||||
sp.addComponent()
|
||||
.setExpression("Coverage")
|
||||
.setDefinition(new Reference("/SearchParameter/coverage-beneficiary"));
|
||||
sp.addComponent()
|
||||
.setExpression("Coverage")
|
||||
.setDefinition(new Reference("/SearchParameter/coverage-identifier"));
|
||||
sp.addExtension()
|
||||
.setUrl(JpaConstants.EXT_SP_UNIQUE)
|
||||
.setValue(new BooleanType(true));
|
||||
mySearchParameterDao.update(sp);
|
||||
mySearchParamRegsitry.forceRefresh();
|
||||
}
|
||||
|
||||
private void createUniqueIndexObservationSubject() {
|
||||
|
||||
SearchParameter sp = new SearchParameter();
|
||||
sp.setId("SearchParameter/observation-subject");
|
||||
sp.setCode("observation-subject");
|
||||
sp.setExpression("Observation.subject");
|
||||
sp.setType(Enumerations.SearchParamType.REFERENCE);
|
||||
sp.setStatus(PublicationStatus.ACTIVE);
|
||||
sp.addBase("Observation");
|
||||
mySearchParameterDao.update(sp);
|
||||
|
||||
sp = new SearchParameter();
|
||||
sp.setId("SearchParameter/observation-uniq-subject");
|
||||
sp.setCode("observation-uniq-subject");
|
||||
sp.setExpression("Observation.subject");
|
||||
sp.setType(Enumerations.SearchParamType.COMPOSITE);
|
||||
sp.setStatus(PublicationStatus.ACTIVE);
|
||||
sp.addBase("Observation");
|
||||
sp.addComponent()
|
||||
.setExpression("Observation")
|
||||
.setDefinition(new Reference("/SearchParameter/observation-subject"));
|
||||
sp.addExtension()
|
||||
.setUrl(JpaConstants.EXT_SP_UNIQUE)
|
||||
.setValue(new BooleanType(true));
|
||||
mySearchParameterDao.update(sp);
|
||||
mySearchParamRegsitry.forceRefresh();
|
||||
}
|
||||
|
||||
private void createUniqueIndexPatientIdentifier() {
|
||||
|
||||
SearchParameter sp = new SearchParameter();
|
||||
sp.setId("SearchParameter/patient-identifier");
|
||||
sp.setCode("identifier");
|
||||
sp.setExpression("Patient.identifier");
|
||||
sp.setType(Enumerations.SearchParamType.TOKEN);
|
||||
sp.setStatus(PublicationStatus.ACTIVE);
|
||||
sp.addBase("Patient");
|
||||
mySearchParameterDao.update(sp);
|
||||
|
||||
sp = new SearchParameter();
|
||||
sp.setId("SearchParameter/patient-uniq-identifier");
|
||||
sp.setCode("patient-uniq-identifier");
|
||||
sp.setExpression("Patient.identifier");
|
||||
sp.setType(Enumerations.SearchParamType.COMPOSITE);
|
||||
sp.setStatus(PublicationStatus.ACTIVE);
|
||||
sp.addBase("Patient");
|
||||
sp.addComponent()
|
||||
.setExpression("Patient")
|
||||
.setDefinition(new Reference("/SearchParameter/patient-identifier"));
|
||||
sp.addExtension()
|
||||
.setUrl(JpaConstants.EXT_SP_UNIQUE)
|
||||
.setValue(new BooleanType(true));
|
||||
mySearchParameterDao.update(sp);
|
||||
mySearchParamRegsitry.forceRefresh();
|
||||
}
|
||||
|
||||
private void createUniqueIndexPatientIdentifierCount1() {
|
||||
|
||||
SearchParameter sp = new SearchParameter();
|
||||
sp.setId("SearchParameter/patient-identifier");
|
||||
sp.setCode("first-identifier");
|
||||
sp.setExpression("Patient.identifier.first()");
|
||||
sp.setType(Enumerations.SearchParamType.TOKEN);
|
||||
sp.setStatus(PublicationStatus.ACTIVE);
|
||||
sp.addBase("Patient");
|
||||
mySearchParameterDao.update(sp);
|
||||
|
||||
sp = new SearchParameter();
|
||||
sp.setId("SearchParameter/patient-uniq-identifier");
|
||||
sp.setCode("patient-uniq-identifier");
|
||||
sp.setExpression("Patient.identifier");
|
||||
sp.setType(Enumerations.SearchParamType.COMPOSITE);
|
||||
sp.setStatus(PublicationStatus.ACTIVE);
|
||||
sp.addBase("Patient");
|
||||
sp.addComponent()
|
||||
.setExpression("Patient")
|
||||
.setDefinition(new Reference("/SearchParameter/patient-identifier"));
|
||||
sp.addExtension()
|
||||
.setUrl(JpaConstants.EXT_SP_UNIQUE)
|
||||
.setValue(new BooleanType(true));
|
||||
mySearchParameterDao.update(sp);
|
||||
mySearchParamRegsitry.forceRefresh();
|
||||
}
|
||||
|
||||
private void createUniqueNameAndManagingOrganizationSps() {
|
||||
SearchParameter sp = new SearchParameter();
|
||||
sp.setId("SearchParameter/patient-name");
|
||||
|
@ -215,6 +311,98 @@ public class FhirResourceDaoR4UniqueSearchParamTest extends BaseJpaR4Test {
|
|||
assertEquals("gender", params.get(0).getCompositeOf().get(1).getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDoubleMatching() {
|
||||
createUniqueIndexPatientIdentifier();
|
||||
|
||||
Patient pt = new Patient();
|
||||
pt.addIdentifier().setSystem("urn").setValue("111");
|
||||
pt.addIdentifier().setSystem("urn").setValue("222");
|
||||
|
||||
Bundle input = new Bundle();
|
||||
input.setType(Bundle.BundleType.TRANSACTION);
|
||||
input.addEntry()
|
||||
.setResource(pt)
|
||||
.setFullUrl("Patient")
|
||||
.getRequest()
|
||||
.setMethod(Bundle.HTTPVerb.POST)
|
||||
.setUrl("/Patient")
|
||||
.setIfNoneExist("/Patient?identifier=urn|111,urn|222");
|
||||
mySystemDao.transaction(mySrd, input);
|
||||
|
||||
myEntityManager.clear();
|
||||
|
||||
pt = new Patient();
|
||||
pt.setActive(true);
|
||||
pt.addIdentifier().setSystem("urn").setValue("111");
|
||||
pt.addIdentifier().setSystem("urn").setValue("222");
|
||||
|
||||
input = new Bundle();
|
||||
input.setType(Bundle.BundleType.TRANSACTION);
|
||||
input.addEntry()
|
||||
.setResource(pt)
|
||||
.setFullUrl("Patient")
|
||||
.getRequest()
|
||||
.setMethod(Bundle.HTTPVerb.POST)
|
||||
.setUrl("/Patient")
|
||||
.setIfNoneExist("/Patient?identifier=urn|111,urn|222");
|
||||
mySystemDao.transaction(mySrd, input);
|
||||
|
||||
new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
|
||||
@Override
|
||||
protected void doInTransactionWithoutResult(TransactionStatus status) {
|
||||
List<ResourceIndexedCompositeStringUnique> all = myResourceIndexedCompositeStringUniqueDao.findAll();
|
||||
assertEquals(2, all.size());
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDoubleMatchingPut() {
|
||||
createUniqueIndexPatientIdentifier();
|
||||
|
||||
Patient pt = new Patient();
|
||||
pt.addIdentifier().setSystem("urn").setValue("111");
|
||||
pt.addIdentifier().setSystem("urn").setValue("222");
|
||||
|
||||
Bundle input = new Bundle();
|
||||
input.setType(Bundle.BundleType.TRANSACTION);
|
||||
input.addEntry()
|
||||
.setResource(pt)
|
||||
.setFullUrl("Patient")
|
||||
.getRequest()
|
||||
.setMethod(Bundle.HTTPVerb.PUT)
|
||||
.setUrl("/Patient?identifier=urn|111,urn|222");
|
||||
mySystemDao.transaction(mySrd, input);
|
||||
|
||||
myEntityManager.clear();
|
||||
|
||||
pt = new Patient();
|
||||
pt.setActive(true);
|
||||
pt.addIdentifier().setSystem("urn").setValue("111");
|
||||
pt.addIdentifier().setSystem("urn").setValue("222");
|
||||
|
||||
input = new Bundle();
|
||||
input.setType(Bundle.BundleType.TRANSACTION);
|
||||
input.addEntry()
|
||||
.setResource(pt)
|
||||
.setFullUrl("Patient")
|
||||
.getRequest()
|
||||
.setMethod(Bundle.HTTPVerb.PUT)
|
||||
.setUrl("/Patient?identifier=urn|111,urn|222");
|
||||
mySystemDao.transaction(mySrd, input);
|
||||
|
||||
new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
|
||||
@Override
|
||||
protected void doInTransactionWithoutResult(TransactionStatus status) {
|
||||
List<ResourceIndexedCompositeStringUnique> all = myResourceIndexedCompositeStringUniqueDao.findAll();
|
||||
assertEquals(2, all.size());
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDuplicateUniqueValuesAreReIndexed() {
|
||||
|
||||
|
@ -302,305 +490,6 @@ public class FhirResourceDaoR4UniqueSearchParamTest extends BaseJpaR4Test {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchSynchronousUsingUniqueComposite() {
|
||||
createUniqueBirthdateAndGenderSps();
|
||||
|
||||
Patient pt1 = new Patient();
|
||||
pt1.setGender(Enumerations.AdministrativeGender.MALE);
|
||||
pt1.setBirthDateElement(new DateType("2011-01-01"));
|
||||
IIdType id1 = myPatientDao.create(pt1).getId().toUnqualifiedVersionless();
|
||||
|
||||
Patient pt2 = new Patient();
|
||||
pt2.setGender(Enumerations.AdministrativeGender.MALE);
|
||||
pt2.setBirthDateElement(new DateType("2011-01-02"));
|
||||
IIdType id2 = myPatientDao.create(pt2).getId().toUnqualifiedVersionless();
|
||||
|
||||
SearchBuilder.resetLastHandlerMechanismForUnitTest();
|
||||
SearchParameterMap params = new SearchParameterMap();
|
||||
params.setLoadSynchronousUpTo(100);
|
||||
params.add("gender", new TokenParam("http://hl7.org/fhir/administrative-gender", "male"));
|
||||
params.add("birthdate", new DateParam("2011-01-01"));
|
||||
IBundleProvider results = myPatientDao.search(params);
|
||||
assertThat(toUnqualifiedVersionlessIdValues(results), containsInAnyOrder(id1.getValue()));
|
||||
assertEquals(SearchBuilder.HandlerTypeEnum.UNIQUE_INDEX, SearchBuilder.getLastHandlerMechanismForUnitTest());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchUsingUniqueComposite() {
|
||||
createUniqueBirthdateAndGenderSps();
|
||||
|
||||
Patient pt1 = new Patient();
|
||||
pt1.setGender(Enumerations.AdministrativeGender.MALE);
|
||||
pt1.setBirthDateElement(new DateType("2011-01-01"));
|
||||
String id1 = myPatientDao.create(pt1).getId().toUnqualifiedVersionless().getValue();
|
||||
|
||||
Patient pt2 = new Patient();
|
||||
pt2.setGender(Enumerations.AdministrativeGender.MALE);
|
||||
pt2.setBirthDateElement(new DateType("2011-01-02"));
|
||||
IIdType id2 = myPatientDao.create(pt2).getId().toUnqualifiedVersionless();
|
||||
|
||||
SearchBuilder.resetLastHandlerMechanismForUnitTest();
|
||||
SearchParameterMap params = new SearchParameterMap();
|
||||
params.add("gender", new TokenParam("http://hl7.org/fhir/administrative-gender", "male"));
|
||||
params.add("birthdate", new DateParam("2011-01-01"));
|
||||
IBundleProvider results = myPatientDao.search(params);
|
||||
String searchId = results.getUuid();
|
||||
assertThat(toUnqualifiedVersionlessIdValues(results), containsInAnyOrder(id1));
|
||||
assertEquals(SearchBuilder.HandlerTypeEnum.UNIQUE_INDEX, SearchBuilder.getLastHandlerMechanismForUnitTest());
|
||||
|
||||
// Other order
|
||||
SearchBuilder.resetLastHandlerMechanismForUnitTest();
|
||||
params = new SearchParameterMap();
|
||||
params.add("birthdate", new DateParam("2011-01-01"));
|
||||
params.add("gender", new TokenParam("http://hl7.org/fhir/administrative-gender", "male"));
|
||||
results = myPatientDao.search(params);
|
||||
assertEquals(searchId, results.getUuid());
|
||||
assertThat(toUnqualifiedVersionlessIdValues(results), containsInAnyOrder(id1));
|
||||
// Null because we just reuse the last search
|
||||
assertEquals(null, SearchBuilder.getLastHandlerMechanismForUnitTest());
|
||||
|
||||
SearchBuilder.resetLastHandlerMechanismForUnitTest();
|
||||
params = new SearchParameterMap();
|
||||
params.add("gender", new TokenParam("http://hl7.org/fhir/administrative-gender", "male"));
|
||||
params.add("birthdate", new DateParam("2011-01-03"));
|
||||
results = myPatientDao.search(params);
|
||||
assertThat(toUnqualifiedVersionlessIdValues(results), empty());
|
||||
assertEquals(SearchBuilder.HandlerTypeEnum.UNIQUE_INDEX, SearchBuilder.getLastHandlerMechanismForUnitTest());
|
||||
|
||||
SearchBuilder.resetLastHandlerMechanismForUnitTest();
|
||||
params = new SearchParameterMap();
|
||||
params.add("birthdate", new DateParam("2011-01-03"));
|
||||
results = myPatientDao.search(params);
|
||||
assertThat(toUnqualifiedVersionlessIdValues(results), empty());
|
||||
assertEquals(SearchBuilder.HandlerTypeEnum.STANDARD_QUERY, SearchBuilder.getLastHandlerMechanismForUnitTest());
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void createUniqueIndexCoverageBeneficiary() {
|
||||
SearchParameter sp = new SearchParameter();
|
||||
sp.setId("SearchParameter/coverage-beneficiary");
|
||||
sp.setCode("beneficiary");
|
||||
sp.setExpression("Coverage.beneficiary");
|
||||
sp.setType(Enumerations.SearchParamType.REFERENCE);
|
||||
sp.setStatus(PublicationStatus.ACTIVE);
|
||||
sp.addBase("Coverage");
|
||||
mySearchParameterDao.update(sp);
|
||||
|
||||
sp = new SearchParameter();
|
||||
sp.setId("SearchParameter/coverage-identifier");
|
||||
sp.setCode("identifier");
|
||||
sp.setExpression("Coverage.identifier");
|
||||
sp.setType(Enumerations.SearchParamType.TOKEN);
|
||||
sp.setStatus(PublicationStatus.ACTIVE);
|
||||
sp.addBase("Coverage");
|
||||
mySearchParameterDao.update(sp);
|
||||
|
||||
sp = new SearchParameter();
|
||||
sp.setId("SearchParameter/coverage-beneficiary-identifier");
|
||||
sp.setCode("coverage-beneficiary-identifier");
|
||||
sp.setExpression("Coverage.beneficiary");
|
||||
sp.setType(Enumerations.SearchParamType.COMPOSITE);
|
||||
sp.setStatus(PublicationStatus.ACTIVE);
|
||||
sp.addBase("Coverage");
|
||||
sp.addComponent()
|
||||
.setExpression("Coverage")
|
||||
.setDefinition(new Reference("/SearchParameter/coverage-beneficiary"));
|
||||
sp.addComponent()
|
||||
.setExpression("Coverage")
|
||||
.setDefinition(new Reference("/SearchParameter/coverage-identifier"));
|
||||
sp.addExtension()
|
||||
.setUrl(JpaConstants.EXT_SP_UNIQUE)
|
||||
.setValue(new BooleanType(true));
|
||||
mySearchParameterDao.update(sp);
|
||||
mySearchParamRegsitry.forceRefresh();
|
||||
}
|
||||
|
||||
private void createUniqueIndexPatientIdentifier() {
|
||||
|
||||
SearchParameter sp = new SearchParameter();
|
||||
sp.setId("SearchParameter/patient-identifier");
|
||||
sp.setCode("identifier");
|
||||
sp.setExpression("Patient.identifier");
|
||||
sp.setType(Enumerations.SearchParamType.TOKEN);
|
||||
sp.setStatus(PublicationStatus.ACTIVE);
|
||||
sp.addBase("Patient");
|
||||
mySearchParameterDao.update(sp);
|
||||
|
||||
sp = new SearchParameter();
|
||||
sp.setId("SearchParameter/patient-uniq-identifier");
|
||||
sp.setCode("patient-uniq-identifier");
|
||||
sp.setExpression("Patient.identifier");
|
||||
sp.setType(Enumerations.SearchParamType.COMPOSITE);
|
||||
sp.setStatus(PublicationStatus.ACTIVE);
|
||||
sp.addBase("Patient");
|
||||
sp.addComponent()
|
||||
.setExpression("Patient")
|
||||
.setDefinition(new Reference("/SearchParameter/patient-identifier"));
|
||||
sp.addExtension()
|
||||
.setUrl(JpaConstants.EXT_SP_UNIQUE)
|
||||
.setValue(new BooleanType(true));
|
||||
mySearchParameterDao.update(sp);
|
||||
mySearchParamRegsitry.forceRefresh();
|
||||
}
|
||||
|
||||
private void createUniqueIndexPatientIdentifierCount1() {
|
||||
|
||||
SearchParameter sp = new SearchParameter();
|
||||
sp.setId("SearchParameter/patient-identifier");
|
||||
sp.setCode("first-identifier");
|
||||
sp.setExpression("Patient.identifier.first()");
|
||||
sp.setType(Enumerations.SearchParamType.TOKEN);
|
||||
sp.setStatus(PublicationStatus.ACTIVE);
|
||||
sp.addBase("Patient");
|
||||
mySearchParameterDao.update(sp);
|
||||
|
||||
sp = new SearchParameter();
|
||||
sp.setId("SearchParameter/patient-uniq-identifier");
|
||||
sp.setCode("patient-uniq-identifier");
|
||||
sp.setExpression("Patient.identifier");
|
||||
sp.setType(Enumerations.SearchParamType.COMPOSITE);
|
||||
sp.setStatus(PublicationStatus.ACTIVE);
|
||||
sp.addBase("Patient");
|
||||
sp.addComponent()
|
||||
.setExpression("Patient")
|
||||
.setDefinition(new Reference("/SearchParameter/patient-identifier"));
|
||||
sp.addExtension()
|
||||
.setUrl(JpaConstants.EXT_SP_UNIQUE)
|
||||
.setValue(new BooleanType(true));
|
||||
mySearchParameterDao.update(sp);
|
||||
mySearchParamRegsitry.forceRefresh();
|
||||
}
|
||||
|
||||
private void createUniqueIndexObservationSubject() {
|
||||
|
||||
SearchParameter sp = new SearchParameter();
|
||||
sp.setId("SearchParameter/observation-subject");
|
||||
sp.setCode("observation-subject");
|
||||
sp.setExpression("Observation.subject");
|
||||
sp.setType(Enumerations.SearchParamType.REFERENCE);
|
||||
sp.setStatus(PublicationStatus.ACTIVE);
|
||||
sp.addBase("Observation");
|
||||
mySearchParameterDao.update(sp);
|
||||
|
||||
sp = new SearchParameter();
|
||||
sp.setId("SearchParameter/observation-uniq-subject");
|
||||
sp.setCode("observation-uniq-subject");
|
||||
sp.setExpression("Observation.subject");
|
||||
sp.setType(Enumerations.SearchParamType.COMPOSITE);
|
||||
sp.setStatus(PublicationStatus.ACTIVE);
|
||||
sp.addBase("Observation");
|
||||
sp.addComponent()
|
||||
.setExpression("Observation")
|
||||
.setDefinition(new Reference("/SearchParameter/observation-subject"));
|
||||
sp.addExtension()
|
||||
.setUrl(JpaConstants.EXT_SP_UNIQUE)
|
||||
.setValue(new BooleanType(true));
|
||||
mySearchParameterDao.update(sp);
|
||||
mySearchParamRegsitry.forceRefresh();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIndexTransactionWithMatchUrl() {
|
||||
Patient pt2 = new Patient();
|
||||
pt2.setGender(Enumerations.AdministrativeGender.MALE);
|
||||
pt2.setBirthDateElement(new DateType("2011-01-02"));
|
||||
IIdType id2 = myPatientDao.create(pt2).getId().toUnqualifiedVersionless();
|
||||
|
||||
Coverage cov = new Coverage();
|
||||
cov.getBeneficiary().setReference(id2.getValue());
|
||||
cov.addIdentifier().setSystem("urn:foo:bar").setValue("123");
|
||||
IIdType id3 = myCoverageDao.create(cov).getId().toUnqualifiedVersionless();
|
||||
|
||||
createUniqueIndexCoverageBeneficiary();
|
||||
|
||||
mySystemDao.markAllResourcesForReindexing();
|
||||
mySystemDao.performReindexingPass(1000);
|
||||
|
||||
List<ResourceIndexedCompositeStringUnique> uniques = myResourceIndexedCompositeStringUniqueDao.findAll();
|
||||
assertEquals(uniques.toString(), 1, uniques.size());
|
||||
assertEquals("Coverage/" + id3.getIdPart(), uniques.get(0).getResource().getIdDt().toUnqualifiedVersionless().getValue());
|
||||
assertEquals("Coverage?beneficiary=Patient%2F" + id2.getIdPart() + "&identifier=urn%3Afoo%3Abar%7C123", uniques.get(0).getIndexString());
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDoubleMatching() {
|
||||
createUniqueIndexPatientIdentifier();
|
||||
|
||||
Patient pt = new Patient();
|
||||
pt.addIdentifier().setSystem("urn").setValue("111");
|
||||
pt.addIdentifier().setSystem("urn").setValue("222");
|
||||
|
||||
Bundle input = new Bundle();
|
||||
input.setType(Bundle.BundleType.TRANSACTION);
|
||||
input.addEntry()
|
||||
.setResource(pt)
|
||||
.setFullUrl("Patient")
|
||||
.getRequest()
|
||||
.setMethod(Bundle.HTTPVerb.POST)
|
||||
.setUrl("/Patient")
|
||||
.setIfNoneExist("/Patient?identifier=urn|111,urn|222");
|
||||
mySystemDao.transaction(mySrd, input);
|
||||
|
||||
myEntityManager.clear();
|
||||
|
||||
pt = new Patient();
|
||||
pt.setActive(true);
|
||||
pt.addIdentifier().setSystem("urn").setValue("111");
|
||||
pt.addIdentifier().setSystem("urn").setValue("222");
|
||||
|
||||
input = new Bundle();
|
||||
input.setType(Bundle.BundleType.TRANSACTION);
|
||||
input.addEntry()
|
||||
.setResource(pt)
|
||||
.setFullUrl("Patient")
|
||||
.getRequest()
|
||||
.setMethod(Bundle.HTTPVerb.POST)
|
||||
.setUrl("/Patient")
|
||||
.setIfNoneExist("/Patient?identifier=urn|111,urn|222");
|
||||
mySystemDao.transaction(mySrd, input);
|
||||
|
||||
new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
|
||||
@Override
|
||||
protected void doInTransactionWithoutResult(TransactionStatus status) {
|
||||
List<ResourceIndexedCompositeStringUnique> all = myResourceIndexedCompositeStringUniqueDao.findAll();
|
||||
assertEquals(2, all.size());
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testObservationSubject() {
|
||||
createUniqueIndexObservationSubject();
|
||||
|
||||
Patient pt = new Patient();
|
||||
pt.addIdentifier().setSystem("urn").setValue("111");
|
||||
pt.addIdentifier().setSystem("urn").setValue("222");
|
||||
IIdType ptid = myPatientDao.create(pt).getId().toUnqualifiedVersionless();
|
||||
|
||||
Encounter enc = new Encounter();
|
||||
enc.setSubject(new Reference(ptid));
|
||||
IIdType encid = myEncounterDao.create(enc).getId().toUnqualifiedVersionless();
|
||||
|
||||
Observation obs = new Observation();
|
||||
obs.setSubject(new Reference(ptid));
|
||||
obs.setContext(new Reference(encid));
|
||||
myObservationDao.create(obs);
|
||||
|
||||
new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
|
||||
@Override
|
||||
protected void doInTransactionWithoutResult(TransactionStatus status) {
|
||||
List<ResourceIndexedCompositeStringUnique> all = myResourceIndexedCompositeStringUniqueDao.findAll();
|
||||
assertEquals(all.toString(), 1, all.size());
|
||||
}
|
||||
});
|
||||
|
||||
}er
|
||||
|
||||
@Test
|
||||
public void testIndexFirstMatchOnly() {
|
||||
createUniqueIndexPatientIdentifierCount1();
|
||||
|
@ -635,49 +524,28 @@ public class FhirResourceDaoR4UniqueSearchParamTest extends BaseJpaR4Test {
|
|||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testDoubleMatchingPut() {
|
||||
createUniqueIndexPatientIdentifier();
|
||||
public void testIndexTransactionWithMatchUrl() {
|
||||
Patient pt2 = new Patient();
|
||||
pt2.setGender(Enumerations.AdministrativeGender.MALE);
|
||||
pt2.setBirthDateElement(new DateType("2011-01-02"));
|
||||
IIdType id2 = myPatientDao.create(pt2).getId().toUnqualifiedVersionless();
|
||||
|
||||
Patient pt = new Patient();
|
||||
pt.addIdentifier().setSystem("urn").setValue("111");
|
||||
pt.addIdentifier().setSystem("urn").setValue("222");
|
||||
Coverage cov = new Coverage();
|
||||
cov.getBeneficiary().setReference(id2.getValue());
|
||||
cov.addIdentifier().setSystem("urn:foo:bar").setValue("123");
|
||||
IIdType id3 = myCoverageDao.create(cov).getId().toUnqualifiedVersionless();
|
||||
|
||||
Bundle input = new Bundle();
|
||||
input.setType(Bundle.BundleType.TRANSACTION);
|
||||
input.addEntry()
|
||||
.setResource(pt)
|
||||
.setFullUrl("Patient")
|
||||
.getRequest()
|
||||
.setMethod(Bundle.HTTPVerb.PUT)
|
||||
.setUrl("/Patient?identifier=urn|111,urn|222");
|
||||
mySystemDao.transaction(mySrd, input);
|
||||
createUniqueIndexCoverageBeneficiary();
|
||||
|
||||
myEntityManager.clear();
|
||||
mySystemDao.markAllResourcesForReindexing();
|
||||
mySystemDao.performReindexingPass(1000);
|
||||
|
||||
pt = new Patient();
|
||||
pt.setActive(true);
|
||||
pt.addIdentifier().setSystem("urn").setValue("111");
|
||||
pt.addIdentifier().setSystem("urn").setValue("222");
|
||||
List<ResourceIndexedCompositeStringUnique> uniques = myResourceIndexedCompositeStringUniqueDao.findAll();
|
||||
assertEquals(uniques.toString(), 1, uniques.size());
|
||||
assertEquals("Coverage/" + id3.getIdPart(), uniques.get(0).getResource().getIdDt().toUnqualifiedVersionless().getValue());
|
||||
assertEquals("Coverage?beneficiary=Patient%2F" + id2.getIdPart() + "&identifier=urn%3Afoo%3Abar%7C123", uniques.get(0).getIndexString());
|
||||
|
||||
input = new Bundle();
|
||||
input.setType(Bundle.BundleType.TRANSACTION);
|
||||
input.addEntry()
|
||||
.setResource(pt)
|
||||
.setFullUrl("Patient")
|
||||
.getRequest()
|
||||
.setMethod(Bundle.HTTPVerb.PUT)
|
||||
.setUrl("/Patient?identifier=urn|111,urn|222");
|
||||
mySystemDao.transaction(mySrd, input);
|
||||
|
||||
new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
|
||||
@Override
|
||||
protected void doInTransactionWithoutResult(TransactionStatus status) {
|
||||
List<ResourceIndexedCompositeStringUnique> all = myResourceIndexedCompositeStringUniqueDao.findAll();
|
||||
assertEquals(2, all.size());
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
@ -791,6 +659,134 @@ public class FhirResourceDaoR4UniqueSearchParamTest extends BaseJpaR4Test {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNonTransaction() {
|
||||
createUniqueBirthdateAndGenderSps();
|
||||
|
||||
Patient p = new Patient();
|
||||
p.setGender(Enumerations.AdministrativeGender.MALE);
|
||||
p.setBirthDateElement(new DateType("2001-01-01"));
|
||||
|
||||
Bundle input = new Bundle();
|
||||
input.setType(Bundle.BundleType.TRANSACTION);
|
||||
input.addEntry()
|
||||
.setResource(p)
|
||||
.setFullUrl("Patient")
|
||||
.getRequest()
|
||||
.setMethod(Bundle.HTTPVerb.POST)
|
||||
.setUrl("/Patient")
|
||||
.setIfNoneExist("Patient?gender=http%3A%2F%2Fhl7.org%2Ffhir%2Fadministrative-gender%7Cmale&birthdate=2001-01-01");
|
||||
|
||||
Bundle output0 = mySystemDao.transaction(mySrd, input);
|
||||
Bundle output1 = mySystemDao.transaction(mySrd, input);
|
||||
assertEquals(output1.getEntry().get(0).getFullUrl(), output0.getEntry().get(0).getFullUrl());
|
||||
Bundle output2 = mySystemDao.transaction(mySrd, input);
|
||||
assertEquals(output2.getEntry().get(0).getFullUrl(), output0.getEntry().get(0).getFullUrl());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testObservationSubject() {
|
||||
createUniqueIndexObservationSubject();
|
||||
|
||||
Patient pt = new Patient();
|
||||
pt.addIdentifier().setSystem("urn").setValue("111");
|
||||
pt.addIdentifier().setSystem("urn").setValue("222");
|
||||
IIdType ptid = myPatientDao.create(pt).getId().toUnqualifiedVersionless();
|
||||
|
||||
Encounter enc = new Encounter();
|
||||
enc.setSubject(new Reference(ptid));
|
||||
IIdType encid = myEncounterDao.create(enc).getId().toUnqualifiedVersionless();
|
||||
|
||||
Observation obs = new Observation();
|
||||
obs.setSubject(new Reference(ptid));
|
||||
obs.setContext(new Reference(encid));
|
||||
myObservationDao.create(obs);
|
||||
|
||||
new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
|
||||
@Override
|
||||
protected void doInTransactionWithoutResult(TransactionStatus status) {
|
||||
List<ResourceIndexedCompositeStringUnique> all = myResourceIndexedCompositeStringUniqueDao.findAll();
|
||||
assertEquals(all.toString(), 1, all.size());
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchSynchronousUsingUniqueComposite() {
|
||||
createUniqueBirthdateAndGenderSps();
|
||||
|
||||
Patient pt1 = new Patient();
|
||||
pt1.setGender(Enumerations.AdministrativeGender.MALE);
|
||||
pt1.setBirthDateElement(new DateType("2011-01-01"));
|
||||
IIdType id1 = myPatientDao.create(pt1).getId().toUnqualifiedVersionless();
|
||||
|
||||
Patient pt2 = new Patient();
|
||||
pt2.setGender(Enumerations.AdministrativeGender.MALE);
|
||||
pt2.setBirthDateElement(new DateType("2011-01-02"));
|
||||
IIdType id2 = myPatientDao.create(pt2).getId().toUnqualifiedVersionless();
|
||||
|
||||
SearchBuilder.resetLastHandlerMechanismForUnitTest();
|
||||
SearchParameterMap params = new SearchParameterMap();
|
||||
params.setLoadSynchronousUpTo(100);
|
||||
params.add("gender", new TokenParam("http://hl7.org/fhir/administrative-gender", "male"));
|
||||
params.add("birthdate", new DateParam("2011-01-01"));
|
||||
IBundleProvider results = myPatientDao.search(params);
|
||||
assertThat(toUnqualifiedVersionlessIdValues(results), containsInAnyOrder(id1.getValue()));
|
||||
assertEquals(SearchBuilder.HandlerTypeEnum.UNIQUE_INDEX, SearchBuilder.getLastHandlerMechanismForUnitTest());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchUsingUniqueComposite() {
|
||||
createUniqueBirthdateAndGenderSps();
|
||||
|
||||
Patient pt1 = new Patient();
|
||||
pt1.setGender(Enumerations.AdministrativeGender.MALE);
|
||||
pt1.setBirthDateElement(new DateType("2011-01-01"));
|
||||
String id1 = myPatientDao.create(pt1).getId().toUnqualifiedVersionless().getValue();
|
||||
|
||||
Patient pt2 = new Patient();
|
||||
pt2.setGender(Enumerations.AdministrativeGender.MALE);
|
||||
pt2.setBirthDateElement(new DateType("2011-01-02"));
|
||||
IIdType id2 = myPatientDao.create(pt2).getId().toUnqualifiedVersionless();
|
||||
|
||||
SearchBuilder.resetLastHandlerMechanismForUnitTest();
|
||||
SearchParameterMap params = new SearchParameterMap();
|
||||
params.add("gender", new TokenParam("http://hl7.org/fhir/administrative-gender", "male"));
|
||||
params.add("birthdate", new DateParam("2011-01-01"));
|
||||
IBundleProvider results = myPatientDao.search(params);
|
||||
String searchId = results.getUuid();
|
||||
assertThat(toUnqualifiedVersionlessIdValues(results), containsInAnyOrder(id1));
|
||||
assertEquals(SearchBuilder.HandlerTypeEnum.UNIQUE_INDEX, SearchBuilder.getLastHandlerMechanismForUnitTest());
|
||||
|
||||
// Other order
|
||||
SearchBuilder.resetLastHandlerMechanismForUnitTest();
|
||||
params = new SearchParameterMap();
|
||||
params.add("birthdate", new DateParam("2011-01-01"));
|
||||
params.add("gender", new TokenParam("http://hl7.org/fhir/administrative-gender", "male"));
|
||||
results = myPatientDao.search(params);
|
||||
assertEquals(searchId, results.getUuid());
|
||||
assertThat(toUnqualifiedVersionlessIdValues(results), containsInAnyOrder(id1));
|
||||
// Null because we just reuse the last search
|
||||
assertEquals(null, SearchBuilder.getLastHandlerMechanismForUnitTest());
|
||||
|
||||
SearchBuilder.resetLastHandlerMechanismForUnitTest();
|
||||
params = new SearchParameterMap();
|
||||
params.add("gender", new TokenParam("http://hl7.org/fhir/administrative-gender", "male"));
|
||||
params.add("birthdate", new DateParam("2011-01-03"));
|
||||
results = myPatientDao.search(params);
|
||||
assertThat(toUnqualifiedVersionlessIdValues(results), empty());
|
||||
assertEquals(SearchBuilder.HandlerTypeEnum.UNIQUE_INDEX, SearchBuilder.getLastHandlerMechanismForUnitTest());
|
||||
|
||||
SearchBuilder.resetLastHandlerMechanismForUnitTest();
|
||||
params = new SearchParameterMap();
|
||||
params.add("birthdate", new DateParam("2011-01-03"));
|
||||
results = myPatientDao.search(params);
|
||||
assertThat(toUnqualifiedVersionlessIdValues(results), empty());
|
||||
assertEquals(SearchBuilder.HandlerTypeEnum.STANDARD_QUERY, SearchBuilder.getLastHandlerMechanismForUnitTest());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUniqueValuesAreIndexed_DateAndToken() {
|
||||
|
@ -837,38 +833,6 @@ public class FhirResourceDaoR4UniqueSearchParamTest extends BaseJpaR4Test {
|
|||
assertEquals("Observation?code=foo%7Cbar&date=2011-01-01&subject=Patient%2F" + id1.getIdPart(), uniques.get(0).getIndexString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUniqueValuesAreIndexed_StringAndReference() {
|
||||
createUniqueNameAndManagingOrganizationSps();
|
||||
|
||||
Organization org = new Organization();
|
||||
org.setId("Organization/ORG");
|
||||
org.setName("ORG");
|
||||
myOrganizationDao.update(org);
|
||||
|
||||
Patient pt1 = new Patient();
|
||||
pt1.addName()
|
||||
.setFamily("FAMILY1")
|
||||
.addGiven("GIVEN1")
|
||||
.addGiven("GIVEN2")
|
||||
.addGiven("GIVEN2"); // GIVEN2 happens twice
|
||||
pt1.setManagingOrganization(new Reference("Organization/ORG"));
|
||||
IIdType id1 = myPatientDao.create(pt1).getId().toUnqualifiedVersionless();
|
||||
|
||||
List<ResourceIndexedCompositeStringUnique> uniques = myResourceIndexedCompositeStringUniqueDao.findAll();
|
||||
Collections.sort(uniques);
|
||||
|
||||
assertEquals(3, uniques.size());
|
||||
assertEquals("Patient/" + id1.getIdPart(), uniques.get(0).getResource().getIdDt().toUnqualifiedVersionless().getValue());
|
||||
assertEquals("Patient?name=FAMILY1&organization=Organization%2FORG", uniques.get(0).getIndexString());
|
||||
|
||||
assertEquals("Patient/" + id1.getIdPart(), uniques.get(1).getResource().getIdDt().toUnqualifiedVersionless().getValue());
|
||||
assertEquals("Patient?name=GIVEN1&organization=Organization%2FORG", uniques.get(1).getIndexString());
|
||||
|
||||
assertEquals("Patient/" + id1.getIdPart(), uniques.get(2).getResource().getIdDt().toUnqualifiedVersionless().getValue());
|
||||
assertEquals("Patient?name=GIVEN2&organization=Organization%2FORG", uniques.get(2).getIndexString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUniqueValuesAreIndexed_Reference_UsingModifierSyntax() {
|
||||
createUniqueNameAndManagingOrganizationSps();
|
||||
|
@ -907,6 +871,37 @@ public class FhirResourceDaoR4UniqueSearchParamTest extends BaseJpaR4Test {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUniqueValuesAreIndexed_StringAndReference() {
|
||||
createUniqueNameAndManagingOrganizationSps();
|
||||
|
||||
Organization org = new Organization();
|
||||
org.setId("Organization/ORG");
|
||||
org.setName("ORG");
|
||||
myOrganizationDao.update(org);
|
||||
|
||||
Patient pt1 = new Patient();
|
||||
pt1.addName()
|
||||
.setFamily("FAMILY1")
|
||||
.addGiven("GIVEN1")
|
||||
.addGiven("GIVEN2")
|
||||
.addGiven("GIVEN2"); // GIVEN2 happens twice
|
||||
pt1.setManagingOrganization(new Reference("Organization/ORG"));
|
||||
IIdType id1 = myPatientDao.create(pt1).getId().toUnqualifiedVersionless();
|
||||
|
||||
List<ResourceIndexedCompositeStringUnique> uniques = myResourceIndexedCompositeStringUniqueDao.findAll();
|
||||
Collections.sort(uniques);
|
||||
|
||||
assertEquals(3, uniques.size());
|
||||
assertEquals("Patient/" + id1.getIdPart(), uniques.get(0).getResource().getIdDt().toUnqualifiedVersionless().getValue());
|
||||
assertEquals("Patient?name=FAMILY1&organization=Organization%2FORG", uniques.get(0).getIndexString());
|
||||
|
||||
assertEquals("Patient/" + id1.getIdPart(), uniques.get(1).getResource().getIdDt().toUnqualifiedVersionless().getValue());
|
||||
assertEquals("Patient?name=GIVEN1&organization=Organization%2FORG", uniques.get(1).getIndexString());
|
||||
|
||||
assertEquals("Patient/" + id1.getIdPart(), uniques.get(2).getResource().getIdDt().toUnqualifiedVersionless().getValue());
|
||||
assertEquals("Patient?name=GIVEN2&organization=Organization%2FORG", uniques.get(2).getIndexString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUniqueValuesAreIndexed_StringAndReference_UsingConditional() {
|
||||
|
|
Loading…
Reference in New Issue