From 7eb36c3392b3e24e888f0e83b7aa3c43b56699d7 Mon Sep 17 00:00:00 2001 From: jamesagnew Date: Sat, 11 Aug 2018 16:14:53 -0400 Subject: [PATCH] Work on subscription --- ...ashMapResourceProviderConceptMapDstu3.java | 14 +- .../HashMapResourceProviderConceptMapR4.java | 15 +- .../AbstractHashMapResourceProvider.java | 198 ------------------ .../provider/HashMapResourceProvider.java | 12 +- 4 files changed, 25 insertions(+), 214 deletions(-) delete mode 100644 hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/provider/AbstractHashMapResourceProvider.java diff --git a/hapi-fhir-cli/hapi-fhir-cli-api/src/test/java/ca/uhn/fhir/cli/HashMapResourceProviderConceptMapDstu3.java b/hapi-fhir-cli/hapi-fhir-cli-api/src/test/java/ca/uhn/fhir/cli/HashMapResourceProviderConceptMapDstu3.java index 7ca6a49417f..9550a66ab17 100644 --- a/hapi-fhir-cli/hapi-fhir-cli-api/src/test/java/ca/uhn/fhir/cli/HashMapResourceProviderConceptMapDstu3.java +++ b/hapi-fhir-cli/hapi-fhir-cli-api/src/test/java/ca/uhn/fhir/cli/HashMapResourceProviderConceptMapDstu3.java @@ -25,7 +25,7 @@ import ca.uhn.fhir.context.FhirVersionEnum; import ca.uhn.fhir.rest.annotation.*; import ca.uhn.fhir.rest.api.MethodOutcome; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; -import ca.uhn.fhir.rest.server.provider.AbstractHashMapResourceProvider; +import ca.uhn.fhir.rest.server.provider.HashMapResourceProvider; import com.google.common.base.Charsets; import org.apache.http.NameValuePair; import org.apache.http.client.utils.URLEncodedUtils; @@ -42,7 +42,7 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank; /** * This is a subclass to implement FHIR operations specific to DSTU3 ConceptMap - * resources. Its superclass, {@link AbstractHashMapResourceProvider}, is a simple + * resources. Its superclass, {@link HashMapResourceProvider}, is a simple * implementation of the resource provider interface that uses a HashMap to * store all resources in memory. *

@@ -53,7 +53,7 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank; *

  • Conditional update for DSTU3 ConceptMap resources by ConceptMap.url
  • * */ -public class HashMapResourceProviderConceptMapDstu3 extends AbstractHashMapResourceProvider { +public class HashMapResourceProviderConceptMapDstu3 extends HashMapResourceProvider { @SuppressWarnings("unchecked") public HashMapResourceProviderConceptMapDstu3(FhirContext theFhirContext) { super(theFhirContext, ConceptMap.class); @@ -84,10 +84,10 @@ public class HashMapResourceProviderConceptMapDstu3 extends AbstractHashMapResou return retVal; } + @Override @Update - public MethodOutcome updateConceptMapConditional( + public MethodOutcome update( @ResourceParam ConceptMap theConceptMap, - @IdParam IdType theId, @ConditionalUrlParam String theConditional) { MethodOutcome methodOutcome = new MethodOutcome(); @@ -112,14 +112,14 @@ public class HashMapResourceProviderConceptMapDstu3 extends AbstractHashMapResou List conceptMaps = searchByUrl(url); if (!conceptMaps.isEmpty()) { - methodOutcome = update(conceptMaps.get(0)); + methodOutcome = super.update(conceptMaps.get(0), null); } else { methodOutcome = create(theConceptMap); } } } else { - methodOutcome = update(theConceptMap); + methodOutcome = super.update(theConceptMap, null); } return methodOutcome; diff --git a/hapi-fhir-cli/hapi-fhir-cli-api/src/test/java/ca/uhn/fhir/cli/HashMapResourceProviderConceptMapR4.java b/hapi-fhir-cli/hapi-fhir-cli-api/src/test/java/ca/uhn/fhir/cli/HashMapResourceProviderConceptMapR4.java index d958ae5a3c4..471af74a751 100644 --- a/hapi-fhir-cli/hapi-fhir-cli-api/src/test/java/ca/uhn/fhir/cli/HashMapResourceProviderConceptMapR4.java +++ b/hapi-fhir-cli/hapi-fhir-cli-api/src/test/java/ca/uhn/fhir/cli/HashMapResourceProviderConceptMapR4.java @@ -25,7 +25,7 @@ import ca.uhn.fhir.context.FhirVersionEnum; import ca.uhn.fhir.rest.annotation.*; import ca.uhn.fhir.rest.api.MethodOutcome; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; -import ca.uhn.fhir.rest.server.provider.AbstractHashMapResourceProvider; +import ca.uhn.fhir.rest.server.provider.HashMapResourceProvider; import com.google.common.base.Charsets; import org.apache.http.NameValuePair; import org.apache.http.client.utils.URLEncodedUtils; @@ -42,7 +42,7 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank; /** * This is a subclass to implement FHIR operations specific to R4 ConceptMap - * resources. Its superclass, {@link AbstractHashMapResourceProvider}, is a simple + * resources. Its superclass, {@link HashMapResourceProvider}, is a simple * implementation of the resource provider interface that uses a HashMap to * store all resources in memory. *

    @@ -53,7 +53,7 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank; *

  • Conditional update for R4 ConceptMap resources by ConceptMap.url
  • * */ -public class HashMapResourceProviderConceptMapR4 extends AbstractHashMapResourceProvider { +public class HashMapResourceProviderConceptMapR4 extends HashMapResourceProvider { @SuppressWarnings("unchecked") public HashMapResourceProviderConceptMapR4(FhirContext theFhirContext) { super(theFhirContext, ConceptMap.class); @@ -84,16 +84,15 @@ public class HashMapResourceProviderConceptMapR4 extends AbstractHashMapResource return retVal; } + @Override @Update - public MethodOutcome updateConceptMapConditional( + public MethodOutcome update( @ResourceParam ConceptMap theConceptMap, - @IdParam IdType theId, @ConditionalUrlParam String theConditional) { MethodOutcome methodOutcome = new MethodOutcome(); if (theConditional != null) { - String url = null; try { @@ -112,14 +111,14 @@ public class HashMapResourceProviderConceptMapR4 extends AbstractHashMapResource List conceptMaps = searchByUrl(url); if (!conceptMaps.isEmpty()) { - methodOutcome = update(conceptMaps.get(0)); + methodOutcome = super.update(conceptMaps.get(0), null); } else { methodOutcome = create(theConceptMap); } } } else { - methodOutcome = update(theConceptMap); + methodOutcome = super.update(theConceptMap, null); } return methodOutcome; diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/provider/AbstractHashMapResourceProvider.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/provider/AbstractHashMapResourceProvider.java deleted file mode 100644 index 0756072e34b..00000000000 --- a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/provider/AbstractHashMapResourceProvider.java +++ /dev/null @@ -1,198 +0,0 @@ -package ca.uhn.fhir.rest.server.provider; - -/*- - * #%L - * HAPI FHIR - Server Framework - * %% - * Copyright (C) 2014 - 2018 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 ca.uhn.fhir.context.FhirContext; -import ca.uhn.fhir.rest.annotation.*; -import ca.uhn.fhir.rest.api.MethodOutcome; -import ca.uhn.fhir.rest.server.IResourceProvider; -import ca.uhn.fhir.rest.server.exceptions.ResourceGoneException; -import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException; -import org.hl7.fhir.instance.model.api.IBaseResource; -import org.hl7.fhir.instance.model.api.IIdType; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.*; - -/** - * This class is a simple implementation of the resource provider - * interface that uses a HashMap to store all resources in memory. - * It is essentially a copy of {@link ca.uhn.fhir.rest.server.provider.HashMapResourceProvider} - * with the {@link Update} and {@link ResourceParam} annotations removed from method - * {@link ca.uhn.fhir.rest.server.provider.HashMapResourceProvider#update(IBaseResource)}. - * Non-generic subclasses of this abstract class may implement their own annotated methods (e.g. a conditional - * update method specifically for ConceptMap resources). - *

    - * This class currently supports the following FHIR operations: - *

    - *
      - *
    • Create
    • - *
    • Update existing resource
    • - *
    • Update non-existing resource (e.g. create with client-supplied ID)
    • - *
    • Delete
    • - *
    • Search by resource type with no parameters
    • - *
    - * - * @param The resource type to support - */ -public class AbstractHashMapResourceProvider implements IResourceProvider { - private static final Logger ourLog = LoggerFactory.getLogger(AbstractHashMapResourceProvider.class); - private final Class myResourceType; - private final FhirContext myFhirContext; - private final String myResourceName; - protected Map> myIdToVersionToResourceMap = new HashMap<>(); - private long myNextId; - - /** - * Constructor - * - * @param theFhirContext The FHIR context - * @param theResourceType The resource type to support - */ - @SuppressWarnings("WeakerAccess") - public AbstractHashMapResourceProvider(FhirContext theFhirContext, Class theResourceType) { - myFhirContext = theFhirContext; - myResourceType = theResourceType; - myResourceName = myFhirContext.getResourceDefinition(theResourceType).getName(); - clear(); - } - - /** - * Clear all data held in this resource provider - */ - public void clear() { - myNextId = 1; - myIdToVersionToResourceMap.clear(); - } - - @Create - public MethodOutcome create(@ResourceParam T theResource) { - long idPart = myNextId++; - String idPartAsString = Long.toString(idPart); - Long versionIdPart = 1L; - - IIdType id = store(theResource, idPartAsString, versionIdPart); - - return new MethodOutcome() - .setCreated(true) - .setId(id); - } - - @Delete - public MethodOutcome delete(@IdParam IIdType theId) { - TreeMap versions = myIdToVersionToResourceMap.get(theId.getIdPart()); - if (versions == null || versions.isEmpty()) { - throw new ResourceNotFoundException(theId); - } - - long nextVersion = versions.lastEntry().getKey() + 1L; - IIdType id = store(null, theId.getIdPart(), nextVersion); - - return new MethodOutcome() - .setId(id); - } - - @Override - public Class getResourceType() { - return myResourceType; - } - - private synchronized TreeMap getVersionToResource(String theIdPart) { - if (!myIdToVersionToResourceMap.containsKey(theIdPart)) { - myIdToVersionToResourceMap.put(theIdPart, new TreeMap()); - } - return myIdToVersionToResourceMap.get(theIdPart); - } - - @Read(version = true) - public IBaseResource read(@IdParam IIdType theId) { - TreeMap versions = myIdToVersionToResourceMap.get(theId.getIdPart()); - if (versions == null || versions.isEmpty()) { - throw new ResourceNotFoundException(theId); - } - - if (theId.hasVersionIdPart()) { - Long versionId = theId.getVersionIdPartAsLong(); - if (!versions.containsKey(versionId)) { - throw new ResourceNotFoundException(theId); - } else { - T resource = versions.get(versionId); - if (resource == null) { - throw new ResourceGoneException(theId); - } - return resource; - } - - } else { - return versions.lastEntry().getValue(); - } - } - - @Search - public List search() { - List retVal = new ArrayList<>(); - - for (TreeMap next : myIdToVersionToResourceMap.values()) { - if (next.isEmpty() == false) { - retVal.add(next.lastEntry().getValue()); - } - } - - return retVal; - } - - private IIdType store(@ResourceParam T theResource, String theIdPart, Long theVersionIdPart) { - IIdType id = myFhirContext.getVersion().newIdType(); - id.setParts(null, myResourceName, theIdPart, Long.toString(theVersionIdPart)); - if (theResource != null) { - theResource.setId(id); - } - - TreeMap versionToResource = getVersionToResource(theIdPart); - versionToResource.put(theVersionIdPart, theResource); - - ourLog.info("Storing resource with ID: {}", id.getValue()); - - return id; - } - - public MethodOutcome update(T theResource) { - String idPartAsString = theResource.getIdElement().getIdPart(); - TreeMap versionToResource = getVersionToResource(idPartAsString); - - Long versionIdPart; - Boolean created; - if (versionToResource.isEmpty()) { - versionIdPart = 1L; - created = true; - } else { - versionIdPart = versionToResource.lastKey() + 1L; - created = false; - } - - IIdType id = store(theResource, idPartAsString, versionIdPart); - - return new MethodOutcome() - .setCreated(created) - .setId(id); - } -} 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 e876efa85fc..59a14d9f2b7 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 @@ -34,6 +34,7 @@ import ca.uhn.fhir.rest.param.TokenParam; import ca.uhn.fhir.rest.server.IResourceProvider; import ca.uhn.fhir.rest.server.exceptions.ResourceGoneException; import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException; +import ca.uhn.fhir.util.ValidateUtil; import org.hl7.fhir.instance.model.api.IBase; import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IIdType; @@ -44,6 +45,8 @@ import org.slf4j.LoggerFactory; import java.util.*; import java.util.concurrent.atomic.AtomicLong; +import static org.apache.commons.lang3.StringUtils.isBlank; + /** * This class is a simple implementation of the resource provider * interface that uses a HashMap to store all resources in memory. @@ -338,8 +341,15 @@ public class HashMapResourceProvider implements IResour return id; } + /** + * @param theConditional This is provided only so that subclasses can implement if they want + */ @Update - public MethodOutcome update(@ResourceParam T theResource) { + public MethodOutcome update( + @ResourceParam T theResource, + @ConditionalUrlParam String theConditional) { + + ValidateUtil.isTrueOrThrowInvalidRequest(isBlank(theConditional), "This server doesn't support conditional update"); String idPartAsString = theResource.getIdElement().getIdPart(); TreeMap versionToResource = getVersionToResource(idPartAsString);