Support inline match URL references, per Simone's requast for the next
connectathon
This commit is contained in:
parent
1f875c1ca6
commit
1ba0ae3960
|
@ -43,6 +43,9 @@ ca.uhn.fhir.validation.ValidationResult.noIssuesDetected=No issues detected duri
|
|||
# JPA Messages
|
||||
|
||||
ca.uhn.fhir.jpa.dao.BaseHapiFhirDao.incomingNoopInTransaction=Transaction contains resource with operation NOOP. This is only valid as a response operation, not in a request.
|
||||
ca.uhn.fhir.jpa.dao.BaseHapiFhirDao.invalidMatchUrlInvalidResourceType=Invalid match URL "{0}" - Unknown resource type: "{1}"
|
||||
ca.uhn.fhir.jpa.dao.BaseHapiFhirDao.invalidMatchUrlNoMatches=Invalid match URL "{0}" - No resources match this search
|
||||
ca.uhn.fhir.jpa.dao.BaseHapiFhirDao.invalidMatchUrlMultipleMatches=Invalid match URL "{0}" - Multiple resources match this search
|
||||
ca.uhn.fhir.jpa.dao.BaseHapiFhirDao.transactionOperationWithMultipleMatchFailure=Failed to {0} resource with match URL "{1}" because this search matched {2} resources
|
||||
ca.uhn.fhir.jpa.dao.BaseHapiFhirDao.transactionOperationFailedNoId=Failed to {0} resource in transaction because no ID was provided
|
||||
ca.uhn.fhir.jpa.dao.BaseHapiFhirDao.transactionOperationFailedUnknownId=Failed to {0} resource in transaction because no resource could be found with ID {1}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -34,6 +34,32 @@ import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
|
|||
|
||||
public class DaoConfig {
|
||||
|
||||
// ***
|
||||
// update setter javadoc if default changes
|
||||
// ***
|
||||
private boolean myAllowInlineMatchUrlReferences = false;
|
||||
|
||||
/**
|
||||
* @see #setAllowInlineMatchUrlReferences(boolean)
|
||||
*/
|
||||
public boolean isAllowInlineMatchUrlReferences() {
|
||||
return myAllowInlineMatchUrlReferences;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should references containing match URLs be resolved and replaced in create and update operations. For
|
||||
* example, if this property is set to true and a resource is created containing a reference
|
||||
* to "Patient?identifier=12345", this is reference match URL will be resolved and replaced according
|
||||
* to the usual match URL rules.
|
||||
* <p>
|
||||
* Default is false for now, as this is an experimental feature.
|
||||
* </p>
|
||||
* @since 1.5
|
||||
*/
|
||||
public void setAllowInlineMatchUrlReferences(boolean theAllowInlineMatchUrlReferences) {
|
||||
myAllowInlineMatchUrlReferences = theAllowInlineMatchUrlReferences;
|
||||
}
|
||||
|
||||
private boolean myAllowMultipleDelete;
|
||||
private int myHardSearchLimit = 1000;
|
||||
private int myHardTagListLimit = 1000;
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
package ca.uhn.fhir.jpa.dao.data;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR JPA Server
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2016 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
|
||||
import ca.uhn.fhir.jpa.entity.ForcedId;
|
||||
|
||||
public interface IForcedIdDao extends JpaRepository<ForcedId, Long> {
|
||||
|
||||
@Query("SELECT f FROM ForcedId f WHERE f.myResourcePid = :resource_pid")
|
||||
public ForcedId findByResourcePid(@Param("resource_pid") Long theResourcePid);
|
||||
|
||||
}
|
|
@ -462,7 +462,7 @@ public class FhirSystemDaoDstu3 extends BaseHapiFhirSystemDao<Bundle, Meta> {
|
|||
|
||||
FhirTerser terser = getContext().newTerser();
|
||||
for (DaoMethodOutcome nextOutcome : idToPersistedOutcome.values()) {
|
||||
IBaseResource nextResource = (IBaseResource) nextOutcome.getResource();
|
||||
IBaseResource nextResource = nextOutcome.getResource();
|
||||
if (nextResource == null) {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -35,7 +35,8 @@ import javax.persistence.UniqueConstraint;
|
|||
//@formatter:off
|
||||
@Entity()
|
||||
@Table(name = "HFJ_FORCED_ID", uniqueConstraints = {
|
||||
@UniqueConstraint(name = "IDX_FORCEDID", columnNames = {"FORCED_ID"})
|
||||
@UniqueConstraint(name = "IDX_FORCEDID", columnNames = {"FORCED_ID"}),
|
||||
@UniqueConstraint(name = "IDX_FORCEDID_RESID", columnNames = {"RESOURCE_PID"})
|
||||
})
|
||||
@NamedQueries(value = {
|
||||
@NamedQuery(name = "Q_GET_FORCED_ID", query = "SELECT f FROM ForcedId f WHERE myForcedId = :ID")
|
||||
|
|
|
@ -17,10 +17,8 @@ import static org.mockito.Matchers.eq;
|
|||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
@ -44,8 +42,10 @@ import org.hl7.fhir.dstu3.model.UriType;
|
|||
import org.hl7.fhir.dstu3.model.ValueSet;
|
||||
import org.hl7.fhir.instance.model.api.IAnyResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.springframework.transaction.TransactionDefinition;
|
||||
import org.springframework.transaction.TransactionStatus;
|
||||
import org.springframework.transaction.support.TransactionCallback;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
@ -113,7 +113,7 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest {
|
|||
// Try making the resource unparseable
|
||||
|
||||
TransactionTemplate template = new TransactionTemplate(myTxManager);
|
||||
template.setPropagationBehavior(TransactionTemplate.PROPAGATION_REQUIRES_NEW);
|
||||
template.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
|
||||
template.execute(new TransactionCallback<ResourceTable>() {
|
||||
@Override
|
||||
public ResourceTable doInTransaction(TransactionStatus theStatus) {
|
||||
|
@ -300,12 +300,106 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest {
|
|||
assertThat(respEntry.getResponse().getLocation(), endsWith("/_history/1"));
|
||||
assertEquals("1", respEntry.getResponse().getEtag());
|
||||
|
||||
o = (Observation) myObservationDao.read(new IdType(respEntry.getResponse().getLocationElement()));
|
||||
o = myObservationDao.read(new IdType(respEntry.getResponse().getLocationElement()));
|
||||
assertEquals(id.toVersionless().getValue(), o.getSubject().getReference());
|
||||
assertEquals("1", o.getIdElement().getVersionIdPart());
|
||||
|
||||
}
|
||||
|
||||
@After
|
||||
public void after() {
|
||||
myDaoConfig.setAllowInlineMatchUrlReferences(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTransactionCreateInlineMatchUrlWithOneMatch() {
|
||||
String methodName = "testTransactionCreateInlineMatchUrlWithOneMatch";
|
||||
Bundle request = new Bundle();
|
||||
|
||||
myDaoConfig.setAllowInlineMatchUrlReferences(true);
|
||||
|
||||
Patient p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.setId("Patient/" + methodName);
|
||||
IIdType id = myPatientDao.update(p).getId();
|
||||
ourLog.info("Created patient, got it: {}", id);
|
||||
|
||||
Observation o = new Observation();
|
||||
o.getCode().setText("Some Observation");
|
||||
o.getSubject().setReference("Patient?identifier=urn%3Asystem%7C" + methodName);
|
||||
request.addEntry().setResource(o).getRequest().setMethod(HTTPVerb.POST);
|
||||
|
||||
Bundle resp = mySystemDao.transaction(myRequestDetails, request);
|
||||
assertEquals(1, resp.getEntry().size());
|
||||
|
||||
BundleEntryComponent respEntry = resp.getEntry().get(0);
|
||||
assertEquals(Constants.STATUS_HTTP_201_CREATED + " Created", respEntry.getResponse().getStatus());
|
||||
assertThat(respEntry.getResponse().getLocation(), containsString("Observation/"));
|
||||
assertThat(respEntry.getResponse().getLocation(), endsWith("/_history/1"));
|
||||
assertEquals("1", respEntry.getResponse().getEtag());
|
||||
|
||||
o = myObservationDao.read(new IdType(respEntry.getResponse().getLocationElement()));
|
||||
assertEquals(id.toVersionless().getValue(), o.getSubject().getReference());
|
||||
assertEquals("1", o.getIdElement().getVersionIdPart());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTransactionCreateInlineMatchUrlWithNoMatches() {
|
||||
String methodName = "testTransactionCreateInlineMatchUrlWithNoMatches";
|
||||
Bundle request = new Bundle();
|
||||
|
||||
myDaoConfig.setAllowInlineMatchUrlReferences(true);
|
||||
|
||||
Patient p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
myPatientDao.create(p).getId();
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
myPatientDao.create(p).getId();
|
||||
|
||||
Observation o = new Observation();
|
||||
o.getCode().setText("Some Observation");
|
||||
o.getSubject().setReference("Patient?identifier=urn%3Asystem%7C" + methodName);
|
||||
request.addEntry().setResource(o).getRequest().setMethod(HTTPVerb.POST);
|
||||
|
||||
try {
|
||||
mySystemDao.transaction(myRequestDetails, request);
|
||||
fail();
|
||||
} catch (InvalidRequestException e) {
|
||||
assertEquals("Invalid match URL \"Patient?identifier=urn%3Asystem%7CtestTransactionCreateInlineMatchUrlWithNoMatches\" - Multiple resources match this search", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTransactionCreateInlineMatchUrlWithTwoMatches() {
|
||||
String methodName = "testTransactionCreateInlineMatchUrlWithTwoMatches";
|
||||
Bundle request = new Bundle();
|
||||
|
||||
myDaoConfig.setAllowInlineMatchUrlReferences(true);
|
||||
|
||||
Patient p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
myPatientDao.create(p).getId();
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
myPatientDao.create(p).getId();
|
||||
|
||||
Observation o = new Observation();
|
||||
o.getCode().setText("Some Observation");
|
||||
o.getSubject().setReference("Patient?identifier=urn%3Asystem%7C" + methodName);
|
||||
request.addEntry().setResource(o).getRequest().setMethod(HTTPVerb.POST);
|
||||
|
||||
try {
|
||||
mySystemDao.transaction(myRequestDetails, request);
|
||||
fail();
|
||||
} catch (InvalidRequestException e) {
|
||||
assertEquals("Invalid match URL \"Patient?identifier=urn%3Asystem%7CtestTransactionCreateInlineMatchUrlWithTwoMatches\" - Multiple resources match this search", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTransactionCreateMatchUrlWithTwoMatch() {
|
||||
String methodName = "testTransactionCreateMatchUrlWithTwoMatch";
|
||||
|
@ -374,7 +468,7 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest {
|
|||
assertThat(respEntry.getResponse().getLocation(), endsWith("/_history/1"));
|
||||
assertEquals("1", respEntry.getResponse().getEtag());
|
||||
|
||||
o = (Observation) myObservationDao.read(new IdType(respEntry.getResponse().getLocationElement()));
|
||||
o = myObservationDao.read(new IdType(respEntry.getResponse().getLocationElement()));
|
||||
assertEquals(new IdType(patientId).toUnqualifiedVersionless().getValue(), o.getSubject().getReference());
|
||||
}
|
||||
|
||||
|
|
|
@ -50,6 +50,7 @@ public class TestDstu2Config extends BaseJavaConfigDstu2 {
|
|||
retVal.setSubscriptionPollDelay(5000);
|
||||
retVal.setSubscriptionPurgeInactiveAfterMillis(DateUtils.MILLIS_PER_HOUR);
|
||||
retVal.setAllowMultipleDelete(true);
|
||||
retVal.setAllowInlineMatchUrlReferences(true);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
|
|
@ -46,6 +46,7 @@ public class TestDstu3Config extends BaseJavaConfigDstu3 {
|
|||
retVal.setSubscriptionPollDelay(5000);
|
||||
retVal.setSubscriptionPurgeInactiveAfterMillis(DateUtils.MILLIS_PER_HOUR);
|
||||
retVal.setAllowMultipleDelete(true);
|
||||
retVal.setAllowInlineMatchUrlReferences(true);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
|
|
@ -59,6 +59,13 @@
|
|||
<action type="add">
|
||||
JPA server now supports :above and :below qualifiers on URI search params
|
||||
</action>
|
||||
<action type="add">
|
||||
Add optional support (disabled by default for now) to JPA server to support
|
||||
inline references containing search URLs. These URLs will be resolved when
|
||||
a resource is being created/updated and replaced with the single matching
|
||||
resource. This is being used as a part of the May 2016 Connectathon for
|
||||
a testing scenario.
|
||||
</action>
|
||||
</release>
|
||||
<release version="1.4" date="2016-02-04">
|
||||
<action type="add">
|
||||
|
|
Loading…
Reference in New Issue