More work on loinc loader

This commit is contained in:
James Agnew 2018-04-15 17:19:34 -04:00
parent b3a9ea263f
commit 8bfd7913c8
10 changed files with 174 additions and 22 deletions

View File

@ -209,7 +209,7 @@ public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao<Bundle, MetaDt> {
for (int i = 0; i < theRequest.getEntry().size(); i++) {
if (i % 100 == 0) {
ourLog.info("Processed {} non-GET entries out of {}", i, theRequest.getEntry().size());
ourLog.debug("Processed {} non-GET entries out of {}", i, theRequest.getEntry().size());
}
Entry nextReqEntry = theRequest.getEntry().get(i);

View File

@ -318,7 +318,7 @@ public class FhirSystemDaoDstu3 extends BaseHapiFhirSystemDao<Bundle, Meta> {
for (int i = 0; i < theEntries.size(); i++) {
if (i % 100 == 0) {
ourLog.info("Processed {} non-GET entries out of {}", i, theEntries.size());
ourLog.debug("Processed {} non-GET entries out of {}", i, theEntries.size());
}
BundleEntryComponent nextReqEntry = theEntries.get(i);

View File

@ -333,7 +333,7 @@ public class FhirSystemDaoR4 extends BaseHapiFhirSystemDao<Bundle, Meta> {
for (int i = 0; i < theEntries.size(); i++) {
if (i % 100 == 0) {
ourLog.info("Processed {} non-GET entries out of {}", i, theEntries.size());
ourLog.debug("Processed {} non-GET entries out of {}", i, theEntries.size());
}
BundleEntryComponent nextReqEntry = theEntries.get(i);

View File

@ -168,6 +168,19 @@ public abstract class BaseSubscriptionInterceptor<S extends IBaseResource> exten
retVal.getEmailDetails().setSubjectTemplate(subjectTemplate);
}
if (retVal.getChannelType() == Subscription.SubscriptionChannelType.RESTHOOK) {
String stripVersionIds;
String deliverLatestVersion;
try {
stripVersionIds = subscription.getChannel().getExtensionString(JpaConstants.EXT_SUBSCRIPTION_RESTHOOK_STRIP_VERSION_IDS);
deliverLatestVersion = subscription.getChannel().getExtensionString(JpaConstants.EXT_SUBSCRIPTION_RESTHOOK_DELIVER_LATEST_VERSION);
} catch (FHIRException theE) {
throw new ConfigurationException("Failed to extract subscription extension(s): " + theE.getMessage(), theE);
}
retVal.getRestHookDetails().setStripVersionId(Boolean.parseBoolean(stripVersionIds));
retVal.getRestHookDetails().setDeliverLatestVersion(Boolean.parseBoolean(deliverLatestVersion));
}
} catch (FHIRException theE) {
throw new InternalErrorException(theE);
}
@ -201,6 +214,19 @@ public abstract class BaseSubscriptionInterceptor<S extends IBaseResource> exten
retVal.getEmailDetails().setSubjectTemplate(subjectTemplate);
}
if (retVal.getChannelType() == Subscription.SubscriptionChannelType.RESTHOOK) {
String stripVersionIds;
String deliverLatestVersion;
try {
stripVersionIds = subscription.getChannel().getExtensionString(JpaConstants.EXT_SUBSCRIPTION_RESTHOOK_STRIP_VERSION_IDS);
deliverLatestVersion = subscription.getChannel().getExtensionString(JpaConstants.EXT_SUBSCRIPTION_RESTHOOK_DELIVER_LATEST_VERSION);
} catch (FHIRException theE) {
throw new ConfigurationException("Failed to extract subscription extension(s): " + theE.getMessage(), theE);
}
retVal.getRestHookDetails().setStripVersionId(Boolean.parseBoolean(stripVersionIds));
retVal.getRestHookDetails().setDeliverLatestVersion(Boolean.parseBoolean(deliverLatestVersion));
}
List<org.hl7.fhir.r4.model.Extension> topicExts = subscription.getExtensionsByUrl("http://hl7.org/fhir/subscription/topics");
if (topicExts.size() > 0) {
IBaseReference ref = (IBaseReference) topicExts.get(0).getValueAsPrimitive();

View File

@ -67,6 +67,8 @@ public class CanonicalSubscription implements Serializable {
private CanonicalEventDefinition myTrigger;
@JsonProperty("emailDetails")
private EmailDetails myEmailDetails;
@JsonProperty("restHookDetails")
private RestHookDetails myRestHookDetails;
/**
* For now we're using the R4 TriggerDefinition, but this
@ -131,12 +133,10 @@ public class CanonicalSubscription implements Serializable {
return myHeaders;
}
public void setHeaders(List<? extends IPrimitiveType<String>> theHeader) {
public void setHeaders(String theHeaders) {
myHeaders = new ArrayList<>();
for (IPrimitiveType<String> next : theHeader) {
if (isNotBlank(next.getValueAsString())) {
myHeaders.add(next.getValueAsString());
}
if (isNotBlank(theHeaders)) {
myHeaders.add(theHeaders);
}
}
@ -160,6 +160,13 @@ public class CanonicalSubscription implements Serializable {
myPayloadString = thePayloadString;
}
public RestHookDetails getRestHookDetails() {
if (myRestHookDetails == null) {
myRestHookDetails = new RestHookDetails();
}
return myRestHookDetails;
}
public Subscription.SubscriptionStatus getStatus() {
return myStatus;
}
@ -191,10 +198,12 @@ public class CanonicalSubscription implements Serializable {
}
}
public void setHeaders(String theHeaders) {
public void setHeaders(List<? extends IPrimitiveType<String>> theHeader) {
myHeaders = new ArrayList<>();
if (isNotBlank(theHeaders)) {
myHeaders.add(theHeaders);
for (IPrimitiveType<String> next : theHeader) {
if (isNotBlank(next.getValueAsString())) {
myHeaders.add(next.getValueAsString());
}
}
}
@ -230,6 +239,32 @@ public class CanonicalSubscription implements Serializable {
}
}
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonAutoDetect(creatorVisibility = JsonAutoDetect.Visibility.NONE, fieldVisibility = JsonAutoDetect.Visibility.NONE, getterVisibility = JsonAutoDetect.Visibility.NONE, isGetterVisibility = JsonAutoDetect.Visibility.NONE, setterVisibility = JsonAutoDetect.Visibility.NONE)
public static class RestHookDetails {
@JsonProperty("stripVersionId")
private boolean myStripVersionId;
@JsonProperty("deliverLatestVersion")
private boolean myDeliverLatestVersion;
public boolean isDeliverLatestVersion() {
return myDeliverLatestVersion;
}
public void setDeliverLatestVersion(boolean theDeliverLatestVersion) {
myDeliverLatestVersion = theDeliverLatestVersion;
}
public boolean isStripVersionId() {
return myStripVersionId;
}
public void setStripVersionId(boolean theStripVersionId) {
myStripVersionId = theStripVersionId;
}
}
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonAutoDetect(creatorVisibility = JsonAutoDetect.Visibility.NONE, fieldVisibility = JsonAutoDetect.Visibility.NONE, getterVisibility = JsonAutoDetect.Visibility.NONE, isGetterVisibility = JsonAutoDetect.Visibility.NONE, setterVisibility = JsonAutoDetect.Visibility.NONE)
public static class CanonicalEventDefinition {

View File

@ -28,8 +28,10 @@ import ca.uhn.fhir.rest.api.RequestTypeEnum;
import ca.uhn.fhir.rest.client.api.*;
import ca.uhn.fhir.rest.client.interceptor.SimpleRequestHeaderInterceptor;
import ca.uhn.fhir.rest.gclient.IClientExecutable;
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.hl7.fhir.r4.model.Subscription;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -51,21 +53,26 @@ public class SubscriptionDeliveringRestHookSubscriber extends BaseSubscriptionDe
}
protected void deliverPayload(ResourceDeliveryMessage theMsg, CanonicalSubscription theSubscription, EncodingEnum thePayloadType, IGenericClient theClient) {
IBaseResource payloadResource = theMsg.getPayload(getContext());
IBaseResource payloadResource = getAndMassagePayload(theMsg, theSubscription);
if (payloadResource == null) return;
doDelivery(theMsg, theSubscription, thePayloadType, theClient, payloadResource);
}
protected void doDelivery(ResourceDeliveryMessage theMsg, CanonicalSubscription theSubscription, EncodingEnum thePayloadType, IGenericClient theClient, IBaseResource thePayloadResource) {
IClientExecutable<?, ?> operation;
switch (theMsg.getOperationType()) {
case CREATE:
if (payloadResource == null || payloadResource.isEmpty()) {
if (thePayloadResource == null || thePayloadResource.isEmpty()) {
if (thePayloadType != null ) {
operation = theClient.create().resource(payloadResource);
operation = theClient.create().resource(thePayloadResource);
} else {
sendNotification(theMsg);
return;
}
} else {
if (thePayloadType != null ) {
operation = theClient.update().resource(payloadResource);
operation = theClient.update().resource(thePayloadResource);
} else {
sendNotification(theMsg);
return;
@ -73,16 +80,16 @@ public class SubscriptionDeliveringRestHookSubscriber extends BaseSubscriptionDe
}
break;
case UPDATE:
if (payloadResource == null || payloadResource.isEmpty()) {
if (thePayloadResource == null || thePayloadResource.isEmpty()) {
if (thePayloadType != null ) {
operation = theClient.create().resource(payloadResource);
operation = theClient.create().resource(thePayloadResource);
} else {
sendNotification(theMsg);
return;
}
} else {
if (thePayloadType != null ) {
operation = theClient.update().resource(payloadResource);
operation = theClient.update().resource(thePayloadResource);
} else {
sendNotification(theMsg);
return;
@ -101,7 +108,7 @@ public class SubscriptionDeliveringRestHookSubscriber extends BaseSubscriptionDe
operation.encoded(thePayloadType);
}
ourLog.info("Delivering {} rest-hook payload {} for {}", theMsg.getOperationType(), payloadResource.getIdElement().toUnqualified().getValue(), theSubscription.getIdElement(getContext()).toUnqualifiedVersionless().getValue());
ourLog.info("Delivering {} rest-hook payload {} for {}", theMsg.getOperationType(), thePayloadResource.getIdElement().toUnqualified().getValue(), theSubscription.getIdElement(getContext()).toUnqualifiedVersionless().getValue());
try {
operation.execute();
@ -112,6 +119,27 @@ public class SubscriptionDeliveringRestHookSubscriber extends BaseSubscriptionDe
}
}
protected IBaseResource getAndMassagePayload(ResourceDeliveryMessage theMsg, CanonicalSubscription theSubscription) {
IBaseResource payloadResource = theMsg.getPayload(getContext());
if (theSubscription.getRestHookDetails().isDeliverLatestVersion()) {
IFhirResourceDao dao = getSubscriptionDao().getDao(payloadResource.getClass());
try {
payloadResource = dao.read(payloadResource.getIdElement().toVersionless());
} catch (ResourceGoneException e) {
ourLog.warn("Resource {} is deleted, not going to deliver for subscription {}", payloadResource.getIdElement(), theSubscription.getIdElement(getContext()));
return null;
}
}
IIdType resourceId = payloadResource.getIdElement();
if (theSubscription.getRestHookDetails().isStripVersionId()) {
resourceId = resourceId.toVersionless();
payloadResource.setId(resourceId);
}
return payloadResource;
}
@Override
public void handleMessage(ResourceDeliveryMessage theMessage) throws MessagingException {
CanonicalSubscription subscription = theMessage.getSubscription();

View File

@ -9,9 +9,9 @@ package ca.uhn.fhir.jpa.term;
* 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.

View File

@ -40,4 +40,33 @@ public class JpaConstants {
*/
public static final String EXT_SUBSCRIPTION_SUBJECT_TEMPLATE = "http://hapifhir.io/fhir/StructureDefinition/subscription-email-subject-template";
/**
* This extension URL indicates whether a REST HOOK delivery should
* include the version ID when delivering.
* <p>
* This extension should be of type <code>boolean</code> and should be
* placed on the <code>Subscription.channel</code> element.
* </p>
*/
public static final String EXT_SUBSCRIPTION_RESTHOOK_STRIP_VERSION_IDS = "http://hapifhir.io/fhir/StructureDefinition/subscription-resthook-strip-version-ids";
/**
* This extension URL indicates whether a REST HOOK delivery should
* reload the resource and deliver the latest version always. This
* could be useful for example if a resource which triggers a
* subscription gets updated many times in short succession and there
* is no value in delivering the older versions.
* <p>
* Note that if the resource is now deleted, this may cause
* the delivery to be cancelled altogether.
* </p>
*
* <p>
* This extension should be of type <code>boolean</code> and should be
* placed on the <code>Subscription.channel</code> element.
* </p>
*/
public static final String EXT_SUBSCRIPTION_RESTHOOK_DELIVER_LATEST_VERSION = "http://hapifhir.io/fhir/StructureDefinition/subscription-resthook-deliver-latest-version";
}

View File

@ -2,8 +2,10 @@ package ca.uhn.fhir.jpa.subscription.r4;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.jpa.dao.DaoConfig;
import ca.uhn.fhir.jpa.provider.JpaConformanceProviderDstu2;
import ca.uhn.fhir.jpa.provider.r4.BaseResourceProviderR4Test;
import ca.uhn.fhir.jpa.subscription.RestHookTestDstu2Test;
import ca.uhn.fhir.jpa.util.JpaConstants;
import ca.uhn.fhir.rest.annotation.Create;
import ca.uhn.fhir.rest.annotation.ResourceParam;
import ca.uhn.fhir.rest.annotation.Update;
@ -172,7 +174,38 @@ public class RestHookTestR4Test extends BaseResourceProviderR4Test {
}
@Test
public void testRestHookSubscriptionApplicationJsonDisableVersionIdInDelivery() throws Exception {
String payload = "application/json";
String code = "1000000050";
String criteria1 = "Observation?code=SNOMED-CT|" + code + "&_format=xml";
Subscription subscription1 = createSubscription(criteria1, payload, ourListenerServerBase);
subscription1
.getChannel()
.addExtension(JpaConstants.EXT_SUBSCRIPTION_RESTHOOK_STRIP_VERSION_IDS, new BooleanType("true"));
subscription1
.getChannel()
.addExtension(JpaConstants.EXT_SUBSCRIPTION_RESTHOOK_DELIVER_LATEST_VERSION, new BooleanType("true"));
myClient.update().resource(subscription1).execute();
waitForQueueToDrain();
Observation observation1 = sendObservation(code, "SNOMED-CT");
// Should see 1 subscription notification
waitForQueueToDrain();
waitForSize(0, ourCreatedObservations);
waitForSize(1, ourUpdatedObservations);
assertEquals(Constants.CT_FHIR_JSON_NEW, ourContentTypes.get(0));
assertEquals(observation1.getIdElement().getIdPart(), ourUpdatedObservations.get(0).getIdElement().getIdPart());
assertEquals(null, ourUpdatedObservations.get(0).getIdElement().getVersionIdPart());
}
@Test
public void testRestHookSubscriptionApplicationJson() throws Exception {
String payload = "application/json";
@ -191,6 +224,8 @@ public class RestHookTestR4Test extends BaseResourceProviderR4Test {
waitForSize(1, ourUpdatedObservations);
assertEquals(Constants.CT_FHIR_JSON_NEW, ourContentTypes.get(0));
assertEquals("1", ourUpdatedObservations.get(0).getIdElement().getVersionIdPart());
Subscription subscriptionTemp = myClient.read(Subscription.class, subscription2.getId());
Assert.assertNotNull(subscriptionTemp);

View File

@ -108,7 +108,6 @@ where res_id in (
drop table hfj_history_tag cascade constraints;
drop table hfj_forced_id cascade constraints;
drop table HFJ_SUBSCRIPTION_STATS cascade constraints;
drop table hfj_res_link cascade constraints;
drop table hfj_spidx_coords cascade constraints;
drop table hfj_spidx_date cascade constraints;