From 36311602696621c3bdf79a97f70f6e789eac2dd9 Mon Sep 17 00:00:00 2001 From: jamesagnew Date: Tue, 17 Feb 2015 13:54:26 -0500 Subject: [PATCH] Fix build --- .../BaseRuntimeChildDatatypeDefinition.java | 17 +- .../context/RuntimeResourceDefinition.java | 4 + .../BaseResourceReturningMethodBinding.java | 46 ++- .../rest/method/TransactionMethodBinding.java | 49 ++- .../rest/method/TransactionParamBinder.java | 121 +++--- ...ransactionWithBundleResourceParamTest.java | 349 +++++++++--------- .../model/dev/composite/AttachmentDt.java | 6 +- .../fhir/model/dev/composite/CodingDt.java | 6 +- .../dev/composite/ElementDefinitionDt.java | 6 +- .../model/dev/composite/IdentifierDt.java | 6 +- .../fhir/model/dev/composite/QuantityDt.java | 6 +- .../fhir/model/dev/resource/Conformance.java | 6 +- .../fhir/model/dev/resource/DataElement.java | 2 +- .../dev/resource/OperationDefinition.java | 2 +- .../uhn/fhir/model/dev/resource/Profile.java | 6 +- .../uhn/fhir/model/dev/resource/ValueSet.java | 8 +- .../model/dstu2/composite/AttachmentDt.java | 2 +- .../fhir/model/dstu2/composite/CodingDt.java | 2 +- .../dstu2/composite/ElementDefinitionDt.java | 2 +- .../model/dstu2/composite/IdentifierDt.java | 2 +- .../model/dstu2/composite/QuantityDt.java | 2 +- .../fhir/model/dstu2/resource/ValueSet.java | 8 +- 22 files changed, 371 insertions(+), 287 deletions(-) diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/BaseRuntimeChildDatatypeDefinition.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/BaseRuntimeChildDatatypeDefinition.java index d77f12992c9..c0f780870e6 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/BaseRuntimeChildDatatypeDefinition.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/BaseRuntimeChildDatatypeDefinition.java @@ -47,17 +47,24 @@ public abstract class BaseRuntimeChildDatatypeDefinition extends BaseRuntimeDecl @Override public String getChildNameByDatatype(Class theDatatype) { - if (myDatatype.equals(theDatatype)) { - return getElementName(); + Class nextType = theDatatype; + while(nextType.equals(Object.class)==false) { + if (myDatatype.equals(nextType)) { + return getElementName(); + } + nextType = nextType.getSuperclass(); } return null; } @Override public BaseRuntimeElementDefinition getChildElementDefinitionByDatatype(Class theDatatype) { - Class datatype = theDatatype; - if (myDatatype.equals(datatype)) { - return myElementDefinition; + Class nextType = theDatatype; + while(nextType.equals(Object.class)==false) { + if (myDatatype.equals(nextType)) { + return myElementDefinition; + } + nextType = nextType.getSuperclass(); } return null; } diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/RuntimeResourceDefinition.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/RuntimeResourceDefinition.java index c2751cf34de..d46ad775ae5 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/RuntimeResourceDefinition.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/RuntimeResourceDefinition.java @@ -178,4 +178,8 @@ public class RuntimeResourceDefinition extends BaseRuntimeElementCompositeDefini return retVal; } + + public boolean isBundle() { + return "Bundle".equals(getName()); + } } diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/BaseResourceReturningMethodBinding.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/BaseResourceReturningMethodBinding.java index 4c136685c56..1b4bf99567b 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/BaseResourceReturningMethodBinding.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/BaseResourceReturningMethodBinding.java @@ -94,7 +94,11 @@ abstract class BaseResourceReturningMethodBinding extends BaseMethodBinding) methodReturnType).isBundle()) { + myMethodReturnType = MethodReturnTypeEnum.BUNDLE_RESOURCE; + }else { + myMethodReturnType = MethodReturnTypeEnum.RESOURCE; + } } else if (Bundle.class.isAssignableFrom(methodReturnType)) { myMethodReturnType = MethodReturnTypeEnum.BUNDLE; } else if (IBundleProvider.class.isAssignableFrom(methodReturnType)) { @@ -202,7 +206,7 @@ abstract class BaseResourceReturningMethodBinding extends BaseMethodBinding= 0; i--) { - IServerInterceptor next = theServer.getInterceptors().get(i); - boolean continueProcessing = next.outgoingResponse(theRequest, bundle, theRequest.getServletRequest(), theRequest.getServletResponse()); - if (!continueProcessing) { - return; + if (getMethodReturnType() == MethodReturnTypeEnum.BUNDLE_RESOURCE) { + IResource resource = (IResource) resultObj; + RestfulServer.streamResponseAsResource(theServer, response, resource, responseEncoding, prettyPrint, requestIsBrowser, narrativeMode, respondGzip, theRequest.getFhirServerBase()); + break; + } else { + IBundleProvider result = (IBundleProvider) resultObj; + Bundle bundle = RestfulServer.createBundleFromBundleProvider(theServer, response, result, responseEncoding, theRequest.getFhirServerBase(), theRequest.getCompleteUrl(), prettyPrint, requestIsBrowser, narrativeMode, 0, count, null, getResponseBundleType()); + + for (int i = theServer.getInterceptors().size() - 1; i >= 0; i--) { + IServerInterceptor next = theServer.getInterceptors().get(i); + boolean continueProcessing = next.outgoingResponse(theRequest, bundle, theRequest.getServletRequest(), theRequest.getServletResponse()); + if (!continueProcessing) { + return; + } } + + RestfulServer.streamResponseAsBundle(theServer, response, bundle, responseEncoding, theRequest.getFhirServerBase(), prettyPrint, narrativeMode, respondGzip); + break; } - - RestfulServer.streamResponseAsBundle(theServer, response, bundle, responseEncoding, theRequest.getFhirServerBase(), prettyPrint, narrativeMode, respondGzip); - break; - case RESOURCE: + } + case RESOURCE:{ + IBundleProvider result = (IBundleProvider) resultObj; if (result.size() == 0) { throw new ResourceNotFoundException(theRequest.getId()); } else if (result.size() > 1) { @@ -275,6 +288,7 @@ abstract class BaseResourceReturningMethodBinding extends BaseMethodBinding resources; if (theMethodParams[myTransactionParamIndex] instanceof Bundle) { @@ -102,7 +123,7 @@ public class TransactionMethodBinding extends BaseResourceReturningMethodBinding } else { resources = (List) theMethodParams[myTransactionParamIndex]; } - + IdentityHashMap oldIds = new IdentityHashMap(); for (IResource next : resources) { oldIds.put(next, next.getId()); @@ -113,16 +134,12 @@ public class TransactionMethodBinding extends BaseResourceReturningMethodBinding IBundleProvider retVal = toResourceList(response); /* - int offset = 0; - if (retVal.size() != resources.size()) { - if (retVal.size() > 0 && retVal.getResources(0, 1).get(0) instanceof OperationOutcome) { - offset = 1; - } else { - throw new InternalErrorException("Transaction bundle contained " + resources.size() + " entries, but server method response contained " + retVal.size() + " entries (must be the same)"); - } - } + * int offset = 0; if (retVal.size() != resources.size()) { if (retVal.size() > 0 && retVal.getResources(0, + * 1).get(0) instanceof OperationOutcome) { offset = 1; } else { throw new + * InternalErrorException("Transaction bundle contained " + resources.size() + + * " entries, but server method response contained " + retVal.size() + " entries (must be the same)"); } } */ - + List retResources = retVal.getResources(0, retVal.size()); for (int i = 0; i < retResources.size(); i++) { IdDt oldId = oldIds.get(retResources.get(i)); @@ -141,17 +158,11 @@ public class TransactionMethodBinding extends BaseResourceReturningMethodBinding } return retVal; - - - - } + } @Override protected Object parseRequestObject(Request theRequest) throws IOException { - EncodingEnum encoding = RestfulServer.determineResponseEncoding(theRequest.getServletRequest()); - IParser parser = encoding.newParser(getContext()); - Bundle bundle = parser.parseBundle(theRequest.getServletRequest().getReader()); - return bundle; + return null; // This is parsed in TransactionParamBinder } @Override diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/TransactionParamBinder.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/TransactionParamBinder.java index 6e3e6582f50..863031aa6eb 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/TransactionParamBinder.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/TransactionParamBinder.java @@ -20,6 +20,8 @@ package ca.uhn.fhir.rest.method; * #L% */ +import java.io.BufferedReader; +import java.io.IOException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.ArrayList; @@ -35,20 +37,58 @@ import ca.uhn.fhir.context.RuntimeResourceDefinition; import ca.uhn.fhir.model.api.Bundle; import ca.uhn.fhir.model.api.BundleEntry; import ca.uhn.fhir.model.api.IResource; +import ca.uhn.fhir.parser.IParser; import ca.uhn.fhir.rest.annotation.TransactionParam; +import ca.uhn.fhir.rest.server.EncodingEnum; +import ca.uhn.fhir.rest.server.RestfulServer; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; class TransactionParamBinder implements IParameter { - private boolean myParamIsBundle; private FhirContext myContext; - private boolean myParamIsResource; - + private ParamStyle myParamStyle; + private Class myResourceBundleType; + public TransactionParamBinder(FhirContext theContext) { myContext = theContext; } + private String createParameterTypeError(Method theMethod) { + return "Method '" + theMethod.getName() + "' in type '" + theMethod.getDeclaringClass().getCanonicalName() + "' is annotated with @" + TransactionParam.class.getName() + " but is not of type List<" + IResource.class.getCanonicalName() + "> or Bundle"; + } + + @Override + public void initializeTypes(Method theMethod, Class> theOuterCollectionType, Class> theInnerCollectionType, Class theParameterType) { + if (theOuterCollectionType != null) { + throw new ConfigurationException("Method '" + theMethod.getName() + "' in type '" + theMethod.getDeclaringClass().getCanonicalName() + "' is annotated with @" + TransactionParam.class.getName() + " but can not be a collection of collections"); + } + if (theParameterType.equals(Bundle.class)) { + myParamStyle = ParamStyle.DSTU1_BUNDLE; + if (theInnerCollectionType != null) { + throw new ConfigurationException(createParameterTypeError(theMethod)); + } + } else if (Modifier.isInterface(theParameterType.getModifiers()) == false && IBaseResource.class.isAssignableFrom(theParameterType)) { + @SuppressWarnings("unchecked") + Class parameterType = (Class) theParameterType; + RuntimeResourceDefinition def = myContext.getResourceDefinition(parameterType); + if ("Bundle".equals(def.getName())) { + myParamStyle = ParamStyle.RESOURCE_BUNDLE; + myResourceBundleType = parameterType; + } else { + throw new ConfigurationException(createParameterTypeError(theMethod)); + } + } else { + if (theInnerCollectionType.equals(List.class) == false) { + throw new ConfigurationException(createParameterTypeError(theMethod)); + } + if (theParameterType.equals(IResource.class) == false) { + throw new ConfigurationException(createParameterTypeError(theMethod)); + } + myParamStyle = ParamStyle.RESOURCE_LIST; + } + } + @Override public void translateClientArgumentIntoQueryArgument(FhirContext theContext, Object theSourceClientArgument, Map> theTargetQueryArguments) throws InternalErrorException { // nothing @@ -57,54 +97,51 @@ class TransactionParamBinder implements IParameter { @Override public Object translateQueryParametersIntoServerArgument(Request theRequest, Object theRequestContents) throws InternalErrorException, InvalidRequestException { - Bundle resource = (Bundle) theRequestContents; - if (myParamIsBundle) { - return resource; + + EncodingEnum encoding = RestfulServer.determineResponseEncoding(theRequest.getServletRequest()); + IParser parser = encoding.newParser(myContext); + + BufferedReader reader; + try { + reader = theRequest.getServletRequest().getReader(); + } catch (IOException e) { + throw new InternalErrorException("Failed to read incoming payload", e); } - ArrayList retVal = new ArrayList(); - for (BundleEntry next : resource.getEntries()) { - if (next.getResource() != null) { - retVal.add(next.getResource()); + switch (myParamStyle) { + case DSTU1_BUNDLE: { + Bundle bundle; + bundle = parser.parseBundle(reader); + return bundle; + } + case RESOURCE_LIST: { + Bundle bundle = parser.parseBundle(reader); + ArrayList resourceList = new ArrayList(); + for (BundleEntry next : bundle.getEntries()) { + if (next.getResource() != null) { + resourceList.add(next.getResource()); + } } + return resourceList; + } + case RESOURCE_BUNDLE: + return parser.parseResource(myResourceBundleType, reader); } - return retVal; + throw new IllegalStateException("Unknown type: " + myParamStyle); // should not happen } - @Override - public void initializeTypes(Method theMethod, Class> theOuterCollectionType, Class> theInnerCollectionType, Class theParameterType) { - if (theOuterCollectionType != null) { - throw new ConfigurationException("Method '" + theMethod.getName() + "' in type '" + theMethod.getDeclaringClass().getCanonicalName() + "' is annotated with @" + TransactionParam.class.getName() + " but can not be a collection of collections"); - } - if (theParameterType.equals(Bundle.class)) { - myParamIsBundle=true; - if (theInnerCollectionType!=null) { - throw new ConfigurationException(createParameterTypeError(theMethod)); - } - } else if (Modifier.isInterface(theParameterType.getModifiers()) == false && IBaseResource.class.isAssignableFrom(theParameterType)) { - @SuppressWarnings("unchecked") - Class parameterType = (Class) theParameterType; - RuntimeResourceDefinition def = myContext.getResourceDefinition(parameterType); - if ("Bundle".equals(def.getName())) { - myParamIsResource = true; - } else { - throw new ConfigurationException(createParameterTypeError(theMethod)); - } - } else { - myParamIsBundle=false; - if (theInnerCollectionType.equals(List.class) == false) { - throw new ConfigurationException(createParameterTypeError(theMethod)); - } - if (theParameterType.equals(IResource.class) == false) { - throw new ConfigurationException(createParameterTypeError(theMethod)); - } - } + public ParamStyle getParamStyle() { + return myParamStyle; } - private String createParameterTypeError(Method theMethod) { - return "Method '" + theMethod.getName() + "' in type '" + theMethod.getDeclaringClass().getCanonicalName() + "' is annotated with @" + TransactionParam.class.getName() + " but is not of type List<" + IResource.class.getCanonicalName() - + "> or Bundle"; + enum ParamStyle { + /** Old style bundle (defined in hapi-fhir-base) */ + DSTU1_BUNDLE, + /** New style bundle (defined in hapi-fhir-structures-* as a resource definition itself */ + RESOURCE_BUNDLE, + /** List of resources */ + RESOURCE_LIST } } diff --git a/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/rest/server/TransactionWithBundleResourceParamTest.java b/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/rest/server/TransactionWithBundleResourceParamTest.java index aad4165eda2..e972d3eb90c 100644 --- a/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/rest/server/TransactionWithBundleResourceParamTest.java +++ b/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/rest/server/TransactionWithBundleResourceParamTest.java @@ -41,179 +41,180 @@ public class TransactionWithBundleResourceParamTest { } -// private static CloseableHttpClient ourClient; -// private static FhirContext ourCtx = new FhirContext(); -// private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(TransactionWithBundleResourceParamTest.class); -// private static int ourPort; -// private static boolean ourReturnOperationOutcome; -// -// private static Server ourServer; -// -// @Before -// public void before() { -// ourReturnOperationOutcome = false; -// } -// -// @Test -// public void testTransaction() throws Exception { -// Bundle b = new Bundle(); -// InstantDt nowInstant = InstantDt.withCurrentTime(); -// -// Patient p1 = new Patient(); -// p1.addName().addFamily("Family1"); -// Entry entry = b.addEntry(); -// p1.getId().setValue("1"); -// entry.setResource(p1); -// -// Patient p2 = new Patient(); -// p2.addName().addFamily("Family2"); -// entry = b.addEntry(); -// p2.getId().setValue("2"); -// entry.setResource(p2); -// -// Entry deletedEntry = b.addEntry(); -// deletedEntry.getTransaction().setMethod(HTTPVerbEnum.DELETE); -// deletedEntry.getTransaction().setUrl("http://base.com/Patient/123"); -// -// String bundleString = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(b); -// ourLog.info(bundleString); -// -// HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/"); -// httpPost.addHeader("Accept", Constants.CT_ATOM_XML + "; pretty=true"); -// httpPost.setEntity(new StringEntity(bundleString, ContentType.create(Constants.CT_ATOM_XML, "UTF-8"))); -// HttpResponse status = ourClient.execute(httpPost); -// String responseContent = IOUtils.toString(status.getEntity().getContent()); -// IOUtils.closeQuietly(status.getEntity().getContent()); -// -// assertEquals(200, status.getStatusLine().getStatusCode()); -// -// ourLog.info(responseContent); -// -// Bundle bundle = ourCtx.newXmlParser().parseResource(Bundle.class, responseContent); -// assertEquals(3, bundle.getEntry().size()); -// -// Entry entry0 = bundle.getEntry().get(0); -// assertEquals("http://localhost:" + ourPort + "/Patient/81/_history/91", entry0.getResource().getId().getValue()); -// -// Entry entry1 = bundle.getEntry().get(1); -// assertEquals("http://localhost:" + ourPort + "/Patient/82/_history/92", entry1.getResource().getId().getValue()); -// -// Entry entry2 = bundle.getEntry().get(2); -// assertEquals("http://localhost:" + ourPort + "/Patient/3/_history/93", entry2.getResource().getId().getValue()); -// } -// -// @Test -// public void testTransactionWithOperationOutcome() throws Exception { -// ourReturnOperationOutcome = true; -// -// Bundle b = new Bundle(); -// InstantDt nowInstant = InstantDt.withCurrentTime(); -// -// Patient p1 = new Patient(); -// p1.addName().addFamily("Family1"); -// Entry entry = b.addEntry(); -// p1.getId().setValue("1"); -// entry.setResource(p1); -// -// Patient p2 = new Patient(); -// p2.addName().addFamily("Family2"); -// entry = b.addEntry(); -// p2.getId().setValue("2"); -// entry.setResource(p2); -// -// Entry deletedEntry = b.addEntry(); -// deletedEntry.getTransaction().setMethod(HTTPVerbEnum.DELETE); -// deletedEntry.getTransaction().setUrl(new IdDt("Patient/3")); -// -// String bundleString = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(b); -// ourLog.info(bundleString); -// -// HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/"); -// httpPost.addHeader("Accept", Constants.CT_ATOM_XML + "; pretty=true"); -// httpPost.setEntity(new StringEntity(bundleString, ContentType.create(Constants.CT_ATOM_XML, "UTF-8"))); -// HttpResponse status = ourClient.execute(httpPost); -// String responseContent = IOUtils.toString(status.getEntity().getContent()); -// IOUtils.closeQuietly(status.getEntity().getContent()); -// -// assertEquals(200, status.getStatusLine().getStatusCode()); -// -// ourLog.info(responseContent); -// -// Bundle bundle = new FhirContext().newXmlParser().parseResource(Bundle.class, responseContent); -// assertEquals(4, bundle.getEntry().size()); -// -// assertEquals(OperationOutcome.class, bundle.getEntry().get(0).getResource().getClass()); -// -// Entry entry0 = bundle.getEntry().get(1); -// assertEquals("http://localhost:" + ourPort + "/Patient/81/_history/91", entry0.getResource().getId().getValue()); -// -// Entry entry1 = bundle.getEntry().get(2); -// assertEquals("http://localhost:" + ourPort + "/Patient/82/_history/92", entry1.getResource().getId().getValue()); -// -// Entry entry2 = bundle.getEntry().get(3); -// assertEquals("http://localhost:" + ourPort + "/Patient/3/_history/93", entry2.getResource().getId().getValue()); -// } -// -// @AfterClass -// public static void afterClass() throws Exception { -// ourServer.stop(); -// } -// -// @BeforeClass -// public static void beforeClass() throws Exception { -// ourPort = PortUtil.findFreePort(); -// ourServer = new Server(ourPort); -// -// DummyProvider patientProvider = new DummyProvider(); -// RestfulServer server = new RestfulServer(); -// server.setProviders(patientProvider); -// -// org.eclipse.jetty.servlet.ServletContextHandler proxyHandler = new org.eclipse.jetty.servlet.ServletContextHandler(); -// proxyHandler.setContextPath("/"); -// -// ServletHolder handler = new ServletHolder(); -// handler.setServlet(server); -// proxyHandler.addServlet(handler, "/*"); -// -// ourServer.setHandler(proxyHandler); -// ourServer.start(); -// -// PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(5000, TimeUnit.MILLISECONDS); -// HttpClientBuilder builder = HttpClientBuilder.create(); -// builder.setConnectionManager(connectionManager); -// ourClient = builder.build(); -// -// } -// -// /** -// * Created by dsotnikov on 2/25/2014. -// */ -// public static class DummyProvider { -// -// @Transaction -// public Bundle transaction(@TransactionParam Bundle theResources) { -// Bundle retVal = new Bundle(); -// -// if (ourReturnOperationOutcome) { -// OperationOutcome oo = new OperationOutcome(); -// oo.addIssue().setDetails("AAAAA"); -// retVal.addEntry().setResource(oo); -// } -// -// int index = 1; -// for (Entry nextEntry : theResources.getEntry()) { -// String newId = "8" + Integer.toString(index); -// if (nextEntry.getTransaction().getMethodElement().getValueAsEnum() == HTTPVerbEnum.DELETE) { -// newId = new IdDt(nextEntry.getTransaction().getUrlElement()).getIdPart(); -// } -// IdDt newIdDt = (new IdDt("Patient", newId, "9" + Integer.toString(index))); -// retVal.addEntry().getTransactionResponse().setLocation(newIdDt.getValue()); -// index++; -// } -// -// return retVal; -// } -// -// } + private static CloseableHttpClient ourClient; + private static FhirContext ourCtx = new FhirContext(); + private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(TransactionWithBundleResourceParamTest.class); + private static int ourPort; + private static boolean ourReturnOperationOutcome; + + private static Server ourServer; + + @Before + public void before() { + ourReturnOperationOutcome = false; + } + + @Test + public void testTransaction() throws Exception { + Bundle b = new Bundle(); + InstantDt nowInstant = InstantDt.withCurrentTime(); + + Patient p1 = new Patient(); + p1.addName().addFamily("Family1"); + Entry entry = b.addEntry(); + p1.getId().setValue("1"); + entry.setResource(p1); + + Patient p2 = new Patient(); + p2.addName().addFamily("Family2"); + entry = b.addEntry(); + p2.getId().setValue("2"); + entry.setResource(p2); + + Entry deletedEntry = b.addEntry(); + deletedEntry.getTransaction().setMethod(HTTPVerbEnum.DELETE); + deletedEntry.getTransaction().setUrl("http://base.com/Patient/123"); + + String bundleString = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(b); + ourLog.info(bundleString); + + HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/"); + httpPost.addHeader("Accept", Constants.CT_ATOM_XML + "; pretty=true"); + httpPost.setEntity(new StringEntity(bundleString, ContentType.create(Constants.CT_ATOM_XML, "UTF-8"))); + HttpResponse status = ourClient.execute(httpPost); + String responseContent = IOUtils.toString(status.getEntity().getContent()); + IOUtils.closeQuietly(status.getEntity().getContent()); + + assertEquals(200, status.getStatusLine().getStatusCode()); + + ourLog.info(responseContent); + + Bundle bundle = ourCtx.newXmlParser().parseResource(Bundle.class, responseContent); + assertEquals(3, bundle.getEntry().size()); + + Entry entry0 = bundle.getEntry().get(0); + assertEquals("Patient/81/_history/91", entry0.getTransactionResponse().getLocation()); + + Entry entry1 = bundle.getEntry().get(1); + assertEquals( "Patient/82/_history/92", entry1.getTransactionResponse().getLocation()); + + Entry entry2 = bundle.getEntry().get(2); + assertEquals("Patient/123/_history/93", entry2.getTransactionResponse().getLocation()); + } + + @Test + public void testTransactionWithOperationOutcome() throws Exception { + ourReturnOperationOutcome = true; + + Bundle b = new Bundle(); + InstantDt nowInstant = InstantDt.withCurrentTime(); + + Patient p1 = new Patient(); + p1.addName().addFamily("Family1"); + Entry entry = b.addEntry(); + p1.getId().setValue("1"); + entry.setResource(p1); + + Patient p2 = new Patient(); + p2.addName().addFamily("Family2"); + entry = b.addEntry(); + p2.getId().setValue("2"); + entry.setResource(p2); + + Entry deletedEntry = b.addEntry(); + deletedEntry.getTransaction().setMethod(HTTPVerbEnum.DELETE); + deletedEntry.getTransaction().setUrl(new IdDt("Patient/3")); + + String bundleString = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(b); + ourLog.info(bundleString); + + String base = "http://localhost:" + ourPort + "/"; + HttpPost httpPost = new HttpPost(base); + httpPost.addHeader("Accept", Constants.CT_ATOM_XML + "; pretty=true"); + httpPost.setEntity(new StringEntity(bundleString, ContentType.create(Constants.CT_ATOM_XML, "UTF-8"))); + HttpResponse status = ourClient.execute(httpPost); + String responseContent = IOUtils.toString(status.getEntity().getContent()); + IOUtils.closeQuietly(status.getEntity().getContent()); + + assertEquals(200, status.getStatusLine().getStatusCode()); + + ourLog.info(responseContent); + + Bundle bundle = new FhirContext().newXmlParser().parseResource(Bundle.class, responseContent); + assertEquals(4, bundle.getEntry().size()); + + assertEquals(OperationOutcome.class, bundle.getEntry().get(0).getResource().getClass()); + + Entry entry0 = bundle.getEntry().get(1); + assertEquals("Patient/81/_history/91", entry0.getTransactionResponse().getLocation()); + + Entry entry1 = bundle.getEntry().get(2); + assertEquals("Patient/82/_history/92", entry1.getTransactionResponse().getLocation()); + + Entry entry2 = bundle.getEntry().get(3); + assertEquals( "Patient/3/_history/93", entry2.getTransactionResponse().getLocation()); + } + + @AfterClass + public static void afterClass() throws Exception { + ourServer.stop(); + } + + @BeforeClass + public static void beforeClass() throws Exception { + ourPort = PortUtil.findFreePort(); + ourServer = new Server(ourPort); + + DummyProvider patientProvider = new DummyProvider(); + RestfulServer server = new RestfulServer(); + server.setProviders(patientProvider); + + org.eclipse.jetty.servlet.ServletContextHandler proxyHandler = new org.eclipse.jetty.servlet.ServletContextHandler(); + proxyHandler.setContextPath("/"); + + ServletHolder handler = new ServletHolder(); + handler.setServlet(server); + proxyHandler.addServlet(handler, "/*"); + + ourServer.setHandler(proxyHandler); + ourServer.start(); + + PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(5000, TimeUnit.MILLISECONDS); + HttpClientBuilder builder = HttpClientBuilder.create(); + builder.setConnectionManager(connectionManager); + ourClient = builder.build(); + + } + + /** + * Created by dsotnikov on 2/25/2014. + */ + public static class DummyProvider { + + @Transaction + public Bundle transaction(@TransactionParam Bundle theResources) { + Bundle retVal = new Bundle(); + + if (ourReturnOperationOutcome) { + OperationOutcome oo = new OperationOutcome(); + oo.addIssue().setDetails("AAAAA"); + retVal.addEntry().setResource(oo); + } + + int index = 1; + for (Entry nextEntry : theResources.getEntry()) { + String newId = "8" + Integer.toString(index); + if (nextEntry.getTransaction().getMethodElement().getValueAsEnum() == HTTPVerbEnum.DELETE) { + newId = new IdDt(nextEntry.getTransaction().getUrlElement()).getIdPart(); + } + IdDt newIdDt = (new IdDt("Patient", newId, "9" + Integer.toString(index))); + retVal.addEntry().getTransactionResponse().setLocation(newIdDt.getValue()); + index++; + } + + return retVal; + } + + } } diff --git a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dev/composite/AttachmentDt.java b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dev/composite/AttachmentDt.java index e3068303423..5e3d286aa24 100644 --- a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dev/composite/AttachmentDt.java +++ b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dev/composite/AttachmentDt.java @@ -18,13 +18,15 @@ package ca.uhn.fhir.model.dev.composite; import java.net.URI; import java.math.BigDecimal; + import org.apache.commons.lang3.StringUtils; + import java.util.*; + import ca.uhn.fhir.model.api.*; import ca.uhn.fhir.model.primitive.*; import ca.uhn.fhir.model.api.annotation.*; import ca.uhn.fhir.model.base.composite.*; - import ca.uhn.fhir.model.dev.valueset.AddressUseEnum; import ca.uhn.fhir.model.dev.valueset.AggregationModeEnum; import ca.uhn.fhir.model.dev.valueset.BindingConformanceEnum; @@ -354,7 +356,7 @@ public class AttachmentDt * An alternative location where the data can be accessed *

*/ - public URI getUrl() { + public String getUrl() { return getUrlElement().getValue(); } diff --git a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dev/composite/CodingDt.java b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dev/composite/CodingDt.java index 286a19c19c4..47926ef29be 100644 --- a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dev/composite/CodingDt.java +++ b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dev/composite/CodingDt.java @@ -18,13 +18,15 @@ package ca.uhn.fhir.model.dev.composite; import java.net.URI; import java.math.BigDecimal; + import org.apache.commons.lang3.StringUtils; + import java.util.*; + import ca.uhn.fhir.model.api.*; import ca.uhn.fhir.model.primitive.*; import ca.uhn.fhir.model.api.annotation.*; import ca.uhn.fhir.model.base.composite.*; - import ca.uhn.fhir.model.dev.valueset.AddressUseEnum; import ca.uhn.fhir.model.dev.valueset.AggregationModeEnum; import ca.uhn.fhir.model.dev.valueset.BindingConformanceEnum; @@ -180,7 +182,7 @@ public class CodingDt * The identification of the code system that defines the meaning of the symbol in the code. *

*/ - public URI getSystem() { + public String getSystem() { return getSystemElement().getValue(); } diff --git a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dev/composite/ElementDefinitionDt.java b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dev/composite/ElementDefinitionDt.java index c0a4b6c024d..5143739dae2 100644 --- a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dev/composite/ElementDefinitionDt.java +++ b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dev/composite/ElementDefinitionDt.java @@ -18,13 +18,15 @@ package ca.uhn.fhir.model.dev.composite; import java.net.URI; import java.math.BigDecimal; + import org.apache.commons.lang3.StringUtils; + import java.util.*; + import ca.uhn.fhir.model.api.*; import ca.uhn.fhir.model.primitive.*; import ca.uhn.fhir.model.api.annotation.*; import ca.uhn.fhir.model.base.composite.*; - import ca.uhn.fhir.model.dev.valueset.AddressUseEnum; import ca.uhn.fhir.model.dev.valueset.AggregationModeEnum; import ca.uhn.fhir.model.dev.valueset.BindingConformanceEnum; @@ -2207,7 +2209,7 @@ public class ElementDefinitionDt * Identifies a profile structure that SHALL hold for resources or datatypes referenced as the type of this element. Can be a local reference - to another structure in this profile, or a reference to a structure in another profile *

*/ - public URI getProfile() { + public String getProfile() { return getProfileElement().getValue(); } diff --git a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dev/composite/IdentifierDt.java b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dev/composite/IdentifierDt.java index 48ae06967a7..ec451fcab68 100644 --- a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dev/composite/IdentifierDt.java +++ b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dev/composite/IdentifierDt.java @@ -18,13 +18,15 @@ package ca.uhn.fhir.model.dev.composite; import java.net.URI; import java.math.BigDecimal; + import org.apache.commons.lang3.StringUtils; + import java.util.*; + import ca.uhn.fhir.model.api.*; import ca.uhn.fhir.model.primitive.*; import ca.uhn.fhir.model.api.annotation.*; import ca.uhn.fhir.model.base.composite.*; - import ca.uhn.fhir.model.dev.valueset.AddressUseEnum; import ca.uhn.fhir.model.dev.valueset.AggregationModeEnum; import ca.uhn.fhir.model.dev.valueset.BindingConformanceEnum; @@ -312,7 +314,7 @@ public class IdentifierDt * Establishes the namespace in which set of possible id values is unique. *

*/ - public URI getSystem() { + public String getSystem() { return getSystemElement().getValue(); } diff --git a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dev/composite/QuantityDt.java b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dev/composite/QuantityDt.java index 6ccd588ad5f..c4a27958f87 100644 --- a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dev/composite/QuantityDt.java +++ b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dev/composite/QuantityDt.java @@ -18,13 +18,15 @@ package ca.uhn.fhir.model.dev.composite; import java.net.URI; import java.math.BigDecimal; + import org.apache.commons.lang3.StringUtils; + import java.util.*; + import ca.uhn.fhir.model.api.*; import ca.uhn.fhir.model.primitive.*; import ca.uhn.fhir.model.api.annotation.*; import ca.uhn.fhir.model.base.composite.*; - import ca.uhn.fhir.model.dev.valueset.AddressUseEnum; import ca.uhn.fhir.model.dev.valueset.AggregationModeEnum; import ca.uhn.fhir.model.dev.valueset.BindingConformanceEnum; @@ -428,7 +430,7 @@ public class QuantityDt * The identification of the system that provides the coded form of the unit *

*/ - public URI getSystem() { + public String getSystem() { return getSystemElement().getValue(); } diff --git a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dev/resource/Conformance.java b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dev/resource/Conformance.java index 58a51fb00b2..4f2b5e5351f 100644 --- a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dev/resource/Conformance.java +++ b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dev/resource/Conformance.java @@ -2084,7 +2084,7 @@ public class Conformance extends BaseResource implements ca.uhn.fhir.model.base. * A base URL for the implementation. This forms the base for REST interfaces as well as the mailbox and document interfaces. *

*/ - public URI getUrl() { + public String getUrl() { return getUrlElement().getValue(); } @@ -3994,7 +3994,7 @@ public class Conformance extends BaseResource implements ca.uhn.fhir.model.base. * A formal reference to where this parameter was first defined, so that a client can be confident of the meaning of the search parameter *

*/ - public URI getDefinition() { + public String getDefinition() { return getDefinitionElement().getValue(); } @@ -4707,7 +4707,7 @@ public class Conformance extends BaseResource implements ca.uhn.fhir.model.base. * An address to which messages and/or replies are to be sent. *

*/ - public URI getEndpoint() { + public String getEndpoint() { return getEndpointElement().getValue(); } diff --git a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dev/resource/DataElement.java b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dev/resource/DataElement.java index 705e66f05da..39565dd25f8 100644 --- a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dev/resource/DataElement.java +++ b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dev/resource/DataElement.java @@ -2106,7 +2106,7 @@ public class DataElement * A URI that identifies the specification that this mapping is expressed to *

*/ - public URI getUri() { + public String getUri() { return getUriElement().getValue(); } diff --git a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dev/resource/OperationDefinition.java b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dev/resource/OperationDefinition.java index d9bd9905e23..2753d248cfe 100644 --- a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dev/resource/OperationDefinition.java +++ b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dev/resource/OperationDefinition.java @@ -621,7 +621,7 @@ public class OperationDefinition * The identifier that is used to identify this operation definition when it is referenced in a specification, model, design or an instance (should be globally unique OID, UUID, or URI) *

*/ - public URI getIdentifier() { + public String getIdentifier() { return getIdentifierElement().getValue(); } diff --git a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dev/resource/Profile.java b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dev/resource/Profile.java index 18b2faa3429..85d742090eb 100644 --- a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dev/resource/Profile.java +++ b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dev/resource/Profile.java @@ -538,7 +538,7 @@ public class Profile * The URL at which this profile is (or will be) published, and which is used to reference this profile in extension urls and tag values in operational FHIR systems *

*/ - public URI getUrl() { + public String getUrl() { return getUrlElement().getValue(); } @@ -1470,7 +1470,7 @@ public class Profile * The structure that is the base on which this set of constraints is derived from. *

*/ - public URI getBase() { + public String getBase() { return getBaseElement().getValue(); } @@ -1709,7 +1709,7 @@ public class Profile * A URI that identifies the specification that this mapping is expressed to *

*/ - public URI getUri() { + public String getUri() { return getUriElement().getValue(); } diff --git a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dev/resource/ValueSet.java b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dev/resource/ValueSet.java index 4e3125a0069..a0ed0e25f78 100644 --- a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dev/resource/ValueSet.java +++ b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dev/resource/ValueSet.java @@ -502,7 +502,7 @@ public class ValueSet * The identifier that is used to identify this value set when it is referenced in a specification, model, design or an instance (should be globally unique OID, UUID, or URI) *

*/ - public URI getIdentifier() { + public String getIdentifier() { return getIdentifierElement().getValue(); } @@ -1533,7 +1533,7 @@ public class ValueSet * *

*/ - public URI getSystem() { + public String getSystem() { return getSystemElement().getValue(); } @@ -2724,7 +2724,7 @@ public class ValueSet * The code system from which the selected codes come from *

*/ - public URI getSystem() { + public String getSystem() { return getSystemElement().getValue(); } @@ -3719,7 +3719,7 @@ public class ValueSet * The system in which the code for this item in the expansion is defined *

*/ - public URI getSystem() { + public String getSystem() { return getSystemElement().getValue(); } diff --git a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dstu2/composite/AttachmentDt.java b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dstu2/composite/AttachmentDt.java index f8e789c8c03..702b845484b 100644 --- a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dstu2/composite/AttachmentDt.java +++ b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dstu2/composite/AttachmentDt.java @@ -356,7 +356,7 @@ public class AttachmentDt * An alternative location where the data can be accessed *

*/ - public URI getUrl() { + public String getUrl() { return getUrlElement().getValue(); } diff --git a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dstu2/composite/CodingDt.java b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dstu2/composite/CodingDt.java index be576e4016d..74040d0f8b8 100644 --- a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dstu2/composite/CodingDt.java +++ b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dstu2/composite/CodingDt.java @@ -182,7 +182,7 @@ public class CodingDt * The identification of the code system that defines the meaning of the symbol in the code. *

*/ - public URI getSystem() { + public String getSystem() { return getSystemElement().getValue(); } diff --git a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dstu2/composite/ElementDefinitionDt.java b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dstu2/composite/ElementDefinitionDt.java index ddf59d37c84..696579b6485 100644 --- a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dstu2/composite/ElementDefinitionDt.java +++ b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dstu2/composite/ElementDefinitionDt.java @@ -2209,7 +2209,7 @@ public class ElementDefinitionDt * Identifies a profile structure that SHALL hold for resources or datatypes referenced as the type of this element. Can be a local reference - to another structure in this profile, or a reference to a structure in another profile *

*/ - public URI getProfile() { + public String getProfile() { return getProfileElement().getValue(); } diff --git a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dstu2/composite/IdentifierDt.java b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dstu2/composite/IdentifierDt.java index 26b8f8518a5..3cdb8907bec 100644 --- a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dstu2/composite/IdentifierDt.java +++ b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dstu2/composite/IdentifierDt.java @@ -313,7 +313,7 @@ public class IdentifierDt * Establishes the namespace in which set of possible id values is unique. *

*/ - public URI getSystem() { + public String getSystem() { return getSystemElement().getValue(); } diff --git a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dstu2/composite/QuantityDt.java b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dstu2/composite/QuantityDt.java index 2413ee36876..97cfeb2711e 100644 --- a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dstu2/composite/QuantityDt.java +++ b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dstu2/composite/QuantityDt.java @@ -429,7 +429,7 @@ public class QuantityDt * The identification of the system that provides the coded form of the unit *

*/ - public URI getSystem() { + public String getSystem() { return getSystemElement().getValue(); } diff --git a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dstu2/resource/ValueSet.java b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dstu2/resource/ValueSet.java index ca80329a09c..e52b9cbb945 100644 --- a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dstu2/resource/ValueSet.java +++ b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/model/dstu2/resource/ValueSet.java @@ -502,7 +502,7 @@ public class ValueSet * The identifier that is used to identify this value set when it is referenced in a specification, model, design or an instance (should be globally unique OID, UUID, or URI) *

*/ - public URI getIdentifier() { + public String getIdentifier() { return getIdentifierElement().getValue(); } @@ -1533,7 +1533,7 @@ public class ValueSet * *

*/ - public URI getSystem() { + public String getSystem() { return getSystemElement().getValue(); } @@ -2724,7 +2724,7 @@ public class ValueSet * The code system from which the selected codes come from *

*/ - public URI getSystem() { + public String getSystem() { return getSystemElement().getValue(); } @@ -3719,7 +3719,7 @@ public class ValueSet * The system in which the code for this item in the expansion is defined *

*/ - public URI getSystem() { + public String getSystem() { return getSystemElement().getValue(); }