It should not be possible to search for deleted resources using the _tag, _id, _profile, or _security search parameters

This commit is contained in:
jamesagnew 2015-09-13 09:42:41 -04:00
parent 48ee2cbee8
commit 780fc871cb
14 changed files with 810 additions and 581 deletions

View File

@ -533,6 +533,7 @@ public class JsonParser extends BaseParser implements IParser {
INarrativeGenerator gen = myContext.getNarrativeGenerator(); INarrativeGenerator gen = myContext.getNarrativeGenerator();
if (gen != null) { if (gen != null) {
BaseNarrativeDt<?> narr = ((IResource) theResource).getText(); BaseNarrativeDt<?> narr = ((IResource) theResource).getText();
if (narr.getDiv().isEmpty()) {
gen.generateNarrative(theResDef.getResourceProfile(), theResource, narr); gen.generateNarrative(theResDef.getResourceProfile(), theResource, narr);
if (narr != null && !narr.isEmpty()) { if (narr != null && !narr.isEmpty()) {
RuntimeChildNarrativeDefinition child = (RuntimeChildNarrativeDefinition) nextChild; RuntimeChildNarrativeDefinition child = (RuntimeChildNarrativeDefinition) nextChild;
@ -542,6 +543,7 @@ public class JsonParser extends BaseParser implements IParser {
continue; continue;
} }
} }
}
} else if (nextChild instanceof RuntimeChildContainedResources) { } else if (nextChild instanceof RuntimeChildContainedResources) {
String childName = nextChild.getValidChildNames().iterator().next(); String childName = nextChild.getValidChildNames().iterator().next();
BaseRuntimeElementDefinition<?> child = nextChild.getChildByName(childName); BaseRuntimeElementDefinition<?> child = nextChild.getChildByName(childName);
@ -1237,7 +1239,6 @@ public class JsonParser extends BaseParser implements IParser {
// theState.endingElement(); // theState.endingElement();
// } // }
@Override @Override
public TagList parseTagList(Reader theReader) { public TagList parseTagList(Reader theReader) {
JsonReader reader = Json.createReader(theReader); JsonReader reader = Json.createReader(theReader);

View File

@ -2,6 +2,7 @@ package ca.uhn.fhir.cli;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.List; import java.util.List;
import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.CommandLine;
@ -16,6 +17,8 @@ public class App {
static { static {
ourCommands = new ArrayList<BaseCommand>(); ourCommands = new ArrayList<BaseCommand>();
ourCommands.add(new RunServerCommand()); ourCommands.add(new RunServerCommand());
Collections.sort(ourCommands);
} }
public static void main(String[] theArgs) { public static void main(String[] theArgs) {

View File

@ -7,7 +7,7 @@ import org.apache.commons.cli.ParseException;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.rest.client.IGenericClient; import ca.uhn.fhir.rest.client.IGenericClient;
public class BaseCommand { public abstract class BaseCommand implements Comparable<BaseCommand> {
public BaseCommand() { public BaseCommand() {
super(); super();
@ -18,18 +18,15 @@ public class BaseCommand {
return fhirClient; return fhirClient;
} }
public Options getOptions() { public abstract Options getOptions();
return null;
}
public String getCommandName() { public abstract String getCommandName();
// TODO Auto-generated method stub
return null;
}
public void run(CommandLine theCommandLine) throws ParseException { public abstract void run(CommandLine theCommandLine) throws ParseException;
// TODO Auto-generated method stub
@Override
public int compareTo(BaseCommand theO) {
return getCommandName().compareTo(theO.getCommandName());
} }
} }

View File

@ -1068,46 +1068,46 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
protected ResourceTable updateEntity(final IResource theResource, ResourceTable entity, boolean theUpdateHistory, Date theDeletedTimestampOrNull, boolean thePerformIndexing, boolean theUpdateVersion) { protected ResourceTable updateEntity(final IResource theResource, ResourceTable theEntity, boolean theUpdateHistory, Date theDeletedTimestampOrNull, boolean thePerformIndexing, boolean theUpdateVersion) {
if (entity.getPublished() == null) { if (theEntity.getPublished() == null) {
entity.setPublished(new Date()); theEntity.setPublished(new Date());
} }
if (theResource != null) { if (theResource != null) {
validateResourceForStorage((T) theResource); validateResourceForStorage((T) theResource);
String resourceType = myContext.getResourceDefinition(theResource).getName(); String resourceType = myContext.getResourceDefinition(theResource).getName();
if (isNotBlank(entity.getResourceType()) && !entity.getResourceType().equals(resourceType)) { if (isNotBlank(theEntity.getResourceType()) && !theEntity.getResourceType().equals(resourceType)) {
throw new UnprocessableEntityException("Existing resource ID[" + entity.getIdDt().toUnqualifiedVersionless() + "] is of type[" + entity.getResourceType() + "] - Cannot update with [" + resourceType + "]"); throw new UnprocessableEntityException("Existing resource ID[" + theEntity.getIdDt().toUnqualifiedVersionless() + "] is of type[" + theEntity.getResourceType() + "] - Cannot update with [" + resourceType + "]");
} }
} }
if (theUpdateHistory) { if (theUpdateHistory) {
final ResourceHistoryTable historyEntry = entity.toHistory(); final ResourceHistoryTable historyEntry = theEntity.toHistory();
myEntityManager.persist(historyEntry); myEntityManager.persist(historyEntry);
} }
if (theUpdateVersion) { if (theUpdateVersion) {
entity.setVersion(entity.getVersion() + 1); theEntity.setVersion(theEntity.getVersion() + 1);
} }
boolean paramsStringPopulated = entity.isParamsStringPopulated(); boolean paramsStringPopulated = theEntity.isParamsStringPopulated();
boolean paramsTokenPopulated = entity.isParamsTokenPopulated(); boolean paramsTokenPopulated = theEntity.isParamsTokenPopulated();
boolean paramsNumberPopulated = entity.isParamsNumberPopulated(); boolean paramsNumberPopulated = theEntity.isParamsNumberPopulated();
boolean paramsQuantityPopulated = entity.isParamsQuantityPopulated(); boolean paramsQuantityPopulated = theEntity.isParamsQuantityPopulated();
boolean paramsDatePopulated = entity.isParamsDatePopulated(); boolean paramsDatePopulated = theEntity.isParamsDatePopulated();
boolean paramsCoordsPopulated = entity.isParamsCoordsPopulated(); boolean paramsCoordsPopulated = theEntity.isParamsCoordsPopulated();
boolean paramsUriPopulated = entity.isParamsUriPopulated(); boolean paramsUriPopulated = theEntity.isParamsUriPopulated();
boolean hasLinks = entity.isHasLinks(); boolean hasLinks = theEntity.isHasLinks();
Collection<ResourceIndexedSearchParamString> paramsString = new ArrayList<ResourceIndexedSearchParamString>(entity.getParamsString()); Collection<ResourceIndexedSearchParamString> paramsString = new ArrayList<ResourceIndexedSearchParamString>(theEntity.getParamsString());
Collection<ResourceIndexedSearchParamToken> paramsToken = new ArrayList<ResourceIndexedSearchParamToken>(entity.getParamsToken()); Collection<ResourceIndexedSearchParamToken> paramsToken = new ArrayList<ResourceIndexedSearchParamToken>(theEntity.getParamsToken());
Collection<ResourceIndexedSearchParamNumber> paramsNumber = new ArrayList<ResourceIndexedSearchParamNumber>(entity.getParamsNumber()); Collection<ResourceIndexedSearchParamNumber> paramsNumber = new ArrayList<ResourceIndexedSearchParamNumber>(theEntity.getParamsNumber());
Collection<ResourceIndexedSearchParamQuantity> paramsQuantity = new ArrayList<ResourceIndexedSearchParamQuantity>(entity.getParamsQuantity()); Collection<ResourceIndexedSearchParamQuantity> paramsQuantity = new ArrayList<ResourceIndexedSearchParamQuantity>(theEntity.getParamsQuantity());
Collection<ResourceIndexedSearchParamDate> paramsDate = new ArrayList<ResourceIndexedSearchParamDate>(entity.getParamsDate()); Collection<ResourceIndexedSearchParamDate> paramsDate = new ArrayList<ResourceIndexedSearchParamDate>(theEntity.getParamsDate());
Collection<ResourceIndexedSearchParamUri> paramsUri = new ArrayList<ResourceIndexedSearchParamUri>(entity.getParamsUri()); Collection<ResourceIndexedSearchParamUri> paramsUri = new ArrayList<ResourceIndexedSearchParamUri>(theEntity.getParamsUri());
Collection<ResourceIndexedSearchParamCoords> paramsCoords = new ArrayList<ResourceIndexedSearchParamCoords>(entity.getParamsCoords()); Collection<ResourceIndexedSearchParamCoords> paramsCoords = new ArrayList<ResourceIndexedSearchParamCoords>(theEntity.getParamsCoords());
Collection<ResourceLink> resourceLinks = new ArrayList<ResourceLink>(entity.getResourceLinks()); Collection<ResourceLink> resourceLinks = new ArrayList<ResourceLink>(theEntity.getResourceLinks());
List<ResourceIndexedSearchParamString> stringParams = null; List<ResourceIndexedSearchParamString> stringParams = null;
List<ResourceIndexedSearchParamToken> tokenParams = null; List<ResourceIndexedSearchParamToken> tokenParams = null;
@ -1128,27 +1128,27 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
uriParams = Collections.emptyList(); uriParams = Collections.emptyList();
coordsParams = Collections.emptyList(); coordsParams = Collections.emptyList();
links = Collections.emptyList(); links = Collections.emptyList();
entity.setDeleted(theDeletedTimestampOrNull); theEntity.setDeleted(theDeletedTimestampOrNull);
entity.setUpdated(theDeletedTimestampOrNull); theEntity.setUpdated(theDeletedTimestampOrNull);
} else { } else {
entity.setDeleted(null); theEntity.setDeleted(null);
if (thePerformIndexing) { if (thePerformIndexing) {
stringParams = extractSearchParamStrings(entity, theResource); stringParams = extractSearchParamStrings(theEntity, theResource);
numberParams = extractSearchParamNumber(entity, theResource); numberParams = extractSearchParamNumber(theEntity, theResource);
quantityParams = extractSearchParamQuantity(entity, theResource); quantityParams = extractSearchParamQuantity(theEntity, theResource);
dateParams = extractSearchParamDates(entity, theResource); dateParams = extractSearchParamDates(theEntity, theResource);
uriParams = extractSearchParamUri(entity, theResource); uriParams = extractSearchParamUri(theEntity, theResource);
coordsParams = extractSearchParamCoords(entity, theResource); coordsParams = extractSearchParamCoords(theEntity, theResource);
// ourLog.info("Indexing resource: {}", entity.getId()); // ourLog.info("Indexing resource: {}", entity.getId());
ourLog.trace("Storing string indexes: {}", stringParams); ourLog.trace("Storing string indexes: {}", stringParams);
tokenParams = new ArrayList<ResourceIndexedSearchParamToken>(); tokenParams = new ArrayList<ResourceIndexedSearchParamToken>();
for (BaseResourceIndexedSearchParam next : extractSearchParamTokens(entity, theResource)) { for (BaseResourceIndexedSearchParam next : extractSearchParamTokens(theEntity, theResource)) {
if (next instanceof ResourceIndexedSearchParamToken) { if (next instanceof ResourceIndexedSearchParamToken) {
tokenParams.add((ResourceIndexedSearchParamToken) next); tokenParams.add((ResourceIndexedSearchParamToken) next);
} else { } else {
@ -1156,49 +1156,49 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
} }
} }
links = extractResourceLinks(entity, theResource); links = extractResourceLinks(theEntity, theResource);
populateResourceIntoEntity(theResource, entity); populateResourceIntoEntity(theResource, theEntity);
entity.setUpdated(new Date()); theEntity.setUpdated(new Date());
entity.setLanguage(theResource.getLanguage().getValue()); theEntity.setLanguage(theResource.getLanguage().getValue());
entity.setParamsString(stringParams); theEntity.setParamsString(stringParams);
entity.setParamsStringPopulated(stringParams.isEmpty() == false); theEntity.setParamsStringPopulated(stringParams.isEmpty() == false);
entity.setParamsToken(tokenParams); theEntity.setParamsToken(tokenParams);
entity.setParamsTokenPopulated(tokenParams.isEmpty() == false); theEntity.setParamsTokenPopulated(tokenParams.isEmpty() == false);
entity.setParamsNumber(numberParams); theEntity.setParamsNumber(numberParams);
entity.setParamsNumberPopulated(numberParams.isEmpty() == false); theEntity.setParamsNumberPopulated(numberParams.isEmpty() == false);
entity.setParamsQuantity(quantityParams); theEntity.setParamsQuantity(quantityParams);
entity.setParamsQuantityPopulated(quantityParams.isEmpty() == false); theEntity.setParamsQuantityPopulated(quantityParams.isEmpty() == false);
entity.setParamsDate(dateParams); theEntity.setParamsDate(dateParams);
entity.setParamsDatePopulated(dateParams.isEmpty() == false); theEntity.setParamsDatePopulated(dateParams.isEmpty() == false);
entity.setParamsUri(uriParams); theEntity.setParamsUri(uriParams);
entity.setParamsUriPopulated(uriParams.isEmpty() == false); theEntity.setParamsUriPopulated(uriParams.isEmpty() == false);
entity.setParamsCoords(coordsParams); theEntity.setParamsCoords(coordsParams);
entity.setParamsCoordsPopulated(coordsParams.isEmpty() == false); theEntity.setParamsCoordsPopulated(coordsParams.isEmpty() == false);
entity.setResourceLinks(links); theEntity.setResourceLinks(links);
entity.setHasLinks(links.isEmpty() == false); theEntity.setHasLinks(links.isEmpty() == false);
entity.setIndexStatus(INDEX_STATUS_INDEXED); theEntity.setIndexStatus(INDEX_STATUS_INDEXED);
} else { } else {
populateResourceIntoEntity(theResource, entity); populateResourceIntoEntity(theResource, theEntity);
entity.setUpdated(new Date()); theEntity.setUpdated(new Date());
entity.setLanguage(theResource.getLanguage().getValue()); theEntity.setLanguage(theResource.getLanguage().getValue());
entity.setIndexStatus(null); theEntity.setIndexStatus(null);
} }
} }
if (entity.getId() == null) { if (theEntity.getId() == null) {
myEntityManager.persist(entity); myEntityManager.persist(theEntity);
if (entity.getForcedId() != null) { if (theEntity.getForcedId() != null) {
myEntityManager.persist(entity.getForcedId()); myEntityManager.persist(theEntity.getForcedId());
} }
} else { } else {
entity = myEntityManager.merge(entity); theEntity = myEntityManager.merge(theEntity);
} }
if (thePerformIndexing) { if (thePerformIndexing) {
@ -1283,10 +1283,10 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
myEntityManager.flush(); myEntityManager.flush();
if (theResource != null) { if (theResource != null) {
theResource.setId(entity.getIdDt()); theResource.setId(theEntity.getIdDt());
} }
return entity; return theEntity;
} }
/** /**

View File

@ -1,5 +1,6 @@
package ca.uhn.fhir.jpa.dao; package ca.uhn.fhir.jpa.dao;
import static org.apache.commons.lang3.StringUtils.INDEX_NOT_FOUND;
/* /*
* #%L * #%L
* HAPI FHIR JPA Server * HAPI FHIR JPA Server
@ -287,12 +288,13 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
Predicate typePredicate = builder.equal(from.get("myResourceType"), myResourceName); Predicate typePredicate = builder.equal(from.get("myResourceType"), myResourceName);
Predicate langPredicate = from.get("myLanguage").as(String.class).in(values); Predicate langPredicate = from.get("myLanguage").as(String.class).in(values);
Predicate masterCodePredicate = builder.and(typePredicate, langPredicate); Predicate masterCodePredicate = builder.and(typePredicate, langPredicate);
Predicate notDeletedPredicate = builder.isNull(from.get("myDeleted"));
if (thePids.size() > 0) { if (thePids.size() > 0) {
Predicate inPids = (from.get("myId").in(thePids)); Predicate inPids = (from.get("myId").in(thePids));
cq.where(builder.and(masterCodePredicate, inPids)); cq.where(builder.and(masterCodePredicate, inPids, notDeletedPredicate));
} else { } else {
cq.where(masterCodePredicate); cq.where(builder.and(masterCodePredicate, notDeletedPredicate));
} }
TypedQuery<Long> q = myEntityManager.createQuery(cq); TypedQuery<Long> q = myEntityManager.createQuery(cq);
@ -376,6 +378,10 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
andPredicates.add(builder.or(orPredicates.toArray(new Predicate[0]))); andPredicates.add(builder.or(orPredicates.toArray(new Predicate[0])));
} }
From<ResourceTag, ResourceTable> defJoin = from.join("myResource");
Predicate notDeletedPredicatePrediate = builder.isNull(defJoin.get("myDeleted"));
andPredicates.add(notDeletedPredicatePrediate);
Predicate masterCodePredicate = builder.and(andPredicates.toArray(new Predicate[0])); Predicate masterCodePredicate = builder.and(andPredicates.toArray(new Predicate[0]));
if (pids.size() > 0) { if (pids.size() > 0) {
@ -1262,6 +1268,8 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
throw new InvalidRequestException("Trying to update " + theId + " but this is not the current version"); throw new InvalidRequestException("Trying to update " + theId + " but this is not the current version");
} }
verifyOkToDelete(entity);
// Notify interceptors // Notify interceptors
ActionRequestDetails requestDetails = new ActionRequestDetails(theId, theId.getResourceType()); ActionRequestDetails requestDetails = new ActionRequestDetails(theId, theId.getResourceType());
notifyInterceptors(RestOperationTypeEnum.DELETE, requestDetails); notifyInterceptors(RestOperationTypeEnum.DELETE, requestDetails);
@ -1274,6 +1282,23 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
return toMethodOutcome(savedEntity, null); return toMethodOutcome(savedEntity, null);
} }
private void verifyOkToDelete(ResourceTable theEntity) {
TypedQuery<ResourceLink> query = myEntityManager.createQuery("SELECT l FROM ResourceLink l WHERE l.myTargetResourcePid = :target_pid", ResourceLink.class);
query.setParameter("target_pid", theEntity.getId());
query.setMaxResults(1);
List<ResourceLink> resultList = query.getResultList();
if (resultList.isEmpty()) {
return;
}
ResourceLink link = resultList.get(0);
String targetId = theEntity.getIdDt().toUnqualifiedVersionless().getValue();
String sourceId = link.getSourceResource().getIdDt().toUnqualifiedVersionless().getValue();
String sourcePath = link.getSourcePath();
throw new PreconditionFailedException("Unable to delete " + targetId + " because at least one resource has a reference to this resource. First reference found was resource " + sourceId + " in path " + sourcePath );
}
@Override @Override
public DaoMethodOutcome deleteByUrl(String theUrl) { public DaoMethodOutcome deleteByUrl(String theUrl) {
StopWatch w = new StopWatch(); StopWatch w = new StopWatch();
@ -1288,6 +1313,8 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
Long pid = resource.iterator().next(); Long pid = resource.iterator().next();
ResourceTable entity = myEntityManager.find(ResourceTable.class, pid); ResourceTable entity = myEntityManager.find(ResourceTable.class, pid);
verifyOkToDelete(entity);
// Notify interceptors // Notify interceptors
IdDt idToDelete = entity.getIdDt(); IdDt idToDelete = entity.getIdDt();
ActionRequestDetails requestDetails = new ActionRequestDetails(idToDelete, idToDelete.getResourceType()); ActionRequestDetails requestDetails = new ActionRequestDetails(idToDelete, idToDelete.getResourceType());
@ -1369,6 +1396,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
protected abstract List<Object> getIncludeValues(FhirTerser theTerser, Include theInclude, IBaseResource theResource, RuntimeResourceDefinition theResourceDef); protected abstract List<Object> getIncludeValues(FhirTerser theTerser, Include theInclude, IBaseResource theResource, RuntimeResourceDefinition theResourceDef);
@Override
public Class<T> getResourceType() { public Class<T> getResourceType() {
return myResourceType; return myResourceType;
} }
@ -2126,18 +2154,23 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
for (IQueryParameterType next : nextValue) { for (IQueryParameterType next : nextValue) {
String value = next.getValueAsQueryToken(); String value = next.getValueAsQueryToken();
IIdType valueId = new IdDt(value); IIdType valueId = new IdDt(value);
try { try {
long valueLong = translateForcedIdToPid(valueId); BaseHasResource entity = readEntity(valueId);
joinPids.add(valueLong); if (entity.getDeleted() != null) {
continue;
}
joinPids.add(entity.getId());
} catch (ResourceNotFoundException e) { } catch (ResourceNotFoundException e) {
// This isn't an error, just means no result found // This isn't an error, just means no result found
} }
} }
if (joinPids.isEmpty()) { if (joinPids.isEmpty()) {
continue; return new HashSet<Long>();
} }
} }
pids = addPredicateId(pids, joinPids); pids = addPredicateId(pids, joinPids);
if (pids.isEmpty()) { if (pids.isEmpty()) {
return new HashSet<Long>(); return new HashSet<Long>();
@ -2250,9 +2283,14 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
} }
private DaoMethodOutcome toMethodOutcome(final ResourceTable theEntity, IResource theResource) { private DaoMethodOutcome toMethodOutcome(final ResourceTable theEntity, IResource theResource) {
DaoMethodOutcome retVal = toMethodOutcome((BaseHasResource)theEntity, theResource);
retVal.setEntity(theEntity);
return retVal;
}
private DaoMethodOutcome toMethodOutcome(final BaseHasResource theEntity, IResource theResource) {
DaoMethodOutcome outcome = new DaoMethodOutcome(); DaoMethodOutcome outcome = new DaoMethodOutcome();
outcome.setId(theEntity.getIdDt()); outcome.setId(theEntity.getIdDt());
outcome.setEntity(theEntity);
outcome.setResource(theResource); outcome.setResource(theResource);
if (theResource != null) { if (theResource != null) {
theResource.setId(theEntity.getIdDt()); theResource.setId(theEntity.getIdDt());

View File

@ -90,6 +90,10 @@ public class SearchParameterMap extends HashMap<String, List<List<? extends IQue
getIncludes().add(theInclude); getIncludes().add(theInclude);
} }
public void addRevInclude(Include theInclude) {
getRevIncludes().add(theInclude);
}
public Integer getCount() { public Integer getCount() {
return myCount; return myCount;
} }
@ -106,6 +110,9 @@ public class SearchParameterMap extends HashMap<String, List<List<? extends IQue
} }
public Set<Include> getRevIncludes() { public Set<Include> getRevIncludes() {
if (myRevIncludes == null) {
myRevIncludes = new HashSet<Include>();
}
return myRevIncludes; return myRevIncludes;
} }

View File

@ -41,16 +41,15 @@ import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.rest.server.Constants; import ca.uhn.fhir.rest.server.Constants;
@Entity @Entity
@Table(name = "HFJ_RES_VER", uniqueConstraints = {@UniqueConstraint(name="IDX_RES_VER_ALL", columnNames = { "RES_ID", "RES_TYPE", "RES_VER" })}) @Table(name = "HFJ_RES_VER", uniqueConstraints = { @UniqueConstraint(name = "IDX_RES_VER_ALL", columnNames = { "RES_ID", "RES_TYPE", "RES_VER" }) })
@org.hibernate.annotations.Table(appliesTo="HFJ_RES_VER", indexes= {@Index(name="IDX_RES_VER_DATE", columnNames= {"RES_UPDATED"})}) @org.hibernate.annotations.Table(appliesTo = "HFJ_RES_VER", indexes = { @Index(name = "IDX_RES_VER_DATE", columnNames = { "RES_UPDATED" }) })
public class ResourceHistoryTable extends BaseHasResource implements Serializable { public class ResourceHistoryTable extends BaseHasResource implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@Id @Id
@GeneratedValue(strategy=GenerationType.AUTO) @GeneratedValue(strategy = GenerationType.AUTO)
@Column(name="PID") @Column(name = "PID")
private Long myId; private Long myId;
@Column(name = "RES_ID") @Column(name = "RES_ID")
@ -87,13 +86,14 @@ public class ResourceHistoryTable extends BaseHasResource implements Serializabl
return historyTag; return historyTag;
} }
@Override
public Long getId() { public Long getId() {
return myId; return myId;
} }
@Override @Override
public IdDt getIdDt() { public IdDt getIdDt() {
Object id = getForcedId()==null? getResourceId() : getForcedId().getForcedId(); Object id = getForcedId() == null ? getResourceId() : getForcedId().getForcedId();
return new IdDt(getResourceType() + '/' + id + '/' + Constants.PARAM_HISTORY + '/' + getVersion()); return new IdDt(getResourceType() + '/' + id + '/' + Constants.PARAM_HISTORY + '/' + getVersion());
} }
@ -101,11 +101,12 @@ public class ResourceHistoryTable extends BaseHasResource implements Serializabl
return myResourceId; return myResourceId;
} }
@Override
public String getResourceType() { public String getResourceType() {
return myResourceType; return myResourceType;
} }
@Override
public Collection<ResourceHistoryTag> getTags() { public Collection<ResourceHistoryTag> getTags() {
if (myTags == null) { if (myTags == null) {
myTags = new ArrayList<ResourceHistoryTag>(); myTags = new ArrayList<ResourceHistoryTag>();
@ -132,11 +133,11 @@ public class ResourceHistoryTable extends BaseHasResource implements Serializabl
} }
public void setResourceType(String theResourceType) { public void setResourceType(String theResourceType) {
myResourceType=theResourceType; myResourceType = theResourceType;
} }
public void setVersion(long theVersion) { public void setVersion(long theVersion) {
myResourceVersion=theVersion; myResourceVersion = theVersion;
} }
} }

View File

@ -46,7 +46,7 @@ public class ResourceIndexedSearchParamCoords extends BaseResourceIndexedSearchP
public ResourceIndexedSearchParamCoords() { public ResourceIndexedSearchParamCoords() {
} }
public ResourceIndexedSearchParamCoords(String theName, String theUri, double theLatitude, double theLongitude) { public ResourceIndexedSearchParamCoords(String theName, double theLatitude, double theLongitude) {
setParamName(theName); setParamName(theName);
setLatitude(theLatitude); setLatitude(theLatitude);
setLongitude(theLongitude); setLongitude(theLongitude);

View File

@ -141,16 +141,19 @@ public class ResourceTable extends BaseHasResource implements Serializable {
@Column(name = "RES_VER") @Column(name = "RES_VER")
private long myVersion; private long myVersion;
@Override
public ResourceTag addTag(TagDefinition theTag) { public ResourceTag addTag(TagDefinition theTag) {
ResourceTag tag = new ResourceTag(this, theTag); ResourceTag tag = new ResourceTag(this, theTag);
getTags().add(tag); getTags().add(tag);
return tag; return tag;
} }
@Override
public Long getId() { public Long getId() {
return myId; return myId;
} }
@Override
public IdDt getIdDt() { public IdDt getIdDt() {
Object id = getForcedId() == null ? myId : getForcedId().getForcedId(); Object id = getForcedId() == null ? myId : getForcedId().getForcedId();
return new IdDt(myResourceType + '/' + id + '/' + Constants.PARAM_HISTORY + '/' + myVersion); return new IdDt(myResourceType + '/' + id + '/' + Constants.PARAM_HISTORY + '/' + myVersion);
@ -224,10 +227,12 @@ public class ResourceTable extends BaseHasResource implements Serializable {
return myResourceLinks; return myResourceLinks;
} }
@Override
public String getResourceType() { public String getResourceType() {
return myResourceType; return myResourceType;
} }
@Override
public Collection<ResourceTag> getTags() { public Collection<ResourceTag> getTags() {
if (myTags == null) { if (myTags == null) {
myTags = new HashSet<ResourceTag>(); myTags = new HashSet<ResourceTag>();
@ -235,6 +240,7 @@ public class ResourceTable extends BaseHasResource implements Serializable {
return myTags; return myTags;
} }
@Override
public long getVersion() { public long getVersion() {
return myVersion; return myVersion;
} }
@ -428,4 +434,5 @@ public class ResourceTable extends BaseHasResource implements Serializable {
return retVal; return retVal;
} }
} }

View File

@ -2,6 +2,8 @@ package ca.uhn.fhir.jpa.dao;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import java.util.List;
import javax.persistence.EntityManager; import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext; import javax.persistence.PersistenceContext;
@ -34,6 +36,7 @@ import ca.uhn.fhir.jpa.entity.ResourceLink;
import ca.uhn.fhir.jpa.entity.ResourceTable; import ca.uhn.fhir.jpa.entity.ResourceTable;
import ca.uhn.fhir.jpa.entity.ResourceTag; import ca.uhn.fhir.jpa.entity.ResourceTag;
import ca.uhn.fhir.jpa.entity.TagDefinition; import ca.uhn.fhir.jpa.entity.TagDefinition;
import ca.uhn.fhir.jpa.provider.JpaSystemProviderDstu2;
import ca.uhn.fhir.model.dstu2.resource.Bundle; import ca.uhn.fhir.model.dstu2.resource.Bundle;
import ca.uhn.fhir.model.dstu2.resource.Device; import ca.uhn.fhir.model.dstu2.resource.Device;
import ca.uhn.fhir.model.dstu2.resource.DiagnosticReport; import ca.uhn.fhir.model.dstu2.resource.DiagnosticReport;
@ -46,6 +49,7 @@ import ca.uhn.fhir.model.dstu2.resource.Practitioner;
import ca.uhn.fhir.model.dstu2.resource.Questionnaire; import ca.uhn.fhir.model.dstu2.resource.Questionnaire;
import ca.uhn.fhir.model.dstu2.resource.QuestionnaireResponse; import ca.uhn.fhir.model.dstu2.resource.QuestionnaireResponse;
import ca.uhn.fhir.model.dstu2.resource.ValueSet; import ca.uhn.fhir.model.dstu2.resource.ValueSet;
import ca.uhn.fhir.rest.server.IResourceProvider;
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor; import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
//@formatter:off //@formatter:off
@ -57,6 +61,8 @@ import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
//@formatter:on //@formatter:on
public class BaseJpaDstu2Test extends BaseJpaTest { public class BaseJpaDstu2Test extends BaseJpaTest {
@Autowired
protected DaoConfig myDaoConfig;
@Autowired @Autowired
@Qualifier("myDeviceDaoDstu2") @Qualifier("myDeviceDaoDstu2")
protected IFhirResourceDao<Device> myDeviceDao; protected IFhirResourceDao<Device> myDeviceDao;
@ -66,6 +72,8 @@ public class BaseJpaDstu2Test extends BaseJpaTest {
@Autowired @Autowired
@Qualifier("myEncounterDaoDstu2") @Qualifier("myEncounterDaoDstu2")
protected IFhirResourceDao<Encounter> myEncounterDao; protected IFhirResourceDao<Encounter> myEncounterDao;
@PersistenceContext()
protected EntityManager myEntityManager;
@Autowired @Autowired
protected FhirContext myFhirCtx; protected FhirContext myFhirCtx;
protected IServerInterceptor myInterceptor; protected IServerInterceptor myInterceptor;
@ -79,9 +87,6 @@ public class BaseJpaDstu2Test extends BaseJpaTest {
@Qualifier("myOrganizationDaoDstu2") @Qualifier("myOrganizationDaoDstu2")
protected IFhirResourceDao<Organization> myOrganizationDao; protected IFhirResourceDao<Organization> myOrganizationDao;
@Autowired @Autowired
@Qualifier("myValueSetDaoDstu2")
protected IFhirResourceDao<ValueSet> myValueSetDao;
@Autowired
@Qualifier("myPatientDaoDstu2") @Qualifier("myPatientDaoDstu2")
protected IFhirResourceDao<Patient> myPatientDao; protected IFhirResourceDao<Patient> myPatientDao;
@Autowired @Autowired
@ -94,14 +99,32 @@ public class BaseJpaDstu2Test extends BaseJpaTest {
@Qualifier("myQuestionnaireResponseDaoDstu2") @Qualifier("myQuestionnaireResponseDaoDstu2")
protected IFhirResourceDao<QuestionnaireResponse> myQuestionnaireResponseDao; protected IFhirResourceDao<QuestionnaireResponse> myQuestionnaireResponseDao;
@Autowired @Autowired
@Qualifier("myResourceProvidersDstu2")
protected Object myResourceProviders;
@Autowired
@Qualifier("mySystemDaoDstu2") @Qualifier("mySystemDaoDstu2")
protected IFhirSystemDao<Bundle> mySystemDao; protected IFhirSystemDao<Bundle> mySystemDao;
@Autowired @Autowired
protected DaoConfig myDaoConfig; @Qualifier("mySystemProviderDstu2")
protected JpaSystemProviderDstu2 mySystemProvider;
@Autowired @Autowired
protected PlatformTransactionManager myTxManager; protected PlatformTransactionManager myTxManager;
@PersistenceContext() @Autowired
protected EntityManager myEntityManager; @Qualifier("myValueSetDaoDstu2")
protected IFhirResourceDao<ValueSet> myValueSetDao;
@Before
public void beforeCreateInterceptor() {
myInterceptor = mock(IServerInterceptor.class);
myDaoConfig.setInterceptors(myInterceptor);
}
@Before
@Transactional()
public void beforePurgeDatabase() {
final EntityManager entityManager = this.myEntityManager;
purgeDatabase(entityManager, myTxManager);
}
/** /**
* Just so that JUnit doesn't complain about no test methods in this class * Just so that JUnit doesn't complain about no test methods in this class
@ -111,52 +134,43 @@ public class BaseJpaDstu2Test extends BaseJpaTest {
// nothing // nothing
} }
@Before public static void purgeDatabase(final EntityManager entityManager, PlatformTransactionManager theTxManager) {
@Transactional() TransactionTemplate txTemplate = new TransactionTemplate(theTxManager);
public void beforePurgeDatabase() {
TransactionTemplate txTemplate = new TransactionTemplate(myTxManager);
txTemplate.setPropagationBehavior(TransactionTemplate.PROPAGATION_REQUIRED); txTemplate.setPropagationBehavior(TransactionTemplate.PROPAGATION_REQUIRED);
txTemplate.execute(new TransactionCallback<Void>() { txTemplate.execute(new TransactionCallback<Void>() {
@Override @Override
public Void doInTransaction(TransactionStatus theStatus) { public Void doInTransaction(TransactionStatus theStatus) {
myEntityManager.createQuery("UPDATE " + ResourceHistoryTable.class.getSimpleName() + " d SET d.myForcedId = null").executeUpdate(); entityManager.createQuery("UPDATE " + ResourceHistoryTable.class.getSimpleName() + " d SET d.myForcedId = null").executeUpdate();
myEntityManager.createQuery("UPDATE " + ResourceTable.class.getSimpleName() + " d SET d.myForcedId = null").executeUpdate(); entityManager.createQuery("UPDATE " + ResourceTable.class.getSimpleName() + " d SET d.myForcedId = null").executeUpdate();
return null; return null;
} }
}); });
txTemplate.execute(new TransactionCallback<Void>() { txTemplate.execute(new TransactionCallback<Void>() {
@Override @Override
public Void doInTransaction(TransactionStatus theStatus) { public Void doInTransaction(TransactionStatus theStatus) {
myEntityManager.createQuery("DELETE from " + ForcedId.class.getSimpleName() + " d").executeUpdate(); entityManager.createQuery("DELETE from " + ForcedId.class.getSimpleName() + " d").executeUpdate();
myEntityManager.createQuery("DELETE from " + ResourceIndexedSearchParamDate.class.getSimpleName() + " d").executeUpdate(); entityManager.createQuery("DELETE from " + ResourceIndexedSearchParamDate.class.getSimpleName() + " d").executeUpdate();
myEntityManager.createQuery("DELETE from " + ResourceIndexedSearchParamNumber.class.getSimpleName() + " d").executeUpdate(); entityManager.createQuery("DELETE from " + ResourceIndexedSearchParamNumber.class.getSimpleName() + " d").executeUpdate();
myEntityManager.createQuery("DELETE from " + ResourceIndexedSearchParamQuantity.class.getSimpleName() + " d").executeUpdate(); entityManager.createQuery("DELETE from " + ResourceIndexedSearchParamQuantity.class.getSimpleName() + " d").executeUpdate();
myEntityManager.createQuery("DELETE from " + ResourceIndexedSearchParamString.class.getSimpleName() + " d").executeUpdate(); entityManager.createQuery("DELETE from " + ResourceIndexedSearchParamString.class.getSimpleName() + " d").executeUpdate();
myEntityManager.createQuery("DELETE from " + ResourceIndexedSearchParamToken.class.getSimpleName() + " d").executeUpdate(); entityManager.createQuery("DELETE from " + ResourceIndexedSearchParamToken.class.getSimpleName() + " d").executeUpdate();
myEntityManager.createQuery("DELETE from " + ResourceIndexedSearchParamUri.class.getSimpleName() + " d").executeUpdate(); entityManager.createQuery("DELETE from " + ResourceIndexedSearchParamUri.class.getSimpleName() + " d").executeUpdate();
myEntityManager.createQuery("DELETE from " + ResourceIndexedSearchParamCoords.class.getSimpleName() + " d").executeUpdate(); entityManager.createQuery("DELETE from " + ResourceIndexedSearchParamCoords.class.getSimpleName() + " d").executeUpdate();
myEntityManager.createQuery("DELETE from " + ResourceLink.class.getSimpleName() + " d").executeUpdate(); entityManager.createQuery("DELETE from " + ResourceLink.class.getSimpleName() + " d").executeUpdate();
return null; return null;
} }
}); });
txTemplate.execute(new TransactionCallback<Void>() { txTemplate.execute(new TransactionCallback<Void>() {
@Override @Override
public Void doInTransaction(TransactionStatus theStatus) { public Void doInTransaction(TransactionStatus theStatus) {
myEntityManager.createQuery("DELETE from " + ResourceHistoryTag.class.getSimpleName() + " d").executeUpdate(); entityManager.createQuery("DELETE from " + ResourceHistoryTag.class.getSimpleName() + " d").executeUpdate();
myEntityManager.createQuery("DELETE from " + ResourceTag.class.getSimpleName() + " d").executeUpdate(); entityManager.createQuery("DELETE from " + ResourceTag.class.getSimpleName() + " d").executeUpdate();
myEntityManager.createQuery("DELETE from " + TagDefinition.class.getSimpleName() + " d").executeUpdate(); entityManager.createQuery("DELETE from " + TagDefinition.class.getSimpleName() + " d").executeUpdate();
myEntityManager.createQuery("DELETE from " + ResourceHistoryTable.class.getSimpleName() + " d").executeUpdate(); entityManager.createQuery("DELETE from " + ResourceHistoryTable.class.getSimpleName() + " d").executeUpdate();
myEntityManager.createQuery("DELETE from " + ResourceTable.class.getSimpleName() + " d").executeUpdate(); entityManager.createQuery("DELETE from " + ResourceTable.class.getSimpleName() + " d").executeUpdate();
return null; return null;
} }
}); });
} }
@Before
public void beforeCreateInterceptor() {
myInterceptor = mock(IServerInterceptor.class);
myDaoConfig.setInterceptors(myInterceptor);
}
} }

View File

@ -4,6 +4,7 @@ import static org.apache.commons.lang3.StringUtils.defaultString;
import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.endsWith; import static org.hamcrest.Matchers.endsWith;
import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.hasItem; import static org.hamcrest.Matchers.hasItem;
@ -42,6 +43,7 @@ import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamString;
import ca.uhn.fhir.jpa.entity.TagTypeEnum; import ca.uhn.fhir.jpa.entity.TagTypeEnum;
import ca.uhn.fhir.model.api.IQueryParameterType; import ca.uhn.fhir.model.api.IQueryParameterType;
import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.Include;
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum; import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
import ca.uhn.fhir.model.api.Tag; import ca.uhn.fhir.model.api.Tag;
import ca.uhn.fhir.model.api.TagList; import ca.uhn.fhir.model.api.TagList;
@ -67,6 +69,7 @@ import ca.uhn.fhir.model.dstu2.valueset.AdministrativeGenderEnum;
import ca.uhn.fhir.model.dstu2.valueset.HTTPVerbEnum; import ca.uhn.fhir.model.dstu2.valueset.HTTPVerbEnum;
import ca.uhn.fhir.model.dstu2.valueset.IssueSeverityEnum; import ca.uhn.fhir.model.dstu2.valueset.IssueSeverityEnum;
import ca.uhn.fhir.model.dstu2.valueset.QuantityComparatorEnum; import ca.uhn.fhir.model.dstu2.valueset.QuantityComparatorEnum;
import ca.uhn.fhir.model.primitive.CodeDt;
import ca.uhn.fhir.model.primitive.DateDt; import ca.uhn.fhir.model.primitive.DateDt;
import ca.uhn.fhir.model.primitive.DateTimeDt; import ca.uhn.fhir.model.primitive.DateTimeDt;
import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.model.primitive.IdDt;
@ -107,45 +110,43 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
return retVal; return retVal;
} }
@Test private void sort(TagList thePublished) {
public void testReadWithDeletedResource() { ArrayList<Tag> tags = new ArrayList<Tag>(thePublished);
String methodName = "testReadWithDeletedResource"; Collections.sort(tags, new Comparator<Tag>() {
@Override
Patient patient = new Patient(); public int compare(Tag theO1, Tag theO2) {
patient.addName().addFamily(methodName); int retVal = defaultString(theO1.getScheme()).compareTo(defaultString(theO2.getScheme()));
IIdType id = myPatientDao.create(patient).getId().toVersionless(); if (retVal == 0) {
myPatientDao.delete(id); retVal = defaultString(theO1.getTerm()).compareTo(defaultString(theO2.getTerm()));
}
try { return retVal;
myPatientDao.read(id); }
fail(); });
} catch (ResourceGoneException e) { thePublished.clear();
// good for (Tag next : tags) {
thePublished.add(next);
}
} }
patient.setId(id); private void sortCodings(List<BaseCodingDt> theSecLabels) {
patient.addAddress().addLine("AAA"); Collections.sort(theSecLabels, new Comparator<BaseCodingDt>() {
myPatientDao.update(patient); @Override
public int compare(BaseCodingDt theO1, BaseCodingDt theO2) {
Patient p; return theO1.getSystemElement().getValue().compareTo(theO2.getSystemElement().getValue());
}
p = myPatientDao.read(id); });
assertEquals(1, (p).getName().size());
p = myPatientDao.read(id.withVersion("1"));
assertEquals(1, (p).getName().size());
try {
myPatientDao.read(id.withVersion("2"));
fail();
} catch (ResourceGoneException e) {
// good
} }
p = myPatientDao.read(id.withVersion("3")); private List<IdDt> sortIds(List<IdDt> theProfiles) {
assertEquals(1, (p).getName().size()); ArrayList<IdDt> retVal = new ArrayList<IdDt>(theProfiles);
Collections.sort(retVal, new Comparator<IdDt>() {
@Override
public int compare(IdDt theO1, IdDt theO2) {
return theO1.getValue().compareTo(theO2.getValue());
}
});
return retVal;
} }
@Test @Test
public void testChoiceParamConcept() { public void testChoiceParamConcept() {
@ -314,48 +315,6 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
} }
} }
@Test
public void testCreateWithInvalidReferenceNoId() {
Patient p = new Patient();
p.addName().addFamily("Hello");
p.getManagingOrganization().setReference("Organization/");
try {
myPatientDao.create(p);
fail();
} catch (InvalidRequestException e) {
assertThat(e.getMessage(), containsString("Does not contain resource ID"));
}
}
@Test
public void testCreateWithReferenceBadType() {
Patient p = new Patient();
p.addName().addFamily("Hello");
p.getManagingOrganization().setReference("Blah/123");
try {
myPatientDao.create(p);
fail();
} catch (InvalidRequestException e) {
assertThat(e.getMessage(), containsString("Invalid resource reference"));
}
}
@Test
public void testCreateWithReferenceNoType() {
Patient p = new Patient();
p.addName().addFamily("Hello");
p.getManagingOrganization().setReference("123");
try {
myPatientDao.create(p);
fail();
} catch (InvalidRequestException e) {
assertThat(e.getMessage(), containsString("Does not contain resource type"));
}
}
@Test @Test
public void testCreateWithIfNoneExistBasic() { public void testCreateWithIfNoneExistBasic() {
String methodName = "testCreateWithIfNoneExistBasic"; String methodName = "testCreateWithIfNoneExistBasic";
@ -422,6 +381,48 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
} }
@Test
public void testCreateWithInvalidReferenceNoId() {
Patient p = new Patient();
p.addName().addFamily("Hello");
p.getManagingOrganization().setReference("Organization/");
try {
myPatientDao.create(p);
fail();
} catch (InvalidRequestException e) {
assertThat(e.getMessage(), containsString("Does not contain resource ID"));
}
}
@Test
public void testCreateWithReferenceBadType() {
Patient p = new Patient();
p.addName().addFamily("Hello");
p.getManagingOrganization().setReference("Blah/123");
try {
myPatientDao.create(p);
fail();
} catch (InvalidRequestException e) {
assertThat(e.getMessage(), containsString("Invalid resource reference"));
}
}
@Test
public void testCreateWithReferenceNoType() {
Patient p = new Patient();
p.addName().addFamily("Hello");
p.getManagingOrganization().setReference("123");
try {
myPatientDao.create(p);
fail();
} catch (InvalidRequestException e) {
assertThat(e.getMessage(), containsString("Does not contain resource type"));
}
}
@Test @Test
public void testDatePeriodParamEndOnly() { public void testDatePeriodParamEndOnly() {
{ {
@ -623,6 +624,81 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
} }
@Test
public void testCantSearchForDeletedResourceByLanguageOrTag() {
String methodName = "testCantSearchForDeletedResourceByLanguageOrTag";
Organization org = new Organization();
org.setLanguage(new CodeDt("EN_ca"));
org.setName(methodName);
TagList tl = new TagList();
tl.add(new Tag(methodName, methodName));
ResourceMetadataKeyEnum.TAG_LIST.put(org, tl);
IIdType orgId = myOrganizationDao.create(org).getId().toUnqualifiedVersionless();
SearchParameterMap map = new SearchParameterMap();
map.add("_language", new StringParam("EN_ca"));
assertEquals(1, myOrganizationDao.search(map).size());
map = new SearchParameterMap();
map.add("_tag", new TokenParam(methodName, methodName));
assertEquals(1, myOrganizationDao.search(map).size());
myOrganizationDao.delete(orgId);
map = new SearchParameterMap();
map.add("_language", new StringParam("EN_ca"));
assertEquals(0, myOrganizationDao.search(map).size());
map = new SearchParameterMap();
map.add("_tag", new TokenParam(methodName, methodName));
assertEquals(0, myOrganizationDao.search(map).size());
}
@Test
public void testDeleteFailsIfIncomingLinks() {
String methodName = "testDeleteFailsIfIncomingLinks";
Organization org = new Organization();
org.setName(methodName);
IIdType orgId = myOrganizationDao.create(org).getId().toUnqualifiedVersionless();
Patient patient = new Patient();
patient.addName().addFamily(methodName);
patient.getManagingOrganization().setReference(orgId);
IIdType patId = myPatientDao.create(patient).getId().toUnqualifiedVersionless();
SearchParameterMap map = new SearchParameterMap();
map.add("_id", new StringParam(orgId.getIdPart()));
map.addRevInclude(new Include("*"));
List<IIdType> found = toUnqualifiedVersionlessIds(myOrganizationDao.search(map));
assertThat(found, contains(orgId, patId));
try {
myOrganizationDao.delete(orgId);
fail();
} catch (PreconditionFailedException e) {
assertThat(e.getMessage(), containsString("Unable to delete Organization/" + orgId.getIdPart() + " because at least one resource has a reference to this resource. First reference found was resource Patient/" + patId.getIdPart() + " in path Patient.managingOrganization"));
}
myPatientDao.delete(patId);
map = new SearchParameterMap();
map.add("_id", new StringParam(orgId.getIdPart()));
map.addRevInclude(new Include("*"));
found = toUnqualifiedVersionlessIds(myOrganizationDao.search(map));
assertThat(found, contains(orgId));
myOrganizationDao.delete(orgId);
map = new SearchParameterMap();
map.add("_id", new StringParam(orgId.getIdPart()));
map.addRevInclude(new Include("*"));
found = toUnqualifiedVersionlessIds(myOrganizationDao.search(map));
assertThat(found, empty());
}
@Test @Test
public void testDeleteThenUndelete() { public void testDeleteThenUndelete() {
Patient patient = new Patient(); Patient patient = new Patient();
@ -717,6 +793,155 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
assertNotEquals(idv1, idv2); assertNotEquals(idv1, idv2);
} }
@Test
public void testHistoryOverMultiplePages() throws Exception {
String methodName = "testHistoryOverMultiplePages";
Patient patient = new Patient();
patient.addName().addFamily(methodName);
IIdType id = myPatientDao.create(patient).getId().toUnqualifiedVersionless();
Date middleDate = null;
int halfSize = 50;
int fullSize = 100;
for (int i = 0; i < fullSize; i++) {
if (i == halfSize) {
Thread.sleep(fullSize);
middleDate = new Date();
Thread.sleep(fullSize);
}
patient.setId(id);
patient.getName().get(0).getFamily().get(0).setValue(methodName + "_i");
myPatientDao.update(patient);
}
// By instance
IBundleProvider history = myPatientDao.history(id, null);
assertEquals(fullSize + 1, history.size());
for (int i = 0; i < fullSize; i++) {
String expected = id.withVersion(Integer.toString(fullSize + 1 - i)).getValue();
String actual = history.getResources(i, i + 1).get(0).getIdElement().getValue();
assertEquals(expected, actual);
}
// By type
history = myPatientDao.history(null);
assertEquals(fullSize + 1, history.size());
for (int i = 0; i < fullSize; i++) {
String expected = id.withVersion(Integer.toString(fullSize + 1 - i)).getValue();
String actual = history.getResources(i, i + 1).get(0).getIdElement().getValue();
assertEquals(expected, actual);
}
// By server
history = mySystemDao.history(null);
assertEquals(fullSize + 1, history.size());
for (int i = 0; i < fullSize; i++) {
String expected = id.withVersion(Integer.toString(fullSize + 1 - i)).getValue();
String actual = history.getResources(i, i + 1).get(0).getIdElement().getValue();
assertEquals(expected, actual);
}
/*
* With since date
*/
// By instance
history = myPatientDao.history(id, middleDate);
assertEquals(halfSize, history.size());
for (int i = 0; i < halfSize; i++) {
String expected = id.withVersion(Integer.toString(fullSize + 1 - i)).getValue();
String actual = history.getResources(i, i + 1).get(0).getIdElement().getValue();
assertEquals(expected, actual);
}
// By type
history = myPatientDao.history(middleDate);
assertEquals(halfSize, history.size());
for (int i = 0; i < halfSize; i++) {
String expected = id.withVersion(Integer.toString(fullSize + 1 - i)).getValue();
String actual = history.getResources(i, i + 1).get(0).getIdElement().getValue();
assertEquals(expected, actual);
}
// By server
history = mySystemDao.history(middleDate);
assertEquals(halfSize, history.size());
for (int i = 0; i < halfSize; i++) {
String expected = id.withVersion(Integer.toString(fullSize + 1 - i)).getValue();
String actual = history.getResources(i, i + 1).get(0).getIdElement().getValue();
assertEquals(expected, actual);
}
/*
* Now delete the most recent version and make sure everything still works
*/
myPatientDao.delete(id.toVersionless());
fullSize++;
halfSize++;
// By instance
history = myPatientDao.history(id, null);
assertEquals(fullSize + 1, history.size());
for (int i = 0; i < fullSize; i++) {
String expected = id.withVersion(Integer.toString(fullSize + 1 - i)).getValue();
String actual = history.getResources(i, i + 1).get(0).getIdElement().getValue();
assertEquals(expected, actual);
}
// By type
history = myPatientDao.history(null);
assertEquals(fullSize + 1, history.size());
for (int i = 0; i < fullSize; i++) {
String expected = id.withVersion(Integer.toString(fullSize + 1 - i)).getValue();
String actual = history.getResources(i, i + 1).get(0).getIdElement().getValue();
assertEquals(expected, actual);
}
// By server
history = mySystemDao.history(null);
assertEquals(fullSize + 1, history.size());
for (int i = 0; i < fullSize; i++) {
String expected = id.withVersion(Integer.toString(fullSize + 1 - i)).getValue();
String actual = history.getResources(i, i + 1).get(0).getIdElement().getValue();
assertEquals(expected, actual);
}
/*
* With since date
*/
// By instance
history = myPatientDao.history(id, middleDate);
assertEquals(halfSize, history.size());
for (int i = 0; i < halfSize; i++) {
String expected = id.withVersion(Integer.toString(fullSize + 1 - i)).getValue();
String actual = history.getResources(i, i + 1).get(0).getIdElement().getValue();
assertEquals(expected, actual);
}
// By type
history = myPatientDao.history(middleDate);
assertEquals(halfSize, history.size());
for (int i = 0; i < halfSize; i++) {
String expected = id.withVersion(Integer.toString(fullSize + 1 - i)).getValue();
String actual = history.getResources(i, i + 1).get(0).getIdElement().getValue();
assertEquals(expected, actual);
}
// By server
history = mySystemDao.history(middleDate);
assertEquals(halfSize, history.size());
for (int i = 0; i < halfSize; i++) {
String expected = id.withVersion(Integer.toString(fullSize + 1 - i)).getValue();
String actual = history.getResources(i, i + 1).get(0).getIdElement().getValue();
assertEquals(expected, actual);
}
}
@Test @Test
public void testHistoryWithDeletedResource() throws Exception { public void testHistoryWithDeletedResource() throws Exception {
String methodName = "testHistoryWithDeletedResource"; String methodName = "testHistoryWithDeletedResource";
@ -745,80 +970,6 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
assertNull(ResourceMetadataKeyEnum.DELETED_AT.get((IResource) entries.get(2))); assertNull(ResourceMetadataKeyEnum.DELETED_AT.get((IResource) entries.get(2)));
} }
@Test
public void testHistoryOverMultiplePages() throws Exception {
String methodName = "testHistoryOverMultiplePages";
Patient patient = new Patient();
patient.addName().addFamily(methodName);
IIdType id = myPatientDao.create(patient).getId().toUnqualifiedVersionless();
Date middleDate = null;
for (int i = 0; i < 100; i++) {
if (i == 50) {
Thread.sleep(100);
middleDate = new Date();
Thread.sleep(100);
}
patient.setId(id);
patient.getName().get(0).getFamily().get(0).setValue(methodName + "_i");
myPatientDao.update(patient);
}
// By instance
IBundleProvider history = myPatientDao.history(id, null);
for (int i = 0; i < 100; i++) {
String expected = id.withVersion(Integer.toString(101 - i)).getValue();
String actual = history.getResources(i, i + 1).get(0).getIdElement().getValue();
assertEquals(expected, actual);
}
// By type
history = myPatientDao.history(null);
for (int i = 0; i < 100; i++) {
String expected = id.withVersion(Integer.toString(101 - i)).getValue();
String actual = history.getResources(i, i + 1).get(0).getIdElement().getValue();
assertEquals(expected, actual);
}
// By server
history = mySystemDao.history(null);
for (int i = 0; i < 100; i++) {
String expected = id.withVersion(Integer.toString(101 - i)).getValue();
String actual = history.getResources(i, i + 1).get(0).getIdElement().getValue();
assertEquals(expected, actual);
}
/*
* With since date
*/
// By instance
history = myPatientDao.history(id, middleDate);
for (int i = 0; i < 50; i++) {
String expected = id.withVersion(Integer.toString(101 - i)).getValue();
String actual = history.getResources(i, i + 1).get(0).getIdElement().getValue();
assertEquals(expected, actual);
}
// By type
history = myPatientDao.history(middleDate);
for (int i = 0; i < 50; i++) {
String expected = id.withVersion(Integer.toString(101 - i)).getValue();
String actual = history.getResources(i, i + 1).get(0).getIdElement().getValue();
assertEquals(expected, actual);
}
// By server
history = mySystemDao.history(middleDate);
for (int i = 0; i < 50; i++) {
String expected = id.withVersion(Integer.toString(101 - i)).getValue();
String actual = history.getResources(i, i + 1).get(0).getIdElement().getValue();
assertEquals(expected, actual);
}
}
@Test @Test
public void testIdParam() { public void testIdParam() {
Patient patient = new Patient(); Patient patient = new Patient();
@ -891,6 +1042,141 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
} }
} }
@Test
public void testInstanceMetaOperations() {
String methodName = "testMetaRead";
IIdType id;
{
Patient patient = new Patient();
patient.addIdentifier().setSystem("urn:system").setValue(methodName);
TagList tagList = new TagList();
tagList.addTag("tag_scheme1", "tag_code1", "tag_display1");
tagList.addTag("tag_scheme2", "tag_code2", "tag_display2");
ResourceMetadataKeyEnum.TAG_LIST.put(patient, tagList);
List<BaseCodingDt> securityLabels = new ArrayList<BaseCodingDt>();
securityLabels.add(new CodingDt().setSystem("seclabel_sys1").setCode("seclabel_code1").setDisplay("seclabel_dis1"));
securityLabels.add(new CodingDt().setSystem("seclabel_sys2").setCode("seclabel_code2").setDisplay("seclabel_dis2"));
ResourceMetadataKeyEnum.SECURITY_LABELS.put(patient, securityLabels);
ArrayList<IdDt> profiles = new ArrayList<IdDt>();
profiles.add(new IdDt("http://profile/1"));
profiles.add(new IdDt("http://profile/2"));
ResourceMetadataKeyEnum.PROFILES.put(patient, profiles);
id = myPatientDao.create(patient).getId();
}
assertTrue(id.hasVersionIdPart());
/*
* Create a second version
*/
Patient pt = myPatientDao.read(id);
pt.addName().addFamily("anotherName");
myPatientDao.update(pt);
/*
* Meta-Delete on previous version
*/
MetaDt meta = new MetaDt();
meta.addTag().setSystem("tag_scheme1").setCode("tag_code1");
meta.addProfile("http://profile/1");
meta.addSecurity().setSystem("seclabel_sys1").setCode("seclabel_code1");
MetaDt newMeta = myPatientDao.metaDeleteOperation(id.withVersion("1"), meta);
assertEquals(1, newMeta.getProfile().size());
assertEquals(1, newMeta.getSecurity().size());
assertEquals(1, newMeta.getTag().size());
assertEquals("tag_code2", newMeta.getTag().get(0).getCode());
assertEquals("http://profile/2", newMeta.getProfile().get(0).getValue());
assertEquals("seclabel_code2", newMeta.getSecurity().get(0).getCode());
/*
* Meta Read on Version
*/
meta = myPatientDao.metaGetOperation(id.withVersion("1"));
assertEquals(1, meta.getProfile().size());
assertEquals(1, meta.getSecurity().size());
assertEquals(1, meta.getTag().size());
assertEquals("tag_code2", meta.getTag().get(0).getCode());
assertEquals("http://profile/2", meta.getProfile().get(0).getValue());
assertEquals("seclabel_code2", meta.getSecurity().get(0).getCode());
/*
* Meta-read on Version 2
*/
meta = myPatientDao.metaGetOperation(id.withVersion("2"));
assertEquals(2, meta.getProfile().size());
assertEquals(2, meta.getSecurity().size());
assertEquals(2, meta.getTag().size());
/*
* Meta-read on latest version
*/
meta = myPatientDao.metaGetOperation(id.toVersionless());
assertEquals(2, meta.getProfile().size());
assertEquals(2, meta.getSecurity().size());
assertEquals(2, meta.getTag().size());
assertEquals("2", meta.getVersionId());
/*
* Meta-Add on previous version
*/
meta = new MetaDt();
meta.addTag().setSystem("tag_scheme1").setCode("tag_code1");
meta.addProfile("http://profile/1");
meta.addSecurity().setSystem("seclabel_sys1").setCode("seclabel_code1");
newMeta = myPatientDao.metaAddOperation(id.withVersion("1"), meta);
assertEquals(2, newMeta.getProfile().size());
assertEquals(2, newMeta.getSecurity().size());
assertEquals(2, newMeta.getTag().size());
/*
* Meta Read on Version
*/
meta = myPatientDao.metaGetOperation(id.withVersion("1"));
assertEquals(2, meta.getProfile().size());
assertEquals(2, meta.getSecurity().size());
assertEquals(2, meta.getTag().size());
assertEquals("1", meta.getVersionId());
/*
* Meta delete on latest
*/
meta = new MetaDt();
meta.addTag().setSystem("tag_scheme1").setCode("tag_code1");
meta.addProfile("http://profile/1");
meta.addSecurity().setSystem("seclabel_sys1").setCode("seclabel_code1");
newMeta = myPatientDao.metaDeleteOperation(id.toVersionless(), meta);
assertEquals(1, newMeta.getProfile().size());
assertEquals(1, newMeta.getSecurity().size());
assertEquals(1, newMeta.getTag().size());
assertEquals("tag_code2", newMeta.getTag().get(0).getCode());
assertEquals("http://profile/2", newMeta.getProfile().get(0).getValue());
assertEquals("seclabel_code2", newMeta.getSecurity().get(0).getCode());
/*
* Meta-Add on latest version
*/
meta = new MetaDt();
meta.addTag().setSystem("tag_scheme1").setCode("tag_code1");
meta.addProfile("http://profile/1");
meta.addSecurity().setSystem("seclabel_sys1").setCode("seclabel_code1");
newMeta = myPatientDao.metaAddOperation(id.toVersionless(), meta);
assertEquals(2, newMeta.getProfile().size());
assertEquals(2, newMeta.getSecurity().size());
assertEquals(2, newMeta.getTag().size());
assertEquals("2", newMeta.getVersionId());
}
/** /**
* See #196 * See #196
*/ */
@ -1217,138 +1503,42 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
} }
@Test @Test
public void testInstanceMetaOperations() { public void testReadWithDeletedResource() {
String methodName = "testMetaRead"; String methodName = "testReadWithDeletedResource";
IIdType id;
{
Patient patient = new Patient(); Patient patient = new Patient();
patient.addIdentifier().setSystem("urn:system").setValue(methodName); patient.addName().addFamily(methodName);
TagList tagList = new TagList(); IIdType id = myPatientDao.create(patient).getId().toVersionless();
tagList.addTag("tag_scheme1", "tag_code1", "tag_display1"); myPatientDao.delete(id);
tagList.addTag("tag_scheme2", "tag_code2", "tag_display2");
ResourceMetadataKeyEnum.TAG_LIST.put(patient, tagList);
List<BaseCodingDt> securityLabels = new ArrayList<BaseCodingDt>(); try {
securityLabels.add(new CodingDt().setSystem("seclabel_sys1").setCode("seclabel_code1").setDisplay("seclabel_dis1")); myPatientDao.read(id);
securityLabels.add(new CodingDt().setSystem("seclabel_sys2").setCode("seclabel_code2").setDisplay("seclabel_dis2")); fail();
ResourceMetadataKeyEnum.SECURITY_LABELS.put(patient, securityLabels); } catch (ResourceGoneException e) {
// good
ArrayList<IdDt> profiles = new ArrayList<IdDt>();
profiles.add(new IdDt("http://profile/1"));
profiles.add(new IdDt("http://profile/2"));
ResourceMetadataKeyEnum.PROFILES.put(patient, profiles);
id = myPatientDao.create(patient).getId();
} }
assertTrue(id.hasVersionIdPart()); patient.setId(id);
patient.addAddress().addLine("AAA");
myPatientDao.update(patient);
/* Patient p;
* Create a second version
*/
Patient pt = myPatientDao.read(id); p = myPatientDao.read(id);
pt.addName().addFamily("anotherName"); assertEquals(1, (p).getName().size());
myPatientDao.update(pt);
/* p = myPatientDao.read(id.withVersion("1"));
* Meta-Delete on previous version assertEquals(1, (p).getName().size());
*/
MetaDt meta = new MetaDt(); try {
meta.addTag().setSystem("tag_scheme1").setCode("tag_code1"); myPatientDao.read(id.withVersion("2"));
meta.addProfile("http://profile/1"); fail();
meta.addSecurity().setSystem("seclabel_sys1").setCode("seclabel_code1"); } catch (ResourceGoneException e) {
MetaDt newMeta = myPatientDao.metaDeleteOperation(id.withVersion("1"), meta); // good
assertEquals(1, newMeta.getProfile().size()); }
assertEquals(1, newMeta.getSecurity().size());
assertEquals(1, newMeta.getTag().size());
assertEquals("tag_code2", newMeta.getTag().get(0).getCode());
assertEquals("http://profile/2", newMeta.getProfile().get(0).getValue());
assertEquals("seclabel_code2", newMeta.getSecurity().get(0).getCode());
/*
* Meta Read on Version
*/
meta = myPatientDao.metaGetOperation(id.withVersion("1"));
assertEquals(1, meta.getProfile().size());
assertEquals(1, meta.getSecurity().size());
assertEquals(1, meta.getTag().size());
assertEquals("tag_code2", meta.getTag().get(0).getCode());
assertEquals("http://profile/2", meta.getProfile().get(0).getValue());
assertEquals("seclabel_code2", meta.getSecurity().get(0).getCode());
/*
* Meta-read on Version 2
*/
meta = myPatientDao.metaGetOperation(id.withVersion("2"));
assertEquals(2, meta.getProfile().size());
assertEquals(2, meta.getSecurity().size());
assertEquals(2, meta.getTag().size());
/*
* Meta-read on latest version
*/
meta = myPatientDao.metaGetOperation(id.toVersionless());
assertEquals(2, meta.getProfile().size());
assertEquals(2, meta.getSecurity().size());
assertEquals(2, meta.getTag().size());
assertEquals("2", meta.getVersionId());
/*
* Meta-Add on previous version
*/
meta = new MetaDt();
meta.addTag().setSystem("tag_scheme1").setCode("tag_code1");
meta.addProfile("http://profile/1");
meta.addSecurity().setSystem("seclabel_sys1").setCode("seclabel_code1");
newMeta = myPatientDao.metaAddOperation(id.withVersion("1"), meta);
assertEquals(2, newMeta.getProfile().size());
assertEquals(2, newMeta.getSecurity().size());
assertEquals(2, newMeta.getTag().size());
/*
* Meta Read on Version
*/
meta = myPatientDao.metaGetOperation(id.withVersion("1"));
assertEquals(2, meta.getProfile().size());
assertEquals(2, meta.getSecurity().size());
assertEquals(2, meta.getTag().size());
assertEquals("1", meta.getVersionId());
/*
* Meta delete on latest
*/
meta = new MetaDt();
meta.addTag().setSystem("tag_scheme1").setCode("tag_code1");
meta.addProfile("http://profile/1");
meta.addSecurity().setSystem("seclabel_sys1").setCode("seclabel_code1");
newMeta = myPatientDao.metaDeleteOperation(id.toVersionless(), meta);
assertEquals(1, newMeta.getProfile().size());
assertEquals(1, newMeta.getSecurity().size());
assertEquals(1, newMeta.getTag().size());
assertEquals("tag_code2", newMeta.getTag().get(0).getCode());
assertEquals("http://profile/2", newMeta.getProfile().get(0).getValue());
assertEquals("seclabel_code2", newMeta.getSecurity().get(0).getCode());
/*
* Meta-Add on latest version
*/
meta = new MetaDt();
meta.addTag().setSystem("tag_scheme1").setCode("tag_code1");
meta.addProfile("http://profile/1");
meta.addSecurity().setSystem("seclabel_sys1").setCode("seclabel_code1");
newMeta = myPatientDao.metaAddOperation(id.toVersionless(), meta);
assertEquals(2, newMeta.getProfile().size());
assertEquals(2, newMeta.getSecurity().size());
assertEquals(2, newMeta.getTag().size());
assertEquals("2", newMeta.getVersionId());
p = myPatientDao.read(id.withVersion("3"));
assertEquals(1, (p).getName().size());
} }
@Test @Test
@ -1989,6 +2179,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
assertEquals("Cat", published.get(1).getTerm()); assertEquals("Cat", published.get(1).getTerm());
assertEquals("Kittens", published.get(1).getLabel()); assertEquals("Kittens", published.get(1).getLabel());
assertEquals("http://foo", published.get(1).getScheme()); assertEquals("http://foo", published.get(1).getScheme());
List<BaseCodingDt> secLabels = ResourceMetadataKeyEnum.SECURITY_LABELS.get(retrieved); List<BaseCodingDt> secLabels = ResourceMetadataKeyEnum.SECURITY_LABELS.get(retrieved);
sortCodings(secLabels); sortCodings(secLabels);
assertEquals(2, secLabels.size()); assertEquals(2, secLabels.size());
@ -2001,19 +2192,24 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
profiles = ResourceMetadataKeyEnum.PROFILES.get(retrieved); profiles = ResourceMetadataKeyEnum.PROFILES.get(retrieved);
profiles = sortIds(profiles); profiles = sortIds(profiles);
assertEquals(2, profiles.size()); assertEquals(2, profiles.size());
assertEquals("http://profile/1", ResourceMetadataKeyEnum.PROFILES.get(retrieved).get(0).getValue()); assertEquals("http://profile/1", profiles.get(0).getValue());
assertEquals("http://profile/2", ResourceMetadataKeyEnum.PROFILES.get(retrieved).get(1).getValue()); assertEquals("http://profile/2", profiles.get(1).getValue());
List<Patient> search = toList(myPatientDao.search(Patient.SP_IDENTIFIER, patient.getIdentifierFirstRep())); List<Patient> search = toList(myPatientDao.search(Patient.SP_IDENTIFIER, patient.getIdentifierFirstRep()));
assertEquals(1, search.size()); assertEquals(1, search.size());
retrieved = search.get(0); retrieved = search.get(0);
published = (TagList) retrieved.getResourceMetadata().get(ResourceMetadataKeyEnum.TAG_LIST); published = (TagList) retrieved.getResourceMetadata().get(ResourceMetadataKeyEnum.TAG_LIST);
sort(published);
assertEquals("Dog", published.get(0).getTerm()); assertEquals("Dog", published.get(0).getTerm());
assertEquals("Puppies", published.get(0).getLabel()); assertEquals("Puppies", published.get(0).getLabel());
assertEquals(null, published.get(0).getScheme()); assertEquals(null, published.get(0).getScheme());
assertEquals("Cat", published.get(1).getTerm()); assertEquals("Cat", published.get(1).getTerm());
assertEquals("Kittens", published.get(1).getLabel()); assertEquals("Kittens", published.get(1).getLabel());
assertEquals("http://foo", published.get(1).getScheme()); assertEquals("http://foo", published.get(1).getScheme());
secLabels = ResourceMetadataKeyEnum.SECURITY_LABELS.get(retrieved);
sortCodings(secLabels);
assertEquals(2, secLabels.size()); assertEquals(2, secLabels.size());
assertEquals("seclabel:sys:1", secLabels.get(0).getSystemElement().getValue()); assertEquals("seclabel:sys:1", secLabels.get(0).getSystemElement().getValue());
assertEquals("seclabel:code:1", secLabels.get(0).getCodeElement().getValue()); assertEquals("seclabel:code:1", secLabels.get(0).getCodeElement().getValue());
@ -2021,25 +2217,32 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
assertEquals("seclabel:sys:2", secLabels.get(1).getSystemElement().getValue()); assertEquals("seclabel:sys:2", secLabels.get(1).getSystemElement().getValue());
assertEquals("seclabel:code:2", secLabels.get(1).getCodeElement().getValue()); assertEquals("seclabel:code:2", secLabels.get(1).getCodeElement().getValue());
assertEquals("seclabel:dis:2", secLabels.get(1).getDisplayElement().getValue()); assertEquals("seclabel:dis:2", secLabels.get(1).getDisplayElement().getValue());
assertEquals(2, ResourceMetadataKeyEnum.PROFILES.get(retrieved).size());
assertEquals("http://profile/1", ResourceMetadataKeyEnum.PROFILES.get(retrieved).get(0).getValue()); profiles = ResourceMetadataKeyEnum.PROFILES.get(retrieved);
assertEquals("http://profile/2", ResourceMetadataKeyEnum.PROFILES.get(retrieved).get(1).getValue()); profiles = sortIds(profiles);
assertEquals(2, profiles.size());
assertEquals("http://profile/1", profiles.get(0).getValue());
assertEquals("http://profile/2", profiles.get(1).getValue());
myPatientDao.addTag(patientId, TagTypeEnum.TAG, "http://foo", "Cat", "Kittens"); myPatientDao.addTag(patientId, TagTypeEnum.TAG, "http://foo", "Cat", "Kittens");
myPatientDao.addTag(patientId, TagTypeEnum.TAG, "http://foo", "Cow", "Calves"); myPatientDao.addTag(patientId, TagTypeEnum.TAG, "http://foo", "Cow", "Calves");
retrieved = myPatientDao.read(patientId); retrieved = myPatientDao.read(patientId);
published = (TagList) retrieved.getResourceMetadata().get(ResourceMetadataKeyEnum.TAG_LIST); published = (TagList) retrieved.getResourceMetadata().get(ResourceMetadataKeyEnum.TAG_LIST);
sort(published);
assertEquals(3, published.size()); assertEquals(3, published.size());
assertEquals("Dog", published.get(0).getTerm()); assertEquals(published.toString(), "Dog", published.get(0).getTerm());
assertEquals("Puppies", published.get(0).getLabel()); assertEquals(published.toString(), "Puppies", published.get(0).getLabel());
assertEquals(null, published.get(0).getScheme()); assertEquals(published.toString(), null, published.get(0).getScheme());
assertEquals("Cat", published.get(1).getTerm()); assertEquals(published.toString(), "Cat", published.get(1).getTerm());
assertEquals("Kittens", published.get(1).getLabel()); assertEquals(published.toString(), "Kittens", published.get(1).getLabel());
assertEquals("http://foo", published.get(1).getScheme()); assertEquals(published.toString(), "http://foo", published.get(1).getScheme());
assertEquals("Cow", published.get(2).getTerm()); assertEquals(published.toString(), "Cow", published.get(2).getTerm());
assertEquals("Calves", published.get(2).getLabel()); assertEquals(published.toString(), "Calves", published.get(2).getLabel());
assertEquals("http://foo", published.get(2).getScheme()); assertEquals(published.toString(), "http://foo", published.get(2).getScheme());
secLabels = ResourceMetadataKeyEnum.SECURITY_LABELS.get(retrieved);
sortCodings(secLabels);
assertEquals(2, secLabels.size()); assertEquals(2, secLabels.size());
assertEquals("seclabel:sys:1", secLabels.get(0).getSystemElement().getValue()); assertEquals("seclabel:sys:1", secLabels.get(0).getSystemElement().getValue());
assertEquals("seclabel:code:1", secLabels.get(0).getCodeElement().getValue()); assertEquals("seclabel:code:1", secLabels.get(0).getCodeElement().getValue());
@ -2047,41 +2250,13 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
assertEquals("seclabel:sys:2", secLabels.get(1).getSystemElement().getValue()); assertEquals("seclabel:sys:2", secLabels.get(1).getSystemElement().getValue());
assertEquals("seclabel:code:2", secLabels.get(1).getCodeElement().getValue()); assertEquals("seclabel:code:2", secLabels.get(1).getCodeElement().getValue());
assertEquals("seclabel:dis:2", secLabels.get(1).getDisplayElement().getValue()); assertEquals("seclabel:dis:2", secLabels.get(1).getDisplayElement().getValue());
assertEquals(2, ResourceMetadataKeyEnum.PROFILES.get(retrieved).size());
assertEquals("http://profile/1", ResourceMetadataKeyEnum.PROFILES.get(retrieved).get(0).getValue());
assertEquals("http://profile/2", ResourceMetadataKeyEnum.PROFILES.get(retrieved).get(1).getValue());
} profiles = ResourceMetadataKeyEnum.PROFILES.get(retrieved);
profiles = sortIds(profiles);
assertEquals(2, profiles.size());
assertEquals("http://profile/1", profiles.get(0).getValue());
assertEquals("http://profile/2", profiles.get(1).getValue());
private List<IdDt> sortIds(List<IdDt> theProfiles) {
ArrayList<IdDt> retVal = new ArrayList<IdDt>(theProfiles);
Collections.sort(retVal, new Comparator<IdDt>() {
@Override
public int compare(IdDt theO1, IdDt theO2) {
return theO1.getValue().compareTo(theO2.getValue());
}});
return retVal;
}
private void sortCodings(List<BaseCodingDt> theSecLabels) {
Collections.sort(theSecLabels, new Comparator<BaseCodingDt>() {
@Override
public int compare(BaseCodingDt theO1, BaseCodingDt theO2) {
return theO1.getSystemElement().getValue().compareTo(theO2.getSystemElement().getValue());
}});
}
private void sort(TagList thePublished) {
ArrayList<Tag> tags = new ArrayList<Tag>(thePublished);
Collections.sort(tags, new Comparator<Tag>() {
@Override
public int compare(Tag theO1, Tag theO2) {
return defaultString(theO1.getScheme()).compareTo(defaultString(theO2.getScheme()));
}});
thePublished.clear();
for (Tag next : tags) {
thePublished.add(next);
}
} }
@Test @Test

View File

@ -49,16 +49,12 @@ import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.servlet.ServletHolder;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.instance.model.api.IIdType;
import org.junit.After;
import org.junit.AfterClass; import org.junit.AfterClass;
import org.junit.BeforeClass; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.jpa.dao.BaseJpaDstu2Test;
import ca.uhn.fhir.jpa.dao.BaseJpaTest;
import ca.uhn.fhir.jpa.dao.DaoConfig;
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.dao.IFhirSystemDao;
import ca.uhn.fhir.jpa.testutil.RandomServerPortProvider; import ca.uhn.fhir.jpa.testutil.RandomServerPortProvider;
import ca.uhn.fhir.model.api.Bundle; import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.api.BundleEntry; import ca.uhn.fhir.model.api.BundleEntry;
@ -105,26 +101,18 @@ import ca.uhn.fhir.rest.api.SummaryEnum;
import ca.uhn.fhir.rest.client.IGenericClient; import ca.uhn.fhir.rest.client.IGenericClient;
import ca.uhn.fhir.rest.client.ServerValidationModeEnum; import ca.uhn.fhir.rest.client.ServerValidationModeEnum;
import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor; import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor;
import ca.uhn.fhir.rest.gclient.IQuery;
import ca.uhn.fhir.rest.gclient.StringClientParam;
import ca.uhn.fhir.rest.gclient.TokenClientParam;
import ca.uhn.fhir.rest.param.DateRangeParam; import ca.uhn.fhir.rest.param.DateRangeParam;
import ca.uhn.fhir.rest.server.Constants; import ca.uhn.fhir.rest.server.Constants;
import ca.uhn.fhir.rest.server.FifoMemoryPagingProvider; import ca.uhn.fhir.rest.server.FifoMemoryPagingProvider;
import ca.uhn.fhir.rest.server.IResourceProvider;
import ca.uhn.fhir.rest.server.RestfulServer; import ca.uhn.fhir.rest.server.RestfulServer;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException; import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
public class ResourceProviderDstu2Test extends BaseJpaTest { public class ResourceProviderDstu2Test extends BaseJpaDstu2Test {
private static ClassPathXmlApplicationContext ourAppCtx;
private static IGenericClient ourClient; private static IGenericClient ourClient;
private static FhirContext ourCtx = FhirContext.forDstu2();
private static DaoConfig ourDaoConfig;
private static CloseableHttpClient ourHttpClient; private static CloseableHttpClient ourHttpClient;
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ResourceProviderDstu2Test.class); private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ResourceProviderDstu2Test.class);
private static IFhirResourceDao<Organization> ourOrganizationDao;
private static int ourPort; private static int ourPort;
private static Server ourServer; private static Server ourServer;
private static String ourServerBase; private static String ourServerBase;
@ -138,28 +126,30 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
assertEquals(200, resp.getStatusLine().getStatusCode()); assertEquals(200, resp.getStatusLine().getStatusCode());
} }
private void delete(String theResourceType, String theParamName, String theParamValue) { // private void delete(String theResourceType, String theParamName, String theParamValue) {
Bundle resources; // Bundle resources;
do { // do {
IQuery<Bundle> forResource = ourClient.search().forResource(theResourceType); // IQuery<Bundle> forResource = ourClient.search().forResource(theResourceType);
if (theParamName != null) { // if (theParamName != null) {
forResource = forResource.where(new StringClientParam(theParamName).matches().value(theParamValue)); // forResource = forResource.where(new StringClientParam(theParamName).matches().value(theParamValue));
} // }
resources = forResource.execute(); // resources = forResource.execute();
for (IResource next : resources.toListOfResources()) { // for (IResource next : resources.toListOfResources()) {
ourLog.info("Deleting resource: {}", next.getId()); // ourLog.info("Deleting resource: {}", next.getId());
ourClient.delete().resource(next).execute(); // ourClient.delete().resource(next).execute();
} // }
} while (resources.size() > 0); // } while (resources.size() > 0);
} // }
//
private void deleteToken(String theResourceType, String theParamName, String theParamSystem, String theParamValue) { // private void deleteToken(String theResourceType, String theParamName, String theParamSystem, String theParamValue)
Bundle resources = ourClient.search().forResource(theResourceType).where(new TokenClientParam(theParamName).exactly().systemAndCode(theParamSystem, theParamValue)).execute(); // {
for (IResource next : resources.toListOfResources()) { // Bundle resources = ourClient.search().forResource(theResourceType).where(new
ourLog.info("Deleting resource: {}", next.getId()); // TokenClientParam(theParamName).exactly().systemAndCode(theParamSystem, theParamValue)).execute();
ourClient.delete().resource(next).execute(); // for (IResource next : resources.toListOfResources()) {
} // ourLog.info("Deleting resource: {}", next.getId());
} // ourClient.delete().resource(next).execute();
// }
// }
@Test @Test
public void testBundleCreate() throws Exception { public void testBundleCreate() throws Exception {
@ -172,7 +162,7 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
ca.uhn.fhir.model.dstu2.resource.Bundle bundle = client.read().resource(ca.uhn.fhir.model.dstu2.resource.Bundle.class).withId(id).execute(); ca.uhn.fhir.model.dstu2.resource.Bundle bundle = client.read().resource(ca.uhn.fhir.model.dstu2.resource.Bundle.class).withId(id).execute();
ourLog.info(ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(bundle)); ourLog.info(myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(bundle));
} }
@Test @Test
@ -192,7 +182,7 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
@Test @Test
public void testCountParam() throws Exception { public void testCountParam() throws Exception {
// NB this does not get used- The paging provider has its own limits built in // NB this does not get used- The paging provider has its own limits built in
ourDaoConfig.setHardSearchLimit(100); myDaoConfig.setHardSearchLimit(100);
List<IBaseResource> resources = new ArrayList<IBaseResource>(); List<IBaseResource> resources = new ArrayList<IBaseResource>();
for (int i = 0; i < 100; i++) { for (int i = 0; i < 100; i++) {
@ -250,7 +240,7 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
Patient pt = new Patient(); Patient pt = new Patient();
pt.addName().addFamily(methodName); pt.addName().addFamily(methodName);
String resource = ourCtx.newXmlParser().encodeResourceToString(pt); String resource = myFhirCtx.newXmlParser().encodeResourceToString(pt);
HttpPost post = new HttpPost(ourServerBase + "/Patient"); HttpPost post = new HttpPost(ourServerBase + "/Patient");
post.addHeader(Constants.HEADER_IF_NONE_EXIST, "Patient?name=" + methodName); post.addHeader(Constants.HEADER_IF_NONE_EXIST, "Patient?name=" + methodName);
@ -322,10 +312,6 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
@Test @Test
public void testDeepChaining() { public void testDeepChaining() {
delete("Location", Location.SP_NAME, "testDeepChainingL1");
delete("Location", Location.SP_NAME, "testDeepChainingL2");
deleteToken("Encounter", Encounter.SP_IDENTIFIER, "urn:foo", "testDeepChainingE1");
Location l1 = new Location(); Location l1 = new Location();
l1.getNameElement().setValue("testDeepChainingL1"); l1.getNameElement().setValue("testDeepChainingL1");
IIdType l1id = ourClient.create().resource(l1).execute().getId(); IIdType l1id = ourClient.create().resource(l1).execute().getId();
@ -365,7 +351,7 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
Patient pt = new Patient(); Patient pt = new Patient();
pt.addName().addFamily(methodName); pt.addName().addFamily(methodName);
String resource = ourCtx.newXmlParser().encodeResourceToString(pt); String resource = myFhirCtx.newXmlParser().encodeResourceToString(pt);
HttpPost post = new HttpPost(ourServerBase + "/Patient"); HttpPost post = new HttpPost(ourServerBase + "/Patient");
post.setEntity(new StringEntity(resource, ContentType.create(Constants.CT_FHIR_XML, "UTF-8"))); post.setEntity(new StringEntity(resource, ContentType.create(Constants.CT_FHIR_XML, "UTF-8")));
@ -409,7 +395,7 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
Patient pt = new Patient(); Patient pt = new Patient();
pt.addName().addFamily(methodName); pt.addName().addFamily(methodName);
pt.addIdentifier().setSystem("http://ghh.org/patient").setValue(methodName); pt.addIdentifier().setSystem("http://ghh.org/patient").setValue(methodName);
String resource = ourCtx.newXmlParser().encodeResourceToString(pt); String resource = myFhirCtx.newXmlParser().encodeResourceToString(pt);
HttpPost post = new HttpPost(ourServerBase + "/Patient"); HttpPost post = new HttpPost(ourServerBase + "/Patient");
post.setEntity(new StringEntity(resource, ContentType.create(Constants.CT_FHIR_XML, "UTF-8"))); post.setEntity(new StringEntity(resource, ContentType.create(Constants.CT_FHIR_XML, "UTF-8")));
@ -491,8 +477,8 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
*/ */
@Test @Test
public void testDocumentManifestResources() throws Exception { public void testDocumentManifestResources() throws Exception {
ourCtx.getResourceDefinition(Practitioner.class); myFhirCtx.getResourceDefinition(Practitioner.class);
ourCtx.getResourceDefinition(ca.uhn.fhir.model.dstu.resource.DocumentManifest.class); myFhirCtx.getResourceDefinition(ca.uhn.fhir.model.dstu.resource.DocumentManifest.class);
IGenericClient client = ourClient; IGenericClient client = ourClient;
@ -531,7 +517,7 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
@Test @Test
public void testEverythingDoesntRepeatPatient() throws Exception { public void testEverythingDoesntRepeatPatient() throws Exception {
ca.uhn.fhir.model.dstu2.resource.Bundle b; ca.uhn.fhir.model.dstu2.resource.Bundle b;
b = ourCtx.newJsonParser().parseResource(ca.uhn.fhir.model.dstu2.resource.Bundle.class, new InputStreamReader(ResourceProviderDstu2Test.class.getResourceAsStream("/bug147-bundle.json"))); b = myFhirCtx.newJsonParser().parseResource(ca.uhn.fhir.model.dstu2.resource.Bundle.class, new InputStreamReader(ResourceProviderDstu2Test.class.getResourceAsStream("/bug147-bundle.json")));
ca.uhn.fhir.model.dstu2.resource.Bundle resp = ourClient.transaction().withBundle(b).execute(); ca.uhn.fhir.model.dstu2.resource.Bundle resp = ourClient.transaction().withBundle(b).execute();
List<IdDt> ids = new ArrayList<IdDt>(); List<IdDt> ids = new ArrayList<IdDt>();
@ -600,7 +586,7 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
ca.uhn.fhir.model.dstu2.resource.Bundle resp = ourClient.transaction().withBundle(b).execute(); ca.uhn.fhir.model.dstu2.resource.Bundle resp = ourClient.transaction().withBundle(b).execute();
ourLog.info(ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(resp)); ourLog.info(myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(resp));
IdDt patientId = new IdDt(resp.getEntry().get(0).getResponse().getLocation()); IdDt patientId = new IdDt(resp.getEntry().get(0).getResponse().getLocation());
assertEquals("Patient", patientId.getResourceType()); assertEquals("Patient", patientId.getResourceType());
@ -794,17 +780,28 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
} }
@Test @Test
public void testSaveAndRetrieveExistingNarrative() { public void testSaveAndRetrieveExistingNarrativeJson() {
deleteToken("Patient", Patient.SP_IDENTIFIER, "urn:system", "testSaveAndRetrieveExistingNarrative01");
Patient p1 = new Patient(); Patient p1 = new Patient();
p1.getText().setStatus(ca.uhn.fhir.model.dstu2.valueset.NarrativeStatusEnum.GENERATED); p1.getText().setStatus(ca.uhn.fhir.model.dstu2.valueset.NarrativeStatusEnum.GENERATED);
p1.getText().getDiv().setValueAsString("<div>HELLO WORLD</div>"); p1.getText().getDiv().setValueAsString("<div>HELLO WORLD</div>");
p1.addIdentifier().setSystem("urn:system").setValue("testSaveAndRetrieveExistingNarrative01"); p1.addIdentifier().setSystem("urn:system").setValue("testSaveAndRetrieveExistingNarrative01");
IIdType newId = ourClient.create().resource(p1).execute().getId(); IIdType newId = ourClient.create().resource(p1).encodedJson().execute().getId();
Patient actual = ourClient.read(Patient.class, (UriDt) newId); Patient actual = ourClient.read().resource(Patient.class).withId(newId).encodedJson().execute();
assertEquals("<div>HELLO WORLD</div>", actual.getText().getDiv().getValueAsString());
}
@Test
public void testSaveAndRetrieveExistingNarrativeXml() {
Patient p1 = new Patient();
p1.getText().setStatus(ca.uhn.fhir.model.dstu2.valueset.NarrativeStatusEnum.GENERATED);
p1.getText().getDiv().setValueAsString("<div>HELLO WORLD</div>");
p1.addIdentifier().setSystem("urn:system").setValue("testSaveAndRetrieveExistingNarrative01");
IIdType newId = ourClient.create().resource(p1).encodedXml().execute().getId();
Patient actual = ourClient.read().resource(Patient.class).withId(newId).encodedXml().execute();
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\">HELLO WORLD</div>", actual.getText().getDiv().getValueAsString()); assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\">HELLO WORLD</div>", actual.getText().getDiv().getValueAsString());
} }
@ -856,9 +853,6 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
@Test @Test
public void testSearchByIdentifier() { public void testSearchByIdentifier() {
deleteToken("Patient", Patient.SP_IDENTIFIER, "urn:system", "testSearchByIdentifier01");
deleteToken("Patient", Patient.SP_IDENTIFIER, "urn:system", "testSearchByIdentifier02");
Patient p1 = new Patient(); Patient p1 = new Patient();
p1.addIdentifier().setSystem("urn:system").setValue("testSearchByIdentifier01"); p1.addIdentifier().setSystem("urn:system").setValue("testSearchByIdentifier01");
p1.addName().addFamily("testSearchByIdentifierFamily01").addGiven("testSearchByIdentifierGiven01"); p1.addName().addFamily("testSearchByIdentifierFamily01").addGiven("testSearchByIdentifierGiven01");
@ -888,7 +882,6 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
@Test @Test
public void testSearchByIdentifierWithoutSystem() { public void testSearchByIdentifierWithoutSystem() {
deleteToken("Patient", Patient.SP_IDENTIFIER, "", "testSearchByIdentifierWithoutSystem01");
Patient p1 = new Patient(); Patient p1 = new Patient();
p1.addIdentifier().setValue("testSearchByIdentifierWithoutSystem01"); p1.addIdentifier().setValue("testSearchByIdentifierWithoutSystem01");
@ -902,8 +895,6 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
@Test @Test
public void testSearchByResourceChain() { public void testSearchByResourceChain() {
delete("Organization", Organization.SP_NAME, "testSearchByResourceChainName01");
deleteToken("Patient", Patient.SP_IDENTIFIER, "urn:system", "testSearchByResourceChain01");
Organization o1 = new Organization(); Organization o1 = new Organization();
o1.setName("testSearchByResourceChainName01"); o1.setName("testSearchByResourceChainName01");
@ -1036,7 +1027,7 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
String resp = IOUtils.toString(response.getEntity().getContent()); String resp = IOUtils.toString(response.getEntity().getContent());
IOUtils.closeQuietly(response.getEntity().getContent()); IOUtils.closeQuietly(response.getEntity().getContent());
ourLog.info(resp); ourLog.info(resp);
ca.uhn.fhir.model.dstu2.resource.Bundle bundle = ourCtx.newXmlParser().parseResource(ca.uhn.fhir.model.dstu2.resource.Bundle.class, resp); ca.uhn.fhir.model.dstu2.resource.Bundle bundle = myFhirCtx.newXmlParser().parseResource(ca.uhn.fhir.model.dstu2.resource.Bundle.class, resp);
matches = bundle.getTotal(); matches = bundle.getTotal();
assertThat(matches, greaterThan(0)); assertThat(matches, greaterThan(0));
@ -1104,8 +1095,6 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
public void testSearchWithMissing() throws Exception { public void testSearchWithMissing() throws Exception {
ourLog.info("Starting testSearchWithMissing"); ourLog.info("Starting testSearchWithMissing");
delete("Organization", null, null);
String methodName = "testSearchWithMissing"; String methodName = "testSearchWithMissing";
Organization org = new Organization(); Organization org = new Organization();
@ -1334,15 +1323,15 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
// Read back directly from the DAO // Read back directly from the DAO
{ {
Organization returned = ourOrganizationDao.read(orgId); Organization returned = myOrganizationDao.read(orgId);
String val = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(returned); String val = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(returned);
ourLog.info(val); ourLog.info(val);
assertThat(val, containsString("<name value=\"測試醫院\"/>")); assertThat(val, containsString("<name value=\"測試醫院\"/>"));
} }
// Read back through the HTTP API // Read back through the HTTP API
{ {
Organization returned = ourClient.read(Organization.class, orgId); Organization returned = ourClient.read(Organization.class, orgId);
String val = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(returned); String val = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(returned);
ourLog.info(val); ourLog.info(val);
assertThat(val, containsString("<name value=\"測試醫院\"/>")); assertThat(val, containsString("<name value=\"測試醫院\"/>"));
} }
@ -1350,8 +1339,6 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
@Test @Test
public void testTryToCreateResourceWithReferenceThatDoesntExist() { public void testTryToCreateResourceWithReferenceThatDoesntExist() {
deleteToken("Patient", Patient.SP_IDENTIFIER, "urn:system", "testTryToCreateResourceWithReferenceThatDoesntExist01");
Patient p1 = new Patient(); Patient p1 = new Patient();
p1.addIdentifier().setSystem("urn:system").setValue("testTryToCreateResourceWithReferenceThatDoesntExist01"); p1.addIdentifier().setSystem("urn:system").setValue("testTryToCreateResourceWithReferenceThatDoesntExist01");
p1.addName().addFamily("testTryToCreateResourceWithReferenceThatDoesntExistFamily01").addGiven("testTryToCreateResourceWithReferenceThatDoesntExistGiven01"); p1.addName().addFamily("testTryToCreateResourceWithReferenceThatDoesntExistFamily01").addGiven("testTryToCreateResourceWithReferenceThatDoesntExistGiven01");
@ -1366,9 +1353,9 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
} }
@Test @Test
public void testUpdateRejectsInvalidTypes() throws InterruptedException { public void testUpdateRejectsInvalidTypes() throws InterruptedException {
deleteToken("Patient", Patient.SP_IDENTIFIER, "urn:system", "testUpdateRejectsInvalidTypes");
Patient p1 = new Patient(); Patient p1 = new Patient();
p1.addIdentifier().setSystem("urn:system").setValue("testUpdateRejectsInvalidTypes"); p1.addIdentifier().setSystem("urn:system").setValue("testUpdateRejectsInvalidTypes");
@ -1399,7 +1386,7 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
Patient pt = new Patient(); Patient pt = new Patient();
pt.addName().addFamily(methodName); pt.addName().addFamily(methodName);
String resource = ourCtx.newXmlParser().encodeResourceToString(pt); String resource = myFhirCtx.newXmlParser().encodeResourceToString(pt);
HttpPost post = new HttpPost(ourServerBase + "/Patient?name=" + methodName); HttpPost post = new HttpPost(ourServerBase + "/Patient?name=" + methodName);
post.setEntity(new StringEntity(resource, ContentType.create(Constants.CT_FHIR_XML, "UTF-8"))); post.setEntity(new StringEntity(resource, ContentType.create(Constants.CT_FHIR_XML, "UTF-8")));
@ -1434,7 +1421,7 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
Patient pt = new Patient(); Patient pt = new Patient();
pt.addName().addFamily(methodName); pt.addName().addFamily(methodName);
String resource = ourCtx.newXmlParser().encodeResourceToString(pt); String resource = myFhirCtx.newXmlParser().encodeResourceToString(pt);
HttpPost post = new HttpPost(ourServerBase + "/Patient"); HttpPost post = new HttpPost(ourServerBase + "/Patient");
post.setEntity(new StringEntity(resource, ContentType.create(Constants.CT_FHIR_XML, "UTF-8"))); post.setEntity(new StringEntity(resource, ContentType.create(Constants.CT_FHIR_XML, "UTF-8")));
@ -1461,7 +1448,7 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
String responseString = IOUtils.toString(response.getEntity().getContent()); String responseString = IOUtils.toString(response.getEntity().getContent());
IOUtils.closeQuietly(response.getEntity().getContent()); IOUtils.closeQuietly(response.getEntity().getContent());
Patient respPt = ourCtx.newXmlParser().parseResource(Patient.class, responseString); Patient respPt = myFhirCtx.newXmlParser().parseResource(Patient.class, responseString);
assertEquals("2", respPt.getId().getVersionIdPart()); assertEquals("2", respPt.getId().getVersionIdPart());
InstantDt updateTime = ResourceMetadataKeyEnum.UPDATED.get(respPt); InstantDt updateTime = ResourceMetadataKeyEnum.UPDATED.get(respPt);
@ -1475,8 +1462,6 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
@Test @Test
public void testUpdateWithClientSuppliedIdWhichDoesntExist() { public void testUpdateWithClientSuppliedIdWhichDoesntExist() {
deleteToken("Patient", Patient.SP_IDENTIFIER, "urn:system", "testUpdateWithClientSuppliedIdWhichDoesntExistRpDstu2");
Patient p1 = new Patient(); Patient p1 = new Patient();
p1.addIdentifier().setSystem("urn:system").setValue("testUpdateWithClientSuppliedIdWhichDoesntExistRpDstu2"); p1.addIdentifier().setSystem("urn:system").setValue("testUpdateWithClientSuppliedIdWhichDoesntExistRpDstu2");
MethodOutcome outcome = ourClient.update().resource(p1).withId("testUpdateWithClientSuppliedIdWhichDoesntExistRpDstu2").execute(); MethodOutcome outcome = ourClient.update().resource(p1).withId("testUpdateWithClientSuppliedIdWhichDoesntExistRpDstu2").execute();
@ -1501,7 +1486,7 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
Parameters input = new Parameters(); Parameters input = new Parameters();
input.addParameter().setName("resource").setResource(patient); input.addParameter().setName("resource").setResource(patient);
String inputStr = ourCtx.newXmlParser().encodeResourceToString(input); String inputStr = myFhirCtx.newXmlParser().encodeResourceToString(input);
ourLog.info(inputStr); ourLog.info(inputStr);
HttpPost post = new HttpPost(ourServerBase + "/Patient/$validate"); HttpPost post = new HttpPost(ourServerBase + "/Patient/$validate");
@ -1529,7 +1514,7 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
Parameters input = new Parameters(); Parameters input = new Parameters();
input.addParameter().setName("resource").setResource(patient); input.addParameter().setName("resource").setResource(patient);
String inputStr = ourCtx.newXmlParser().encodeResourceToString(input); String inputStr = myFhirCtx.newXmlParser().encodeResourceToString(input);
ourLog.info(inputStr); ourLog.info(inputStr);
HttpPost post = new HttpPost(ourServerBase + "/Patient/$validate"); HttpPost post = new HttpPost(ourServerBase + "/Patient/$validate");
@ -1556,7 +1541,7 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
Parameters input = new Parameters(); Parameters input = new Parameters();
input.addParameter().setName("resource").setResource(patient); input.addParameter().setName("resource").setResource(patient);
String inputStr = ourCtx.newXmlParser().encodeResourceToString(input); String inputStr = myFhirCtx.newXmlParser().encodeResourceToString(input);
ourLog.info(inputStr); ourLog.info(inputStr);
HttpPost post = new HttpPost(ourServerBase + "/Patient/123/$validate"); HttpPost post = new HttpPost(ourServerBase + "/Patient/123/$validate");
@ -1576,7 +1561,7 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
@Test @Test
public void testValueSetExpandOperation() throws IOException { public void testValueSetExpandOperation() throws IOException {
ValueSet upload = ourCtx.newXmlParser().parseResource(ValueSet.class, new InputStreamReader(ResourceProviderDstu2Test.class.getResourceAsStream("/extensional-case-2.xml"))); ValueSet upload = myFhirCtx.newXmlParser().parseResource(ValueSet.class, new InputStreamReader(ResourceProviderDstu2Test.class.getResourceAsStream("/extensional-case-2.xml")));
IIdType vsid = ourClient.create().resource(upload).execute().getId().toUnqualifiedVersionless(); IIdType vsid = ourClient.create().resource(upload).execute().getId().toUnqualifiedVersionless();
HttpGet get = new HttpGet(ourServerBase + "/ValueSet/" + vsid.getIdPart() + "/$expand"); HttpGet get = new HttpGet(ourServerBase + "/ValueSet/" + vsid.getIdPart() + "/$expand");
@ -1673,42 +1658,40 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
@AfterClass @AfterClass
public static void afterClass() throws Exception { public static void afterClass() throws Exception {
ourServer.stop(); ourServer.stop();
ourAppCtx.stop();
ourHttpClient.close(); ourHttpClient.close();
} }
@SuppressWarnings("unchecked") @After
@BeforeClass public void after() {
public static void beforeClass() throws Exception { myFhirCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.ONCE);
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Before
public void before() throws Exception {
myFhirCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER);
myFhirCtx.getRestfulClientFactory().setSocketTimeout(1200 * 1000);
if (ourServer == null) {
ourPort = RandomServerPortProvider.findFreePort(); ourPort = RandomServerPortProvider.findFreePort();
RestfulServer restServer = new RestfulServer(ourCtx); RestfulServer restServer = new RestfulServer(myFhirCtx);
restServer.setFhirContext(ourCtx);
ourServerBase = "http://localhost:" + ourPort + "/fhir/context"; ourServerBase = "http://localhost:" + ourPort + "/fhir/context";
ourAppCtx = new ClassPathXmlApplicationContext("hapi-fhir-server-resourceproviders-dstu2.xml", "fhir-jpabase-spring-test-config.xml"); restServer.setResourceProviders((List)myResourceProviders);
ourDaoConfig = (DaoConfig) ourAppCtx.getBean(DaoConfig.class);
ourOrganizationDao = (IFhirResourceDao<Organization>) ourAppCtx.getBean("myOrganizationDaoDstu2", IFhirResourceDao.class);
List<IResourceProvider> rpsDev = (List<IResourceProvider>) ourAppCtx.getBean("myResourceProvidersDstu2", List.class);
restServer.setResourceProviders(rpsDev);
restServer.getFhirContext().setNarrativeGenerator(new DefaultThymeleafNarrativeGenerator()); restServer.getFhirContext().setNarrativeGenerator(new DefaultThymeleafNarrativeGenerator());
JpaSystemProviderDstu2 systemProv = ourAppCtx.getBean(JpaSystemProviderDstu2.class, "mySystemProviderDstu2"); restServer.setPlainProviders(mySystemProvider);
restServer.setPlainProviders(systemProv);
IFhirSystemDao<ca.uhn.fhir.model.dstu2.resource.Bundle> systemDao = ourAppCtx.getBean(IFhirSystemDao.class); JpaConformanceProviderDstu2 confProvider = new JpaConformanceProviderDstu2(restServer, mySystemDao);
JpaConformanceProviderDstu2 confProvider = new JpaConformanceProviderDstu2(restServer, systemDao);
confProvider.setImplementationDescription("THIS IS THE DESC"); confProvider.setImplementationDescription("THIS IS THE DESC");
restServer.setServerConformanceProvider(confProvider); restServer.setServerConformanceProvider(confProvider);
restServer.setPagingProvider(new FifoMemoryPagingProvider(10)); restServer.setPagingProvider(new FifoMemoryPagingProvider(10));
ourServer = new Server(ourPort); Server server = new Server(ourPort);
ServletContextHandler proxyHandler = new ServletContextHandler(); ServletContextHandler proxyHandler = new ServletContextHandler();
proxyHandler.setContextPath("/"); proxyHandler.setContextPath("/");
@ -1717,12 +1700,10 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
servletHolder.setServlet(restServer); servletHolder.setServlet(restServer);
proxyHandler.addServlet(servletHolder, "/fhir/context/*"); proxyHandler.addServlet(servletHolder, "/fhir/context/*");
ourServer.setHandler(proxyHandler); server.setHandler(proxyHandler);
ourServer.start(); server.start();
ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER); ourClient = myFhirCtx.newRestfulGenericClient(ourServerBase);
ourCtx.getRestfulClientFactory().setSocketTimeout(1200 * 1000);
ourClient = ourCtx.newRestfulGenericClient(ourServerBase);
ourClient.registerInterceptor(new LoggingInterceptor(true)); ourClient.registerInterceptor(new LoggingInterceptor(true));
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(5000, TimeUnit.MILLISECONDS); PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(5000, TimeUnit.MILLISECONDS);
@ -1730,6 +1711,8 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
builder.setConnectionManager(connectionManager); builder.setConnectionManager(connectionManager);
ourHttpClient = builder.build(); ourHttpClient = builder.build();
ourServer = server;
}
} }
} }

View File

@ -186,6 +186,9 @@
JPA server now correctly suppresses contents of deleted resources JPA server now correctly suppresses contents of deleted resources
in history in history
</action> </action>
<action type="fix" issue="222">
JPA server returned deleted resources in search results when using the _tag, _id, _profile, or _security search parameters
</action>
</release> </release>
<release version="1.1" date="2015-07-13"> <release version="1.1" date="2015-07-13">
<action type="add"> <action type="add">

View File

@ -26,7 +26,7 @@
<li> <li>
<b>Resource Validation</b> <b>Resource Validation</b>
is validation of the parsed (or constructed) resource against is validation of the parsed (or constructed) resource against
the official FHIR validation rules (e.g. Schema/Schematron). the official FHIR validation rules (e.g. Schema/Schematron/Profile/StructureDefinition/ValueSet).
</li> </li>
</ul> </ul>