From a4e4111376e339471a4e76fa9e45aeaa8d4ab8bd Mon Sep 17 00:00:00 2001 From: James Agnew Date: Thu, 26 Jul 2018 18:08:59 +0700 Subject: [PATCH] Fix a unit test --- .../fhir/rest/client/api/IHttpRequest.java | 19 +- .../okhttp/client/OkHttpRestfulRequest.java | 5 +- .../rest/client/apache/ApacheHttpRequest.java | 11 +- .../fhir/jaxrs/client/JaxRsHttpRequest.java | 11 +- .../ca/uhn/fhir/jpa/dao/BaseHapiFhirDao.java | 81 ++++--- .../jpa/dao/dstu3/FhirSystemDaoDstu3Test.java | 72 +++--- .../src/test/resources/bug1044-bundle.xml | 214 ++++++++++++++++++ .../provider/HashMapResourceProvider.java | 21 +- .../provider/HashMapResourceProviderTest.java | 6 +- 9 files changed, 345 insertions(+), 95 deletions(-) create mode 100644 hapi-fhir-jpaserver-base/src/test/resources/bug1044-bundle.xml diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/api/IHttpRequest.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/api/IHttpRequest.java index 030ce82ce6d..d7780caa397 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/api/IHttpRequest.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/api/IHttpRequest.java @@ -34,36 +34,35 @@ public interface IHttpRequest { * @param theName the header name * @param theValue the header value */ - public void addHeader(String theName, String theValue); + void addHeader(String theName, String theValue); /** * Execute the request * @return the response - * @throws IOException */ - public IHttpResponse execute() throws IOException; + IHttpResponse execute() throws IOException; /** - * @return all request headers in lower case + * @return all request headers in lower case. Note that this method + * returns an immutable Map */ - public Map> getAllHeaders(); + Map> getAllHeaders(); /** - * Return the requestbody as a string. + * Return the request body as a string. * If this is not supported by the underlying technology, null is returned * @return a string representation of the request or null if not supported or empty. - * @throws IOException */ - public String getRequestBodyFromStream() throws IOException; + String getRequestBodyFromStream() throws IOException; /** * Return the request URI, or null */ - public String getUri(); + String getUri(); /** * Return the HTTP verb (e.g. "GET") */ - public String getHttpVerbName(); + String getHttpVerbName(); } diff --git a/hapi-fhir-client-okhttp/src/main/java/ca/uhn/fhir/okhttp/client/OkHttpRestfulRequest.java b/hapi-fhir-client-okhttp/src/main/java/ca/uhn/fhir/okhttp/client/OkHttpRestfulRequest.java index 5b2b68f652a..5ad07eceb2d 100644 --- a/hapi-fhir-client-okhttp/src/main/java/ca/uhn/fhir/okhttp/client/OkHttpRestfulRequest.java +++ b/hapi-fhir-client-okhttp/src/main/java/ca/uhn/fhir/okhttp/client/OkHttpRestfulRequest.java @@ -1,6 +1,7 @@ package ca.uhn.fhir.okhttp.client; import java.io.IOException; +import java.util.Collections; import java.util.List; import java.util.Map; @@ -74,11 +75,11 @@ public class OkHttpRestfulRequest implements IHttpRequest { @Override public Map> getAllHeaders() { - return myRequestBuilder.build().headers().toMultimap(); + return Collections.unmodifiableMap(myRequestBuilder.build().headers().toMultimap()); } @Override - public String getRequestBodyFromStream() throws IOException { + public String getRequestBodyFromStream() { // returning null to indicate this is not supported, as documented in IHttpRequest's contract return null; } diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/apache/ApacheHttpRequest.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/apache/ApacheHttpRequest.java index 555d7ae593d..f968eb8901b 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/apache/ApacheHttpRequest.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/apache/ApacheHttpRequest.java @@ -22,10 +22,7 @@ package ca.uhn.fhir.rest.client.apache; import java.io.IOException; import java.nio.charset.Charset; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; +import java.util.*; import ca.uhn.fhir.util.StopWatch; import org.apache.commons.io.IOUtils; @@ -70,14 +67,14 @@ public class ApacheHttpRequest implements IHttpRequest { @Override public Map> getAllHeaders() { - Map> result = new HashMap>(); + Map> result = new HashMap<>(); for (Header header : myRequest.getAllHeaders()) { if (!result.containsKey(header.getName())) { - result.put(header.getName(), new LinkedList()); + result.put(header.getName(), new LinkedList<>()); } result.get(header.getName()).add(header.getValue()); } - return result; + return Collections.unmodifiableMap(result); } /** diff --git a/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/client/JaxRsHttpRequest.java b/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/client/JaxRsHttpRequest.java index 6ef41b4bf53..c2cb7eeed86 100644 --- a/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/client/JaxRsHttpRequest.java +++ b/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/client/JaxRsHttpRequest.java @@ -28,10 +28,7 @@ import ca.uhn.fhir.util.StopWatch; import javax.ws.rs.client.Entity; import javax.ws.rs.client.Invocation; import javax.ws.rs.core.Response; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; +import java.util.*; /** * A Http Request based on JaxRs. This is an adapter around the class @@ -41,7 +38,7 @@ import java.util.Map; */ public class JaxRsHttpRequest implements IHttpRequest { - private final Map> myHeaders = new HashMap>(); + private final Map> myHeaders = new HashMap<>(); private Invocation.Builder myRequest; private RequestTypeEnum myRequestType; private Entity myEntity; @@ -55,7 +52,7 @@ public class JaxRsHttpRequest implements IHttpRequest { @Override public void addHeader(String theName, String theValue) { if (!myHeaders.containsKey(theName)) { - myHeaders.put(theName, new LinkedList()); + myHeaders.put(theName, new LinkedList<>()); } myHeaders.get(theName).add(theValue); getRequest().header(theName, theValue); @@ -71,7 +68,7 @@ public class JaxRsHttpRequest implements IHttpRequest { @Override public Map> getAllHeaders() { - return this.myHeaders; + return Collections.unmodifiableMap(this.myHeaders); } /** diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirDao.java index 4b643375b78..cc0c919dc94 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirDao.java @@ -74,7 +74,6 @@ import javax.persistence.criteria.Root; import javax.xml.stream.events.Characters; import javax.xml.stream.events.XMLEvent; import java.io.CharArrayWriter; -import java.io.UnsupportedEncodingException; import java.text.Normalizer; import java.util.*; import java.util.Map.Entry; @@ -92,9 +91,9 @@ import static org.apache.commons.lang3.StringUtils.*; * 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. @@ -1250,25 +1249,10 @@ public abstract class BaseHapiFhirDao implements IDao, if (theEntity.getDeleted() == null) { encoding = myConfig.getResourceEncoding(); - IParser parser = encoding.newParser(myContext); - parser.setDontEncodeElements(EXCLUDE_ELEMENTS_IN_ENCODED); - String encoded = parser.encodeResourceToString(theResource); - + Set excludeElements = EXCLUDE_ELEMENTS_IN_ENCODED; theEntity.setFhirVersion(myContext.getVersion().getVersion()); - switch (encoding) { - case JSON: - bytes = encoded.getBytes(Charsets.UTF_8); - break; - case JSONC: - bytes = GZipUtil.compress(encoded); - break; - default: - case DEL: - bytes = new byte[0]; - break; - } - ourLog.debug("Encoded {} chars of resource body as {} bytes", encoded.length(), bytes.length); + bytes = encodeResource(theResource, encoding, excludeElements, myContext); if (theUpdateHash) { HashFunction sha256 = Hashing.sha256(); @@ -1664,22 +1648,8 @@ public abstract class BaseHapiFhirDao implements IDao, return null; } - // 2. get The text - String resourceText = null; - switch (resourceEncoding) { - case JSON: - try { - resourceText = new String(resourceBytes, "UTF-8"); - } catch (UnsupportedEncodingException e) { - throw new Error("Should not happen", e); - } - break; - case JSONC: - resourceText = GZipUtil.decompress(resourceBytes); - break; - case DEL: - break; - } + // 2. get The text + String resourceText = decodeResource(resourceBytes, resourceEncoding); // 3. Use the appropriate custom type if one is specified in the context Class resourceType = theResourceType; @@ -2393,6 +2363,45 @@ public abstract class BaseHapiFhirDao implements IDao, } + public static String decodeResource(byte[] theResourceBytes, ResourceEncodingEnum theResourceEncoding) { + String resourceText = null; + switch (theResourceEncoding) { + case JSON: + resourceText = new String(theResourceBytes, Charsets.UTF_8); + break; + case JSONC: + resourceText = GZipUtil.decompress(theResourceBytes); + break; + case DEL: + break; + } + return resourceText; + } + + public static byte[] encodeResource(IBaseResource theResource, ResourceEncodingEnum theEncoding, Set theExcludeElements, FhirContext theContext) { + byte[] bytes; + IParser parser = theEncoding.newParser(theContext); + parser.setDontEncodeElements(theExcludeElements); + String encoded = parser.encodeResourceToString(theResource); + + + switch (theEncoding) { + case JSON: + bytes = encoded.getBytes(Charsets.UTF_8); + break; + case JSONC: + bytes = GZipUtil.compress(encoded); + break; + default: + case DEL: + bytes = new byte[0]; + break; + } + + ourLog.debug("Encoded {} chars of resource body as {} bytes", encoded.length(), bytes.length); + return bytes; + } + /** * This method is used to create a set of all possible combinations of * parameters across a set of search parameters. An example of why 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 a5897f40de2..da8ff3e43a7 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 @@ -16,6 +16,7 @@ import ca.uhn.fhir.rest.param.TokenParam; import ca.uhn.fhir.rest.server.exceptions.*; import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails; import ca.uhn.fhir.util.TestUtil; +import com.google.common.base.Charsets; import org.apache.commons.io.IOUtils; import org.hl7.fhir.dstu3.model.*; import org.hl7.fhir.dstu3.model.Bundle.*; @@ -152,36 +153,6 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest { return input; } - @Test - public void testTransactionUpdateTwoResourcesWithSameId() { - Bundle request = new Bundle(); - - Patient p = new Patient(); - p.addIdentifier().setSystem("urn:system").setValue("DDD"); - p.setId("Patient/ABC"); - request.addEntry() - .setResource(p) - .getRequest() - .setMethod(HTTPVerb.PUT) - .setUrl("Patient/ABC"); - - p = new Patient(); - p.addIdentifier().setSystem("urn:system").setValue("DDD"); - p.setId("Patient/ABC"); - request.addEntry() - .setResource(p) - .getRequest() - .setMethod(HTTPVerb.PUT) - .setUrl("Patient/ABC"); - - try { - mySystemDao.transaction(mySrd, request); - fail(); - } catch (InvalidRequestException e) { - assertThat(e.getMessage(), containsString("Transaction bundle contains multiple resources with ID: Patient/ABC")); - } - } - @SuppressWarnings("unchecked") private T find(Bundle theBundle, Class theType, int theIndex) { int count = 0; @@ -470,6 +441,17 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest { } } + /** + * See #1044 + */ + @Test + public void testStructureDefinitionInBundle() throws IOException { + String input = IOUtils.toString(FhirSystemDaoDstu3Test.class.getResourceAsStream("/bug1044-bundle.xml"), Charsets.UTF_8); + Bundle inputBundle = myFhirCtx.newXmlParser().parseResource(Bundle.class, input); + + mySystemDao.transaction(mySrd, inputBundle); + } + @Test public void testSystemMetaOperation() { @@ -2256,6 +2238,36 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest { } + @Test + public void testTransactionUpdateTwoResourcesWithSameId() { + Bundle request = new Bundle(); + + Patient p = new Patient(); + p.addIdentifier().setSystem("urn:system").setValue("DDD"); + p.setId("Patient/ABC"); + request.addEntry() + .setResource(p) + .getRequest() + .setMethod(HTTPVerb.PUT) + .setUrl("Patient/ABC"); + + p = new Patient(); + p.addIdentifier().setSystem("urn:system").setValue("DDD"); + p.setId("Patient/ABC"); + request.addEntry() + .setResource(p) + .getRequest() + .setMethod(HTTPVerb.PUT) + .setUrl("Patient/ABC"); + + try { + mySystemDao.transaction(mySrd, request); + fail(); + } catch (InvalidRequestException e) { + assertThat(e.getMessage(), containsString("Transaction bundle contains multiple resources with ID: Patient/ABC")); + } + } + @Test public void testTransactionWIthInvalidPlaceholder() throws Exception { Bundle res = new Bundle(); diff --git a/hapi-fhir-jpaserver-base/src/test/resources/bug1044-bundle.xml b/hapi-fhir-jpaserver-base/src/test/resources/bug1044-bundle.xml new file mode 100644 index 00000000000..d86d0a79e6b --- /dev/null +++ b/hapi-fhir-jpaserver-base/src/test/resources/bug1044-bundle.xml @@ -0,0 +1,214 @@ + + + + + + + + + + + + + <status value="draft"/> + <date value="2018-06-28"/> + <publisher value="HL7 Deutschland e.V. (Technisches Komitee FHIR)"/> + <contact> + <telecom> + <system value="other"/> + <value value="http://hl7.de/technische-komitees/fhir/"/> + </telecom> + </contact> + <description value="Basisprofil für die Verwendung der Organization Ressource in Deutschland."/> + <copyright value="HL7 Deutschland e.V."/> + <fhirVersion value="3.0.1"/> + <kind value="resource"/> + <abstract value="false"/> + <type value="Organization"/> + <baseDefinition value="http://hl7.org/fhir/StructureDefinition/Organization"/> + <differential> + <element id="Organization"> + <path value="Organization"/> + <short value="Organisationen im deutschen Gesundheitswesen."/> + <definition + value="Basisprofil für die Repräsentation verschiedener Organisationen mit in Deutschland üblichen Identifiern."/> + </element> + <element id="Organization.extension"> + <path value="Organization.extension"/> + <slicing> + <discriminator> + <type value="value"/> + <path value="url"/> + </discriminator> + <rules value="open"/> + </slicing> + </element> + <element id="Organization.extension:betriebsstaetten-hierarchie"> + <path value="Organization.extension"/> + <sliceName value="betriebsstaetten-hierarchie"/> + <max value="1"/> + <type> + <code value="Extension"/> + <profile value="http://fhir.de/StructureDefinition/betriebsstaetten-hierarchie/0.2"/> + </type> + </element> + <element id="Organization.identifier"> + <path value="Organization.identifier"/> + <slicing> + <discriminator> + <type value="value"/> + <path value="system"/> + </discriminator> + <discriminator> + <type value="value"/> + <path value="value"/> + </discriminator> + <rules value="open"/> + </slicing> + <short value="Identifiziert eine Organisation"/> + <definition + value="Identifikator für die Organisation, mit dem die Organisation über mehrere verschiedene Systeme hinweg identifiziert wird."/> + </element> + <element id="Organization.identifier.system"> + <path value="Organization.identifier.system"/> + <min value="1"/> + </element> + <element id="Organization.identifier.value"> + <path value="Organization.identifier.value"/> + <min value="1"/> + </element> + <element id="Organization.identifier:Betriebsstaettennummer"> + <path value="Organization.identifier"/> + <sliceName value="Betriebsstaettennummer"/> + <short value="Betriebstättennummer (BSNR) vergeben durch die KBV."/> + <definition + value="Die Betriebsstättennummer (BSNR) entspricht der bis zum 30. Juni 2008 gültigen siebenstelligen KV-Abrechnungsnummer, ergänzt um zwei angehängte Nullen. Sie identifiziert die Arztpraxis als abrechnende Einheit und ermöglicht die Zuordnung ärztlicher Leistungen zum Ort der Leistungserbringung. Dabei umfasst der Begriff Arztpraxis auch Medizinische Versorgungszentren (MVZ), Institute, Notfallambulanzen sowie Ermächtigungen an Krankenhäusern. Stellen 1–2: KV-Landes- oder Bezirksstellenschlüssel[1] Stellen 3–7: eindeutige Identifikationsnummer der KV, in deren Bereich die Betriebsstätte liegt Stellen 8, 9: „00“"/> + <max value="1"/> + </element> + <element id="Organization.identifier:Betriebsstaettennummer.system"> + <path value="Organization.identifier.system"/> + <short value="Namespace für Betriebsstättennnummern der KBV"/> + <definition value="Die URL dient als eindeutiger Name des BSNR-Nummernkreises."/> + <min value="1"/> + <fixedUri value="http://fhir.de/NamingSystem/kbv/bsnr"/> + </element> + <element id="Organization.identifier:Betriebsstaettennummer.value"> + <path value="Organization.identifier.value"/> + <short value="Betriebsstättennummer der Organisation"/> + <definition value="Betriebsstättennummer der Organisation"/> + <min value="1"/> + </element> + <element id="Organization.identifier:Betriebsstaettennummer.period"> + <path value="Organization.identifier.period"/> + <short value="Zeitraum in welchem der Identifikator gültig ist oder war."/> + <definition value="Zeitraum in welchem der Identifikator gültig ist oder war."/> + </element> + <element id="Organization.identifier:Betriebsstaettennummer.period.start"> + <path value="Organization.identifier.period.start"/> + <short value="Beginn der BSNR Gültigkeit"/> + <definition value="Beginn der BSNR Gültigkeit"/> + </element> + <element id="Organization.identifier:Betriebsstaettennummer.period.end"> + <path value="Organization.identifier.period.end"/> + <short value="Ende der BSNR Gültigkeit"/> + <definition value="Ende der BSNR Gültigkeit. leer, falls aktuell gültig."/> + </element> + <element id="Organization.identifier:Betriebsstaettennummer.assigner"> + <path value="Organization.identifier.assigner"/> + <short value="Organisation welche den Identifikator vergeben hat."/> + <definition value="Organisation welche den Identifikator vergeben hat."/> + </element> + <element id="Organization.identifier:Betriebsstaettennummer.assigner.display"> + <extension url="http://hl7.org/fhir/StructureDefinition/elementdefinition-translatable"> + <valueBoolean value="true"/> + </extension> + <path value="Organization.identifier.assigner.display"/> + <short value="Name der zuständigen Kassenärztlichen Vereinigung (KV)"/> + <definition + value="Name der zuständigen Kassenärztlichen Vereinigung (KV). z.B.: "KV Baden-Württemberg""/> + </element> + <element id="Organization.identifier:Institutionskennzeichen"> + <path value="Organization.identifier"/> + <sliceName value="Institutionskennzeichen"/> + <short value="IK Nummer vergeben durch die Arbeitsgemeinschaft Institutionskennzeichen."/> + <definition + value="Die Institutionskennzeichen (kurz: IK) sind bundesweit eindeutige, neunstellige Zahlen vergeben durch die Arbeitsgemeinschaft Institutionskennzeichen, mit deren Hilfe Abrechnungen und Qualitätssicherungsmaßnahmen im Bereich der deutschen Sozialversicherung einrichtungsübergreifend abgewickelt werden können. "/> + <max value="1"/> + </element> + <element id="Organization.identifier:Institutionskennzeichen.system"> + <path value="Organization.identifier.system"/> + <short value="Namespace für Instituskennzeichen."/> + <min value="1"/> + <fixedUri value=" http://fhir.de/NamingSystem/arge-ik/iknr"/> + </element> + <element id="Organization.identifier:Institutionskennzeichen.value"> + <path value="Organization.identifier.value"/> + <short value="Institutskennzeichen der Organisation"/> + <definition value="Institutskennzeichen der Organisation"/> + <min value="1"/> + </element> + <element id="Organization.identifier:ASV-Teamnummer"> + <path value="Organization.identifier"/> + <sliceName value="ASV-Teamnummer"/> + <short value="Die ASV-Teamnummer"/> + <definition value="ASV-Teamnummer. Wird nur für Organizations vom Typ ASV-Team vergeben."/> + <max value="1"/> + </element> + <element id="Organization.identifier:ASV-Teamnummer.system"> + <path value="Organization.identifier.system"/> + <min value="1"/> + <fixedUri value="http://fhir.de/NamingSystem/asv/teamnummer"/> + </element> + <element id="Organization.identifier:ASV-Teamnummer.value"> + <path value="Organization.identifier.value"/> + <min value="1"/> + </element> + <element id="Organization.type"> + <path value="Organization.type"/> + <short value="Art(en) der Organisation"/> + <definition value="Art(en) der Organisation"/> + <binding> + <extension url="http://hl7.org/fhir/StructureDefinition/elementdefinition-bindingName"> + <valueString value="OrganizationType"/> + </extension> + <strength value="extensible"/> + <valueSetUri value="http://fhir.de/ValueSet/arge-ik/klassifikation"/> + </binding> + </element> + <element id="Organization.type.coding"> + <path value="Organization.type.coding"/> + <short value="IK Klassifikation der Organisation"/> + <definition value="IK Klassifikation der Organisation"/> + </element> + <element id="Organization.name"> + <path value="Organization.name"/> + <short value="Name der Betriebsstätte"/> + <definition + value="Menschenlesbarer Name der Betriebsstätte, z.B.: "Gemeinschaftspraxis Dr. Soundso""/> + </element> + <element id="Organization.address"> + <path value="Organization.address"/> + <type> + <code value="Address"/> + <profile value="http://fhir.de/StructureDefinition/address-de-basis/0.2"/> + </type> + </element> + <element id="Organization.address.state"> + <path value="Organization.address.state"/> + <definition value="Name (oder Kürzel) des Bundeslandes."/> + </element> + <element id="Organization.partOf"> + <path value="Organization.partOf"/> + <type> + <code value="Reference"/> + <targetProfile value="http://fhir.de/StructureDefinition/organization-de-basis/0.2"/> + </type> + </element> + </differential> + </StructureDefinition> + </resource> + <request> + <method value="POST"/> + </request> + </entry> +</Bundle> diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/provider/HashMapResourceProvider.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/provider/HashMapResourceProvider.java index bf2da88e36b..4df6926456c 100644 --- a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/provider/HashMapResourceProvider.java +++ b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/provider/HashMapResourceProvider.java @@ -20,7 +20,10 @@ package ca.uhn.fhir.rest.server.provider; * #L% */ -import ca.uhn.fhir.context.*; +import ca.uhn.fhir.context.BaseRuntimeChildDefinition; +import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition; +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.context.FhirVersionEnum; import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum; import ca.uhn.fhir.rest.annotation.*; @@ -40,7 +43,6 @@ import org.slf4j.LoggerFactory; import java.util.*; import java.util.concurrent.atomic.AtomicLong; -import java.util.stream.Collectors; /** * This class is a simple implementation of the resource provider @@ -236,6 +238,21 @@ public class HashMapResourceProvider<T extends IBaseResource> implements IResour return retVal; } + @Search + public List<IBaseResource> searchAll() { + List<IBaseResource> retVal = new ArrayList<>(); + + for (TreeMap<Long, T> next : myIdToVersionToResourceMap.values()) { + if (next.isEmpty() == false) { + T nextResource = next.lastEntry().getValue(); + retVal.add(nextResource); + } + } + + mySearchCount.incrementAndGet(); + return retVal; + } + @Search public List<IBaseResource> searchById( @RequiredParam(name = "_id") TokenAndListParam theIds) { diff --git a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/provider/HashMapResourceProviderTest.java b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/provider/HashMapResourceProviderTest.java index d18aa672276..eadbc300546 100644 --- a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/provider/HashMapResourceProviderTest.java +++ b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/provider/HashMapResourceProviderTest.java @@ -202,7 +202,11 @@ public class HashMapResourceProviderTest { } // Search - Bundle resp = ourClient.search().forResource("Patient").returnBundle(Bundle.class).execute(); + Bundle resp = ourClient + .search() + .forResource("Patient") + .returnBundle(Bundle.class) + .execute(); assertEquals(100, resp.getTotal()); assertEquals(100, resp.getEntry().size());