From cca49425ae291d5bf5d04337b8e27f784c66157c Mon Sep 17 00:00:00 2001 From: James Agnew Date: Thu, 8 Nov 2018 08:56:51 -0500 Subject: [PATCH] Some work on collection processing --- .../fhir/jpa/dao/TransactionProcessor.java | 91 ++++++++++++------ ...ansactionProcessorVersionAdapterDstu3.java | 10 ++ .../TransactionProcessorVersionAdapterR4.java | 20 +++- .../jpa/dao/dstu3/FhirSystemDaoDstu3Test.java | 19 ++++ .../resources/dstu3/Reilly_Libby_73.json.gz | Bin 0 -> 29111 bytes 5 files changed, 107 insertions(+), 33 deletions(-) create mode 100644 hapi-fhir-jpaserver-base/src/test/resources/dstu3/Reilly_Libby_73.json.gz diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/TransactionProcessor.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/TransactionProcessor.java index bec7998d5cc..dc1fe622d3c 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/TransactionProcessor.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/TransactionProcessor.java @@ -9,9 +9,9 @@ package ca.uhn.fhir.jpa.dao; * 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. @@ -43,10 +43,7 @@ import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor; import ca.uhn.fhir.rest.server.method.BaseMethodBinding; import ca.uhn.fhir.rest.server.method.BaseResourceReturningMethodBinding; import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails; -import ca.uhn.fhir.util.FhirTerser; -import ca.uhn.fhir.util.ResourceReferenceInfo; -import ca.uhn.fhir.util.StopWatch; -import ca.uhn.fhir.util.UrlUtil; +import ca.uhn.fhir.util.*; import com.google.common.collect.ArrayListMultimap; import org.apache.commons.lang3.Validate; import org.apache.http.NameValuePair; @@ -86,17 +83,6 @@ public class TransactionProcessor { @Autowired private DaoRegistry myDaoRegistry; - public static boolean isPlaceholder(IIdType theId) { - if (theId != null && theId.getValue() != null) { - return theId.getValue().startsWith("urn:oid:") || theId.getValue().startsWith("urn:uuid:"); - } - return false; - } - - private static String toStatusString(int theStatusCode) { - return Integer.toString(theStatusCode) + " " + defaultString(Constants.HTTP_STATUS_NAMES.get(theStatusCode)); - } - private void populateEntryWithOperationOutcome(BaseServerResponseException caughtEx, BUNDLEENTRY nextEntry) { myVersionAdapter.populateEntryWithOperationOutcome(caughtEx, nextEntry); } @@ -164,7 +150,6 @@ public class TransactionProcessor { return defaultString(theId.getValue()).startsWith(URN_PREFIX); } - public void setDao(BaseHapiFhirDao theDao) { myDao = theDao; } @@ -188,6 +173,40 @@ public class TransactionProcessor { } } + public BUNDLE collection(final RequestDetails theRequestDetails, BUNDLE theRequest) { + String transactionType = myVersionAdapter.getBundleType(theRequest); + + if (!org.hl7.fhir.r4.model.Bundle.BundleType.COLLECTION.toCode().equals(transactionType)) { + throw new InvalidRequestException("Can not process collection Bundle of type: " + transactionType); + } + + ourLog.info("Beginning storing collection with {} resources", myVersionAdapter.getEntries(theRequest).size()); + long start = System.currentTimeMillis(); + + TransactionTemplate txTemplate = new TransactionTemplate(myTxManager); + txTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); + + BUNDLE resp = myVersionAdapter.createBundle(org.hl7.fhir.r4.model.Bundle.BundleType.BATCHRESPONSE.toCode()); + + List resources = new ArrayList<>(); + for (final BUNDLEENTRY nextRequestEntry : myVersionAdapter.getEntries(theRequest)) { + IBaseResource resource = myVersionAdapter.getResource(nextRequestEntry); + resources.add(resource); + } + + BUNDLE transactionBundle = myVersionAdapter.createBundle("transaction"); + for (IBaseResource next : resources) { + BUNDLEENTRY entry = myVersionAdapter.addEntry(transactionBundle); + myVersionAdapter.setResource(entry, next); + myVersionAdapter.setRequestVerb(entry, "PUT"); + myVersionAdapter.setRequestUrl(entry, next.getIdElement().toUnqualifiedVersionless().getValue()); + } + + transaction(theRequestDetails, transactionBundle); + + return resp; + } + private BUNDLE batch(final RequestDetails theRequestDetails, BUNDLE theRequest) { ourLog.info("Beginning batch with {} resources", myVersionAdapter.getEntries(theRequest).size()); long start = System.currentTimeMillis(); @@ -255,6 +274,7 @@ public class TransactionProcessor { validateDependencies(); String transactionType = myVersionAdapter.getBundleType(theRequest); + if (org.hl7.fhir.r4.model.Bundle.BundleType.BATCH.toCode().equals(transactionType)) { return batch(theRequestDetails, theRequest); } @@ -846,18 +866,10 @@ public class TransactionProcessor { String getEntryRequestIfNoneMatch(BUNDLEENTRY theEntry); void setResponseOutcome(BUNDLEENTRY theEntry, IBaseOperationOutcome theOperationOutcome); - } - private static class BaseServerResponseExceptionHolder { - private BaseServerResponseException myException; + void setRequestVerb(BUNDLEENTRY theEntry, String theVerb); - public BaseServerResponseException getException() { - return myException; - } - - public void setException(BaseServerResponseException myException) { - this.myException = myException; - } + void setRequestUrl(BUNDLEENTRY theEntry, String theUrl); } /** @@ -963,4 +975,27 @@ public class TransactionProcessor { } + private static class BaseServerResponseExceptionHolder { + private BaseServerResponseException myException; + + public BaseServerResponseException getException() { + return myException; + } + + public void setException(BaseServerResponseException myException) { + this.myException = myException; + } + } + + public static boolean isPlaceholder(IIdType theId) { + if (theId != null && theId.getValue() != null) { + return theId.getValue().startsWith("urn:oid:") || theId.getValue().startsWith("urn:uuid:"); + } + return false; + } + + private static String toStatusString(int theStatusCode) { + return Integer.toString(theStatusCode) + " " + defaultString(Constants.HTTP_STATUS_NAMES.get(theStatusCode)); + } + } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/dstu3/TransactionProcessorVersionAdapterDstu3.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/dstu3/TransactionProcessorVersionAdapterDstu3.java index ddb198db705..0a98816c6c0 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/dstu3/TransactionProcessorVersionAdapterDstu3.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/dstu3/TransactionProcessorVersionAdapterDstu3.java @@ -150,4 +150,14 @@ public class TransactionProcessorVersionAdapterDstu3 implements TransactionProce theEntry.getResponse().setOutcome((Resource) theOperationOutcome); } + @Override + public void setRequestVerb(Bundle.BundleEntryComponent theEntry, String theVerb) { + theEntry.getRequest().setMethod(Bundle.HTTPVerb.fromCode(theVerb)); + } + + @Override + public void setRequestUrl(Bundle.BundleEntryComponent theEntry, String theUrl) { + theEntry.getRequest().setUrl(theUrl); + } + } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/TransactionProcessorVersionAdapterR4.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/TransactionProcessorVersionAdapterR4.java index db5be3e65c0..a9b510b9876 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/TransactionProcessorVersionAdapterR4.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/TransactionProcessorVersionAdapterR4.java @@ -9,9 +9,9 @@ package ca.uhn.fhir.jpa.dao.r4; * 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. @@ -23,12 +23,12 @@ package ca.uhn.fhir.jpa.dao.r4; import ca.uhn.fhir.jpa.dao.TransactionProcessor; import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; -import org.hl7.fhir.r4.model.Bundle; -import org.hl7.fhir.r4.model.OperationOutcome; -import org.hl7.fhir.r4.model.Resource; import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.instance.model.api.IBaseOperationOutcome; import org.hl7.fhir.instance.model.api.IBaseResource; +import org.hl7.fhir.r4.model.Bundle; +import org.hl7.fhir.r4.model.OperationOutcome; +import org.hl7.fhir.r4.model.Resource; import java.util.Date; import java.util.List; @@ -150,4 +150,14 @@ public class TransactionProcessorVersionAdapterR4 implements TransactionProcesso theEntry.getResponse().setOutcome((Resource) theOperationOutcome); } + @Override + public void setRequestVerb(Bundle.BundleEntryComponent theEntry, String theVerb) { + theEntry.getRequest().setMethod(Bundle.HTTPVerb.fromCode(theVerb)); + } + + @Override + public void setRequestUrl(Bundle.BundleEntryComponent theEntry, String theUrl) { + theEntry.getRequest().setUrl(theUrl); + } + } diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirSystemDaoDstu3Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirSystemDaoDstu3Test.java index effc8d746bd..68dc1ec6bd6 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirSystemDaoDstu3Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirSystemDaoDstu3Test.java @@ -2,12 +2,14 @@ package ca.uhn.fhir.jpa.dao.dstu3; import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao; import ca.uhn.fhir.jpa.dao.DaoConfig; +import ca.uhn.fhir.jpa.dao.GZipUtil; import ca.uhn.fhir.jpa.dao.SearchParameterMap; import ca.uhn.fhir.jpa.entity.ResourceTag; import ca.uhn.fhir.jpa.entity.TagTypeEnum; import ca.uhn.fhir.jpa.provider.SystemProviderDstu2Test; import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum; import ca.uhn.fhir.model.primitive.IdDt; +import ca.uhn.fhir.parser.LenientErrorHandler; import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.api.RestOperationTypeEnum; import ca.uhn.fhir.rest.api.server.IBundleProvider; @@ -52,6 +54,7 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest { public void after() { myDaoConfig.setAllowInlineMatchUrlReferences(false); myDaoConfig.setAllowMultipleDelete(new DaoConfig().isAllowMultipleDelete()); + myDaoConfig.setProcessCollectionsAsBatch(new DaoConfig().isProcessCollectionsAsBatch()); } @Before @@ -322,6 +325,22 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest { } + + @Test + public void testProcessCollectionAsBatch() throws IOException { + myDaoConfig.setProcessCollectionsAsBatch(true); + + byte[] inputBytes = IOUtils.toByteArray(getClass().getResourceAsStream("/dstu3/Reilly_Libby_73.json.gz")); + String input = GZipUtil.decompress(inputBytes); + Bundle bundle = myFhirCtx.newJsonParser().setParserErrorHandler(new LenientErrorHandler()).parseResource(Bundle.class, input); + ourLog.info("Bundle has {} resources", bundle); + + Bundle output = mySystemDao.transaction(mySrd, bundle); + ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(output)); + } + + + /** * See #410 */ diff --git a/hapi-fhir-jpaserver-base/src/test/resources/dstu3/Reilly_Libby_73.json.gz b/hapi-fhir-jpaserver-base/src/test/resources/dstu3/Reilly_Libby_73.json.gz new file mode 100644 index 0000000000000000000000000000000000000000..17ab03b36accf62a51460a2e2b62588d661f380d GIT binary patch literal 29111 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

~ZCUREYXaL#7zjkK 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 z%0A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 literal 0 HcmV?d00001