/** {@inheritDoc} not needed in Testserver */ public UriDt post(IResource res) { log.info(res.getClass().toString()); String resURI = "http://www.test-server.de/" + res.getClass().getSimpleName() + "/" + resNumber; UriDt setUri = new UriDt(resURI); log.info("TestSever Created ID: " + resURI); resMap.put(resURI, res); resNumber++; return setUri; }
private String parseNarrative( HomeRequest theRequest, EncodingEnum theCtEnum, String theResultBody) { try { IBaseResource par = theCtEnum.newParser(getContext(theRequest)).parseResource(theResultBody); String retVal; if (par instanceof IResource) { IResource resource = (IResource) par; retVal = resource.getText().getDiv().getValueAsString(); } else if (par instanceof IDomainResource) { retVal = ((IDomainResource) par).getText().getDivAsString(); } else { retVal = null; } return StringUtils.defaultString(retVal); } catch (Exception e) { ourLog.error("Failed to parse resource", e); return ""; } }
private void encodeResourceToXmlStreamWriter( IBaseResource theResource, XMLStreamWriter theEventWriter, boolean theIncludedResource) throws XMLStreamException, DataFormatException { String resourceId = null; if (theResource instanceof IResource) { // HAPI structs IResource iResource = (IResource) theResource; if (StringUtils.isNotBlank(iResource.getId().getValue())) { resourceId = iResource.getId().getIdPart(); } } else { // HL7 structs IAnyResource resource = (IAnyResource) theResource; if (StringUtils.isNotBlank(resource.getId())) { resourceId = resource.getId(); } } encodeResourceToXmlStreamWriter(theResource, theEventWriter, theIncludedResource, resourceId); }
@Override public IDeleteTyped resource(IResource theResource) { Validate.notNull(theResource, "theResource can not be null"); IdDt id = theResource.getId(); Validate.notNull(id, "theResource.getId() can not be null"); if (id.hasResourceType() == false || id.hasIdPart() == false) { throw new IllegalArgumentException( "theResource.getId() must contain a resource type and logical ID at a minimum (e.g. Patient/1234), found: " + id.getValue()); } myId = id; return this; }
/** * @notice In Fhir model, {@link Patient} has a collection of names, while in this extension * table, {@link PersonComplement}, there is only one name for each {@link Person}. */ @Override public IResourceEntity constructEntityFromResource(IResource resource) { super.constructEntityFromResource(resource); if (resource instanceof Patient) { Patient patient = (Patient) resource; Iterator<HumanNameDt> iterator = patient.getName().iterator(); // while(iterator.hasNext()){ if (iterator.hasNext()) { HumanNameDt next = iterator.next(); this.givenName1 = next.getGiven() .get(0) .getValue(); // the next method was not advancing to the next element, then the need // to use the get(index) method if (next.getGiven().size() > 1) // TODO add unit tests, to assure this won't be changed to hasNext this.givenName2 = next.getGiven().get(1).getValue(); Iterator<StringDt> family = next.getFamily().iterator(); this.familyName = ""; while (family.hasNext()) { this.familyName = this.familyName.concat(family.next().getValue() + " "); } if (next.getSuffix().iterator().hasNext()) this.suffixName = next.getSuffix().iterator().next().getValue(); if (next.getPrefix().iterator().hasNext()) this.prefixName = next.getPrefix().iterator().next().getValue(); } // } this.active = patient.getActive(); // MARITAL STATUS // // this.maritalStatus.setId(OmopConceptMapping.getInstance().get(OmopConceptMapping.MARITAL_STATUS, patient.getMaritalStatus().getText())); } else { ourLog.error( "There was not possible to construct the entity ? using the resource ?. It should be used the resource ?.", this.getClass().getSimpleName(), resource.getResourceName(), getResourceType()); } return this; }
@Override public MethodOutcome execute() { if (myResource == null) { myResource = parseResourceBody(myResourceBody); } if (myId == null) { myId = myResource.getId(); } if (myId == null || myId.hasIdPart() == false) { throw new InvalidRequestException( "No ID supplied for resource to update, can not invoke server"); } BaseHttpClientInvocation invocation = MethodUtil.createUpdateInvocation(myResource, myResourceBody, myId, myContext); RuntimeResourceDefinition def = myContext.getResourceDefinition(myResource); final String resourceName = def.getName(); OutcomeResponseHandler binding = new OutcomeResponseHandler(resourceName); Map<String, List<String>> params = new HashMap<String, List<String>>(); return invoke(params, binding, invocation); }
@SuppressWarnings("unchecked") @Override public Object invokeServer( IRestfulServer theServer, RequestDetails theRequest, Object[] theMethodParams) throws InvalidRequestException, InternalErrorException { /* * The design of HAPI's transaction method for DSTU1 support assumed that a transaction was just an update on a * bunch of resources (because that's what it was), but in DSTU2 transaction has become much more broad, so we * no longer hold the user's hand much here. */ if (myTransactionParamStyle == ParamStyle.RESOURCE_BUNDLE) { // This is the DSTU2 style Object response = invokeServerMethod(theServer, theRequest, theMethodParams); return response; } // Grab the IDs of all of the resources in the transaction List<IResource> resources; if (theMethodParams[myTransactionParamIndex] instanceof Bundle) { resources = ((Bundle) theMethodParams[myTransactionParamIndex]).toListOfResources(); } else { resources = (List<IResource>) theMethodParams[myTransactionParamIndex]; } IdentityHashMap<IResource, IdDt> oldIds = new IdentityHashMap<IResource, IdDt>(); for (IResource next : resources) { oldIds.put(next, next.getId()); } // Call the server implementation method Object response = invokeServerMethod(theServer, theRequest, theMethodParams); 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)"); } } */ List<IBaseResource> retResources = retVal.getResources(0, retVal.size()); for (int i = 0; i < retResources.size(); i++) { IdDt oldId = oldIds.get(retResources.get(i)); IBaseResource newRes = retResources.get(i); if (newRes.getIdElement() == null || newRes.getIdElement().isEmpty()) { if (!(newRes instanceof BaseOperationOutcome)) { throw new InternalErrorException( "Transaction method returned resource at index " + i + " with no id specified - IResource#setId(IdDt)"); } } if (oldId != null && !oldId.isEmpty()) { if (!oldId.equals(newRes.getIdElement()) && newRes instanceof IResource) { ((IResource) newRes) .getResourceMetadata() .put(ResourceMetadataKeyEnum.PREVIOUS_ID, oldId); } } } return retVal; }
private void encodeResourceToXmlStreamWriter( IBaseResource theResource, XMLStreamWriter theEventWriter, boolean theContainedResource, String theResourceId) throws XMLStreamException { if (!theContainedResource) { super.containResourcesForEncoding(theResource); } RuntimeResourceDefinition resDef = myContext.getResourceDefinition(theResource); if (resDef == null) { throw new ConfigurationException("Unknown resource type: " + theResource.getClass()); } theEventWriter.writeStartElement(resDef.getName()); theEventWriter.writeDefaultNamespace(FHIR_NS); if (theResource instanceof IAnyResource) { // HL7.org Structures encodeCompositeElementToStreamWriter( theResource, theResource, theEventWriter, resDef, theContainedResource); } else { if (myContext.getVersion().getVersion().isNewerThan(FhirVersionEnum.DSTU1)) { // DSTU2+ IResource resource = (IResource) theResource; writeOptionalTagWithValue(theEventWriter, "id", theResourceId); InstantDt updated = (InstantDt) resource.getResourceMetadata().get(ResourceMetadataKeyEnum.UPDATED); IdDt resourceId = resource.getId(); String versionIdPart = resourceId.getVersionIdPart(); if (isBlank(versionIdPart)) { versionIdPart = ResourceMetadataKeyEnum.VERSION.get(resource); } List<BaseCodingDt> securityLabels = extractMetadataListNotNull(resource, ResourceMetadataKeyEnum.SECURITY_LABELS); List<IdDt> profiles = extractMetadataListNotNull(resource, ResourceMetadataKeyEnum.PROFILES); TagList tags = ResourceMetadataKeyEnum.TAG_LIST.get(resource); if (ElementUtil.isEmpty(versionIdPart, updated, securityLabels, profiles) == false) { theEventWriter.writeStartElement("meta"); writeOptionalTagWithValue(theEventWriter, "versionId", versionIdPart); if (updated != null) { writeOptionalTagWithValue(theEventWriter, "lastUpdated", updated.getValueAsString()); } for (IdDt profile : profiles) { theEventWriter.writeStartElement("profile"); theEventWriter.writeAttribute("value", profile.getValue()); theEventWriter.writeEndElement(); } for (BaseCodingDt securityLabel : securityLabels) { theEventWriter.writeStartElement("security"); BaseRuntimeElementCompositeDefinition<?> def = (BaseRuntimeElementCompositeDefinition<?>) myContext.getElementDefinition(securityLabel.getClass()); encodeCompositeElementChildrenToStreamWriter( resource, securityLabel, theEventWriter, def.getChildren(), theContainedResource); theEventWriter.writeEndElement(); } if (tags != null) { for (Tag tag : tags) { theEventWriter.writeStartElement("tag"); writeOptionalTagWithValue(theEventWriter, "system", tag.getScheme()); writeOptionalTagWithValue(theEventWriter, "code", tag.getTerm()); writeOptionalTagWithValue(theEventWriter, "display", tag.getLabel()); theEventWriter.writeEndElement(); } } theEventWriter.writeEndElement(); } if (theResource instanceof IBaseBinary) { IBaseBinary bin = (IBaseBinary) theResource; writeOptionalTagWithValue(theEventWriter, "contentType", bin.getContentType()); writeOptionalTagWithValue(theEventWriter, "content", bin.getContentAsBase64()); } else { encodeResourceToStreamWriterInDstu2Format( resDef, theResource, theResource, theEventWriter, resDef, theContainedResource); } } else { // DSTU1 if (theResourceId != null && theContainedResource) { theEventWriter.writeAttribute("id", theResourceId); } if (theResource instanceof IBaseBinary) { IBaseBinary bin = (IBaseBinary) theResource; if (bin.getContentType() != null) { theEventWriter.writeAttribute("contentType", bin.getContentType()); } theEventWriter.writeCharacters(bin.getContentAsBase64()); } else { encodeCompositeElementToStreamWriter( theResource, theResource, theEventWriter, resDef, theContainedResource); } } } theEventWriter.writeEndElement(); }
private void encodeBundleToWriterDstu2(Bundle theBundle, XMLStreamWriter theEventWriter) throws XMLStreamException { theEventWriter.writeStartElement("Bundle"); theEventWriter.writeDefaultNamespace(FHIR_NS); writeOptionalTagWithValue(theEventWriter, "id", theBundle.getId().getIdPart()); InstantDt updated = (InstantDt) theBundle.getResourceMetadata().get(ResourceMetadataKeyEnum.UPDATED); IdDt bundleId = theBundle.getId(); if (bundleId != null && isNotBlank(bundleId.getVersionIdPart()) || (updated != null && !updated.isEmpty())) { theEventWriter.writeStartElement("meta"); writeOptionalTagWithValue(theEventWriter, "versionId", bundleId.getVersionIdPart()); if (updated != null) { writeOptionalTagWithValue(theEventWriter, "lastUpdated", updated.getValueAsString()); } theEventWriter.writeEndElement(); } String bundleBaseUrl = theBundle.getLinkBase().getValue(); writeOptionalTagWithValue(theEventWriter, "type", theBundle.getType().getValue()); writeOptionalTagWithValue(theEventWriter, "base", bundleBaseUrl); writeOptionalTagWithValue( theEventWriter, "total", theBundle.getTotalResults().getValueAsString()); writeBundleResourceLink(theEventWriter, "first", theBundle.getLinkFirst()); writeBundleResourceLink(theEventWriter, "previous", theBundle.getLinkPrevious()); writeBundleResourceLink(theEventWriter, "next", theBundle.getLinkNext()); writeBundleResourceLink(theEventWriter, "last", theBundle.getLinkLast()); writeBundleResourceLink(theEventWriter, "self", theBundle.getLinkSelf()); for (BundleEntry nextEntry : theBundle.getEntries()) { theEventWriter.writeStartElement("entry"); boolean deleted = false; if (nextEntry.getDeletedAt() != null && nextEntry.getDeletedAt().isEmpty() == false) { deleted = true; } writeOptionalTagWithValue( theEventWriter, "base", determineResourceBaseUrl(bundleBaseUrl, nextEntry)); IResource resource = nextEntry.getResource(); if (resource != null && !resource.isEmpty() && !deleted) { theEventWriter.writeStartElement("resource"); encodeResourceToXmlStreamWriter(resource, theEventWriter, false); theEventWriter.writeEndElement(); // content } else { ourLog.debug("Bundle entry contains null resource"); } if (nextEntry.getSearchMode().isEmpty() == false || nextEntry.getScore().isEmpty() == false) { theEventWriter.writeStartElement("search"); writeOptionalTagWithValue( theEventWriter, "mode", nextEntry.getSearchMode().getValueAsString()); writeOptionalTagWithValue(theEventWriter, "score", nextEntry.getScore().getValueAsString()); theEventWriter.writeEndElement(); // IResource nextResource = nextEntry.getResource(); } if (nextEntry.getTransactionMethod().isEmpty() == false || nextEntry.getLinkSearch().isEmpty() == false) { theEventWriter.writeStartElement("transaction"); writeOptionalTagWithValue( theEventWriter, "method", nextEntry.getTransactionMethod().getValue()); writeOptionalTagWithValue(theEventWriter, "url", nextEntry.getLinkSearch().getValue()); theEventWriter.writeEndElement(); } if (deleted) { theEventWriter.writeStartElement("deleted"); writeOptionalTagWithValue(theEventWriter, "type", nextEntry.getId().getResourceType()); writeOptionalTagWithValue(theEventWriter, "id", nextEntry.getId().getIdPart()); writeOptionalTagWithValue( theEventWriter, "versionId", nextEntry.getId().getVersionIdPart()); writeOptionalTagWithValue( theEventWriter, "instant", nextEntry.getDeletedAt().getValueAsString()); theEventWriter.writeEndElement(); } theEventWriter.writeEndElement(); // entry } theEventWriter.writeEndElement(); theEventWriter.close(); }
private void encodeBundleToWriterDstu1(Bundle theBundle, XMLStreamWriter eventWriter) throws XMLStreamException { eventWriter.writeStartElement("feed"); eventWriter.writeDefaultNamespace(ATOM_NS); writeTagWithTextNode(eventWriter, "title", theBundle.getTitle()); writeTagWithTextNode(eventWriter, "id", theBundle.getBundleId()); writeAtomLink(eventWriter, Constants.LINK_SELF, theBundle.getLinkSelf()); writeAtomLink(eventWriter, Constants.LINK_FIRST, theBundle.getLinkFirst()); writeAtomLink(eventWriter, Constants.LINK_PREVIOUS, theBundle.getLinkPrevious()); writeAtomLink(eventWriter, Constants.LINK_NEXT, theBundle.getLinkNext()); writeAtomLink(eventWriter, Constants.LINK_LAST, theBundle.getLinkLast()); writeAtomLink(eventWriter, Constants.LINK_FHIR_BASE, theBundle.getLinkBase()); if (theBundle.getTotalResults().getValue() != null) { eventWriter.writeStartElement("os", "totalResults", OPENSEARCH_NS); eventWriter.writeNamespace("os", OPENSEARCH_NS); eventWriter.writeCharacters(theBundle.getTotalResults().getValue().toString()); eventWriter.writeEndElement(); } writeOptionalTagWithTextNode(eventWriter, "updated", theBundle.getUpdated()); if (StringUtils.isNotBlank(theBundle.getAuthorName().getValue())) { eventWriter.writeStartElement("author"); writeTagWithTextNode(eventWriter, "name", theBundle.getAuthorName()); writeOptionalTagWithTextNode(eventWriter, "uri", theBundle.getAuthorUri()); eventWriter.writeEndElement(); } writeCategories(eventWriter, theBundle.getCategories()); for (BundleEntry nextEntry : theBundle.getEntries()) { boolean deleted = false; if (nextEntry.getDeletedAt() != null && nextEntry.getDeletedAt().isEmpty() == false) { deleted = true; eventWriter.writeStartElement("at", "deleted-entry", TOMBSTONES_NS); eventWriter.writeNamespace("at", TOMBSTONES_NS); if (nextEntry.getDeletedResourceId().isEmpty()) { writeOptionalAttribute(eventWriter, "ref", nextEntry.getId().getValueAsString()); } else { writeOptionalAttribute( eventWriter, "ref", nextEntry.getDeletedResourceId().getValueAsString()); } writeOptionalAttribute(eventWriter, "when", nextEntry.getDeletedAt().getValueAsString()); if (nextEntry.getDeletedByEmail().isEmpty() == false || nextEntry.getDeletedByName().isEmpty() == false) { eventWriter.writeStartElement(TOMBSTONES_NS, "by"); if (nextEntry.getDeletedByName().isEmpty() == false) { eventWriter.writeStartElement(TOMBSTONES_NS, "name"); eventWriter.writeCharacters(nextEntry.getDeletedByName().getValue()); eventWriter.writeEndElement(); } if (nextEntry.getDeletedByEmail().isEmpty() == false) { eventWriter.writeStartElement(TOMBSTONES_NS, "email"); eventWriter.writeCharacters(nextEntry.getDeletedByEmail().getValue()); eventWriter.writeEndElement(); } eventWriter.writeEndElement(); } if (nextEntry.getDeletedComment().isEmpty() == false) { eventWriter.writeStartElement(TOMBSTONES_NS, "comment"); eventWriter.writeCharacters(nextEntry.getDeletedComment().getValue()); eventWriter.writeEndElement(); } } else { eventWriter.writeStartElement("entry"); } writeOptionalTagWithTextNode(eventWriter, "title", nextEntry.getTitle()); if (!deleted) { if (nextEntry.getId().isEmpty() == false) { writeTagWithTextNode(eventWriter, "id", nextEntry.getId()); } else { writeTagWithTextNode(eventWriter, "id", nextEntry.getResource().getId()); } } writeOptionalTagWithTextNode(eventWriter, "updated", nextEntry.getUpdated()); writeOptionalTagWithTextNode(eventWriter, "published", nextEntry.getPublished()); writeCategories(eventWriter, nextEntry.getCategories()); if (!nextEntry.getLinkSelf().isEmpty()) { writeAtomLink(eventWriter, "self", nextEntry.getLinkSelf()); } if (!nextEntry.getLinkAlternate().isEmpty()) { writeAtomLink(eventWriter, "alternate", nextEntry.getLinkAlternate()); } if (!nextEntry.getLinkSearch().isEmpty()) { writeAtomLink(eventWriter, "search", nextEntry.getLinkSearch()); } IResource resource = nextEntry.getResource(); if (resource != null && !resource.isEmpty() && !deleted) { eventWriter.writeStartElement("content"); eventWriter.writeAttribute("type", "text/xml"); encodeResourceToXmlStreamWriter(resource, eventWriter, false); eventWriter.writeEndElement(); // content } else { ourLog.debug("Bundle entry contains null resource"); } if (!nextEntry.getSummary().isEmpty()) { eventWriter.writeStartElement("summary"); eventWriter.writeAttribute("type", "xhtml"); encodeXhtml(nextEntry.getSummary(), eventWriter); eventWriter.writeEndElement(); } eventWriter.writeEndElement(); // entry } eventWriter.writeEndElement(); eventWriter.close(); }
@Transactional(propagation = Propagation.REQUIRED) @Override public List<IResource> transaction( RequestDetails theRequestDetails, List<IResource> theResources) { ourLog.info("Beginning transaction with {} resources", theResources.size()); // Notify interceptors ActionRequestDetails requestDetails = new ActionRequestDetails(null, null); notifyInterceptors(RestOperationTypeEnum.TRANSACTION, requestDetails); long start = System.currentTimeMillis(); Set<IdDt> allIds = new HashSet<IdDt>(); for (int i = 0; i < theResources.size(); i++) { IResource res = theResources.get(i); if (res.getId().hasIdPart() && !res.getId().hasResourceType() && !isPlaceholder(res.getId())) { res.setId(new IdDt(toResourceName(res.getClass()), res.getId().getIdPart())); } /* * Ensure that the bundle doesn't have any duplicates, since this causes all kinds of weirdness */ if (isPlaceholder(res.getId())) { if (!allIds.add(res.getId())) { throw new InvalidRequestException( "Transaction bundle contains multiple resources with ID: " + res.getId()); } } else if (res.getId().hasResourceType() && res.getId().hasIdPart()) { IdDt nextId = res.getId().toUnqualifiedVersionless(); if (!allIds.add(nextId)) { throw new InvalidRequestException( "Transaction bundle contains multiple resources with ID: " + nextId); } } } FhirTerser terser = getContext().newTerser(); int creations = 0; int updates = 0; Map<IdDt, IdDt> idConversions = new HashMap<IdDt, IdDt>(); List<ResourceTable> persistedResources = new ArrayList<ResourceTable>(); List<IResource> retVal = new ArrayList<IResource>(); OperationOutcome oo = new OperationOutcome(); retVal.add(oo); Date updateTime = new Date(); for (int resourceIdx = 0; resourceIdx < theResources.size(); resourceIdx++) { IResource nextResource = theResources.get(resourceIdx); IdDt nextId = nextResource.getId(); if (nextId == null) { nextId = new IdDt(); } String resourceName = toResourceName(nextResource); BundleEntryTransactionMethodEnum nextResouceOperationIn = ResourceMetadataKeyEnum.ENTRY_TRANSACTION_METHOD.get(nextResource); if (nextResouceOperationIn == null && hasValue(ResourceMetadataKeyEnum.DELETED_AT.get(nextResource))) { nextResouceOperationIn = BundleEntryTransactionMethodEnum.DELETE; } String matchUrl = ResourceMetadataKeyEnum.LINK_SEARCH.get(nextResource); Set<Long> candidateMatches = null; if (StringUtils.isNotBlank(matchUrl)) { candidateMatches = processMatchUrl(matchUrl, nextResource.getClass()); } ResourceTable entity; if (nextResouceOperationIn == BundleEntryTransactionMethodEnum.POST) { entity = null; } else if (nextResouceOperationIn == BundleEntryTransactionMethodEnum.PUT || nextResouceOperationIn == BundleEntryTransactionMethodEnum.DELETE) { if (candidateMatches == null || candidateMatches.size() == 0) { if (nextId == null || StringUtils.isBlank(nextId.getIdPart())) { throw new InvalidRequestException( getContext() .getLocalizer() .getMessage( BaseHapiFhirSystemDao.class, "transactionOperationFailedNoId", nextResouceOperationIn.name())); } entity = tryToLoadEntity(nextId); if (entity == null) { if (nextResouceOperationIn == BundleEntryTransactionMethodEnum.PUT) { ourLog.debug( "Attempting to UPDATE resource with unknown ID '{}', will CREATE instead", nextId); } else if (candidateMatches == null) { throw new InvalidRequestException( getContext() .getLocalizer() .getMessage( BaseHapiFhirSystemDao.class, "transactionOperationFailedUnknownId", nextResouceOperationIn.name(), nextId)); } else { ourLog.debug("Resource with match URL [{}] already exists, will be NOOP", matchUrl); persistedResources.add(null); retVal.add(nextResource); continue; } } } else if (candidateMatches.size() == 1) { entity = loadFirstEntityFromCandidateMatches(candidateMatches); } else { throw new InvalidRequestException( getContext() .getLocalizer() .getMessage( BaseHapiFhirSystemDao.class, "transactionOperationWithMultipleMatchFailure", nextResouceOperationIn.name(), matchUrl, candidateMatches.size())); } } else if (nextId.isEmpty() || isPlaceholder(nextId)) { entity = null; } else { entity = tryToLoadEntity(nextId); } BundleEntryTransactionMethodEnum nextResouceOperationOut; if (entity == null) { nextResouceOperationOut = BundleEntryTransactionMethodEnum.POST; entity = toEntity(nextResource); entity.setUpdated(updateTime); entity.setPublished(updateTime); if (nextId.isEmpty() == false && "cid:".equals(nextId.getBaseUrl())) { ourLog.debug( "Resource in transaction has ID[{}], will replace with server assigned ID", nextId.getIdPart()); } else if (nextResouceOperationIn == BundleEntryTransactionMethodEnum.POST) { if (nextId.isEmpty() == false) { ourLog.debug( "Resource in transaction has ID[{}] but is marked for CREATE, will ignore ID", nextId.getIdPart()); } if (candidateMatches != null) { if (candidateMatches.size() == 1) { ourLog.debug("Resource with match URL [{}] already exists, will be NOOP", matchUrl); BaseHasResource existingEntity = loadFirstEntityFromCandidateMatches(candidateMatches); IResource existing = (IResource) toResource(existingEntity, false); persistedResources.add(null); retVal.add(existing); continue; } if (candidateMatches.size() > 1) { throw new InvalidRequestException( getContext() .getLocalizer() .getMessage( BaseHapiFhirSystemDao.class, "transactionOperationWithMultipleMatchFailure", BundleEntryTransactionMethodEnum.POST.name(), matchUrl, candidateMatches.size())); } } } else { createForcedIdIfNeeded(entity, nextId); } myEntityManager.persist(entity); if (entity.getForcedId() != null) { myEntityManager.persist(entity.getForcedId()); } creations++; ourLog.info( "Resource Type[{}] with ID[{}] does not exist, creating it", resourceName, nextId); } else { nextResouceOperationOut = nextResouceOperationIn; if (nextResouceOperationOut == null) { nextResouceOperationOut = BundleEntryTransactionMethodEnum.PUT; } updates++; ourLog.info("Resource Type[{}] with ID[{}] exists, updating it", resourceName, nextId); } persistedResources.add(entity); retVal.add(nextResource); ResourceMetadataKeyEnum.ENTRY_TRANSACTION_METHOD.put(nextResource, nextResouceOperationOut); } ourLog.info("Flushing transaction to database"); myEntityManager.flush(); for (int i = 0; i < persistedResources.size(); i++) { ResourceTable entity = persistedResources.get(i); String resourceName = toResourceName(theResources.get(i)); IdDt nextId = theResources.get(i).getId(); IdDt newId; if (entity == null) { newId = retVal.get(i + 1).getId().toUnqualifiedVersionless(); } else { newId = entity.getIdDt().toUnqualifiedVersionless(); } if (nextId == null || nextId.isEmpty()) { ourLog.info( "Transaction resource (with no preexisting ID) has been assigned new ID[{}]", nextId, newId); } else { if (nextId.toUnqualifiedVersionless().equals(newId)) { ourLog.info("Transaction resource ID[{}] is being updated", newId); } else { if (isPlaceholder(nextId)) { // nextId = new IdDt(resourceName, nextId.getIdPart()); ourLog.info("Transaction resource ID[{}] has been assigned new ID[{}]", nextId, newId); idConversions.put(nextId, newId); idConversions.put(new IdDt(resourceName + "/" + nextId.getValue()), newId); } } } } for (IResource nextResource : theResources) { List<BaseResourceReferenceDt> allRefs = terser.getAllPopulatedChildElementsOfType(nextResource, BaseResourceReferenceDt.class); for (BaseResourceReferenceDt nextRef : allRefs) { IdDt nextId = nextRef.getReference(); if (idConversions.containsKey(nextId)) { IdDt newId = idConversions.get(nextId); ourLog.info(" * Replacing resource ref {} with {}", nextId, newId); nextRef.setReference(newId); } else { ourLog.debug(" * Reference [{}] does not exist in bundle", nextId); } } } ourLog.info("Re-flushing updated resource references and extracting search criteria"); for (int i = 0; i < theResources.size(); i++) { IResource resource = theResources.get(i); ResourceTable table = persistedResources.get(i); if (table == null) { continue; } InstantDt deletedInstantOrNull = ResourceMetadataKeyEnum.DELETED_AT.get(resource); Date deletedTimestampOrNull = deletedInstantOrNull != null ? deletedInstantOrNull.getValue() : null; if (deletedInstantOrNull == null && ResourceMetadataKeyEnum.ENTRY_TRANSACTION_METHOD.get(resource) == BundleEntryTransactionMethodEnum.DELETE) { deletedTimestampOrNull = updateTime; ResourceMetadataKeyEnum.DELETED_AT.put(resource, new InstantDt(deletedTimestampOrNull)); } updateEntity(resource, table, table.getId() != null, deletedTimestampOrNull, updateTime); } long delay = System.currentTimeMillis() - start; ourLog.info( "Transaction completed in {}ms with {} creations and {} updates", new Object[] {delay, creations, updates}); oo.addIssue() .setSeverity(IssueSeverityEnum.INFORMATION) .setDetails( "Transaction completed in " + delay + "ms with " + creations + " creations and " + updates + " updates"); return retVal; }
@Override public Object invokeClient( String theResponseMimeType, Reader theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders) throws IOException { IParser parser = createAppropriateParserForParsingResponse( theResponseMimeType, theResponseReader, theResponseStatusCode); switch (getReturnType()) { case BUNDLE: { Bundle bundle; if (myResourceType != null) { bundle = parser.parseBundle(myResourceType, theResponseReader); } else { bundle = parser.parseBundle(theResponseReader); } switch (getMethodReturnType()) { case BUNDLE: return bundle; case LIST_OF_RESOURCES: List<IResource> listOfResources; if (myResourceListCollectionType != null) { listOfResources = new ArrayList<IResource>(); for (IResource next : bundle.toListOfResources()) { if (!myResourceListCollectionType.isAssignableFrom(next.getClass())) { ourLog.debug( "Not returning resource of type {} because it is not a subclass or instance of {}", next.getClass(), myResourceListCollectionType); continue; } listOfResources.add(next); } } else { listOfResources = bundle.toListOfResources(); } return listOfResources; case RESOURCE: List<IResource> list = bundle.toListOfResources(); if (list.size() == 0) { return null; } else if (list.size() == 1) { return list.get(0); } else { throw new InvalidResponseException( theResponseStatusCode, "FHIR server call returned a bundle with multiple resources, but this method is only able to returns one."); } case BUNDLE_PROVIDER: throw new IllegalStateException( "Return type of " + IBundleProvider.class.getSimpleName() + " is not supported in clients"); } break; } case RESOURCE: { IResource resource; if (myResourceType != null) { resource = parser.parseResource(myResourceType, theResponseReader); } else { resource = parser.parseResource(theResponseReader); } MethodUtil.parseClientRequestResourceHeaders(null, theHeaders, resource); switch (getMethodReturnType()) { case BUNDLE: return Bundle.withSingleResource(resource); case LIST_OF_RESOURCES: return Collections.singletonList(resource); case RESOURCE: return resource; case BUNDLE_PROVIDER: throw new IllegalStateException( "Return type of " + IBundleProvider.class.getSimpleName() + " is not supported in clients"); } break; } } throw new IllegalStateException("Should not get here!"); }
private String getConditionalUrl(IResource resource, IdentifierDt identifier) { return resource.getResourceName() + "?identifier=".concat(identifier.getSystem()).concat("%7C").concat(identifier.getValue()); }
protected String getPreferredId(IResource theResource, String theId) { if (isNotBlank(theId)) { return theId; } return theResource.getId().getIdPart(); }