Address review changes
This commit is contained in:
parent
47786660d5
commit
edc30568f2
|
@ -68,13 +68,13 @@ import com.google.common.collect.Lists;
|
|||
import org.hl7.fhir.instance.model.api.IAnyResource;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.persistence.criteria.From;
|
||||
import javax.persistence.criteria.Join;
|
||||
import javax.persistence.criteria.JoinType;
|
||||
|
@ -988,14 +988,14 @@ class PredicateBuilderReference extends BasePredicateBuilder {
|
|||
return retVal;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Nonnull
|
||||
private InvalidRequestException newInvalidTargetTypeForChainException(String theResourceName, String theParamName, String theTypeValue) {
|
||||
String searchParamName = theResourceName + ":" + theParamName;
|
||||
String msg = myContext.getLocalizer().getMessage(PredicateBuilderReference.class, "invalidTargetTypeForChain", theTypeValue, searchParamName);
|
||||
return new InvalidRequestException(msg);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Nonnull
|
||||
private InvalidRequestException newInvalidResourceTypeException(String theResourceType) {
|
||||
String msg = myContext.getLocalizer().getMessageSanitized(PredicateBuilderReference.class, "invalidResourceType", theResourceType);
|
||||
throw new InvalidRequestException(msg);
|
||||
|
|
|
@ -22,6 +22,7 @@ package ca.uhn.fhir.jpa.provider;
|
|||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.jpa.model.util.JpaConstants;
|
||||
import ca.uhn.fhir.jpa.model.util.ProviderConstants;
|
||||
import ca.uhn.fhir.jpa.subscription.triggering.ISubscriptionTriggeringSvc;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.ResourceTypeEnum;
|
||||
import ca.uhn.fhir.rest.annotation.IdParam;
|
||||
|
@ -45,8 +46,8 @@ public class SubscriptionTriggeringProvider implements IResourceProvider {
|
|||
|
||||
@Operation(name = JpaConstants.OPERATION_TRIGGER_SUBSCRIPTION)
|
||||
public IBaseParameters triggerSubscription(
|
||||
@OperationParam(name = JpaConstants.SUBSCRIPTION_TRIGGERING_PARAM_RESOURCE_ID, min = 0, max = OperationParam.MAX_UNLIMITED, typeName = "uri") List<IPrimitiveType<String>> theResourceIds,
|
||||
@OperationParam(name = JpaConstants.SUBSCRIPTION_TRIGGERING_PARAM_SEARCH_URL, min = 0, max = OperationParam.MAX_UNLIMITED, typeName = "string") List<IPrimitiveType<String>> theSearchUrls
|
||||
@OperationParam(name = ProviderConstants.SUBSCRIPTION_TRIGGERING_PARAM_RESOURCE_ID, min = 0, max = OperationParam.MAX_UNLIMITED, typeName = "uri") List<IPrimitiveType<String>> theResourceIds,
|
||||
@OperationParam(name = ProviderConstants.SUBSCRIPTION_TRIGGERING_PARAM_SEARCH_URL, min = 0, max = OperationParam.MAX_UNLIMITED, typeName = "string") List<IPrimitiveType<String>> theSearchUrls
|
||||
) {
|
||||
return mySubscriptionTriggeringSvc.triggerSubscription(theResourceIds, theSearchUrls, null);
|
||||
}
|
||||
|
@ -54,8 +55,8 @@ public class SubscriptionTriggeringProvider implements IResourceProvider {
|
|||
@Operation(name = JpaConstants.OPERATION_TRIGGER_SUBSCRIPTION)
|
||||
public IBaseParameters triggerSubscription(
|
||||
@IdParam IIdType theSubscriptionId,
|
||||
@OperationParam(name = JpaConstants.SUBSCRIPTION_TRIGGERING_PARAM_RESOURCE_ID, min = 0, max = OperationParam.MAX_UNLIMITED, typeName = "uri") List<IPrimitiveType<String>> theResourceIds,
|
||||
@OperationParam(name = JpaConstants.SUBSCRIPTION_TRIGGERING_PARAM_SEARCH_URL, min = 0, max = OperationParam.MAX_UNLIMITED, typeName = "string") List<IPrimitiveType<String>> theSearchUrls
|
||||
@OperationParam(name = ProviderConstants.SUBSCRIPTION_TRIGGERING_PARAM_RESOURCE_ID, min = 0, max = OperationParam.MAX_UNLIMITED, typeName = "uri") List<IPrimitiveType<String>> theResourceIds,
|
||||
@OperationParam(name = ProviderConstants.SUBSCRIPTION_TRIGGERING_PARAM_SEARCH_URL, min = 0, max = OperationParam.MAX_UNLIMITED, typeName = "string") List<IPrimitiveType<String>> theSearchUrls
|
||||
) {
|
||||
return mySubscriptionTriggeringSvc.triggerSubscription(theResourceIds, theSearchUrls, theSubscriptionId);
|
||||
}
|
||||
|
|
|
@ -27,7 +27,6 @@ import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
|||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.collect.Sets;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.quartz.*;
|
||||
import org.quartz.impl.JobDetailImpl;
|
||||
import org.quartz.impl.StdSchedulerFactory;
|
||||
|
@ -35,6 +34,7 @@ import org.quartz.impl.matchers.GroupMatcher;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
@ -85,7 +85,7 @@ public abstract class BaseHapiScheduler implements IHapiScheduler {
|
|||
addProperty("org.quartz.threadPool.threadNamePrefix", getThreadPrefix());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Nonnull
|
||||
private String getThreadPrefix() {
|
||||
return myThreadNamePrefix + "-" + myInstanceName;
|
||||
}
|
||||
|
|
|
@ -47,7 +47,6 @@ import ca.uhn.fhir.rest.api.server.SimplePreResourceShowDetails;
|
|||
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
@ -256,7 +255,7 @@ public class PersistedJpaBundleProvider implements IBundleProvider {
|
|||
|
||||
template.execute(new TransactionCallbackWithoutResult() {
|
||||
@Override
|
||||
protected void doInTransactionWithoutResult(@NotNull TransactionStatus theStatus) {
|
||||
protected void doInTransactionWithoutResult(@Nonnull TransactionStatus theStatus) {
|
||||
boolean entityLoaded = ensureSearchEntityLoaded();
|
||||
assert entityLoaded;
|
||||
}
|
||||
|
|
|
@ -46,8 +46,6 @@ import java.util.List;
|
|||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Scope("prototype")
|
||||
@Component
|
||||
public class PersistedJpaSearchFirstPageBundleProvider extends PersistedJpaBundleProvider {
|
||||
private static final Logger ourLog = LoggerFactory.getLogger(PersistedJpaSearchFirstPageBundleProvider.class);
|
||||
private SearchTask mySearchTask;
|
||||
|
|
|
@ -26,7 +26,6 @@ import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
|||
import ca.uhn.fhir.rest.server.exceptions.ResourceGoneException;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
|
@ -42,6 +41,7 @@ import org.springframework.data.domain.Pageable;
|
|||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.TransactionStatus;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.persistence.EntityManager;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
@ -493,7 +493,7 @@ public class SearchCoordinatorSvcImplTest {
|
|||
myExpectedNumberOfSearchBuildersCreated = 3;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Nonnull
|
||||
private PersistedJpaBundleProvider newPersistedJpaBundleProvider(String theUuid) {
|
||||
PersistedJpaBundleProvider provider;
|
||||
provider = new PersistedJpaBundleProvider(null, theUuid);
|
||||
|
|
|
@ -4,6 +4,7 @@ import ca.uhn.fhir.context.FhirContext;
|
|||
import ca.uhn.fhir.jpa.api.config.DaoConfig;
|
||||
import ca.uhn.fhir.jpa.model.sched.ISchedulerService;
|
||||
import ca.uhn.fhir.jpa.model.util.JpaConstants;
|
||||
import ca.uhn.fhir.jpa.model.util.ProviderConstants;
|
||||
import ca.uhn.fhir.jpa.provider.dstu3.BaseResourceProviderDstu3Test;
|
||||
import ca.uhn.fhir.jpa.subscription.SubscriptionTestUtil;
|
||||
import ca.uhn.fhir.jpa.subscription.triggering.SubscriptionTriggeringSvcImpl;
|
||||
|
@ -180,7 +181,7 @@ public class SubscriptionTriggeringDstu3Test extends BaseResourceProviderDstu3Te
|
|||
.operation()
|
||||
.onInstance(subscriptionId)
|
||||
.named(JpaConstants.OPERATION_TRIGGER_SUBSCRIPTION)
|
||||
.withParameter(Parameters.class, JpaConstants.SUBSCRIPTION_TRIGGERING_PARAM_RESOURCE_ID, new UriType(obsId.toUnqualifiedVersionless().getValue()))
|
||||
.withParameter(Parameters.class, ProviderConstants.SUBSCRIPTION_TRIGGERING_PARAM_RESOURCE_ID, new UriType(obsId.toUnqualifiedVersionless().getValue()))
|
||||
.execute();
|
||||
|
||||
String responseValue = response.getParameter().get(0).getValue().primitiveValue();
|
||||
|
@ -229,8 +230,8 @@ public class SubscriptionTriggeringDstu3Test extends BaseResourceProviderDstu3Te
|
|||
.operation()
|
||||
.onInstance(sub1id)
|
||||
.named(JpaConstants.OPERATION_TRIGGER_SUBSCRIPTION)
|
||||
.withParameter(Parameters.class, JpaConstants.SUBSCRIPTION_TRIGGERING_PARAM_SEARCH_URL, new StringType("Observation?"))
|
||||
.andParameter(JpaConstants.SUBSCRIPTION_TRIGGERING_PARAM_RESOURCE_ID, new UriType("Observation/O2"))
|
||||
.withParameter(Parameters.class, ProviderConstants.SUBSCRIPTION_TRIGGERING_PARAM_SEARCH_URL, new StringType("Observation?"))
|
||||
.andParameter(ProviderConstants.SUBSCRIPTION_TRIGGERING_PARAM_RESOURCE_ID, new UriType("Observation/O2"))
|
||||
.execute();
|
||||
String responseValue = response.getParameter().get(0).getValue().primitiveValue();
|
||||
assertThat(responseValue, containsString("Subscription triggering job submitted as JOB ID"));
|
||||
|
@ -239,7 +240,7 @@ public class SubscriptionTriggeringDstu3Test extends BaseResourceProviderDstu3Te
|
|||
.operation()
|
||||
.onInstance(sub2id)
|
||||
.named(JpaConstants.OPERATION_TRIGGER_SUBSCRIPTION)
|
||||
.withParameter(Parameters.class, JpaConstants.SUBSCRIPTION_TRIGGERING_PARAM_SEARCH_URL, new StringType("Patient?"))
|
||||
.withParameter(Parameters.class, ProviderConstants.SUBSCRIPTION_TRIGGERING_PARAM_SEARCH_URL, new StringType("Patient?"))
|
||||
.execute();
|
||||
responseValue = response.getParameter().get(0).getValue().primitiveValue();
|
||||
assertThat(responseValue, containsString("Subscription triggering job submitted as JOB ID"));
|
||||
|
@ -278,9 +279,9 @@ public class SubscriptionTriggeringDstu3Test extends BaseResourceProviderDstu3Te
|
|||
.operation()
|
||||
.onInstance(sub2id)
|
||||
.named(JpaConstants.OPERATION_TRIGGER_SUBSCRIPTION)
|
||||
.withParameter(Parameters.class, JpaConstants.SUBSCRIPTION_TRIGGERING_PARAM_SEARCH_URL, new StringType("Patient?_id=P0"))
|
||||
.andParameter(JpaConstants.SUBSCRIPTION_TRIGGERING_PARAM_SEARCH_URL, new StringType("Patient?_id=P1"))
|
||||
.andParameter(JpaConstants.SUBSCRIPTION_TRIGGERING_PARAM_SEARCH_URL, new StringType("Patient?_id=P2"))
|
||||
.withParameter(Parameters.class, ProviderConstants.SUBSCRIPTION_TRIGGERING_PARAM_SEARCH_URL, new StringType("Patient?_id=P0"))
|
||||
.andParameter(ProviderConstants.SUBSCRIPTION_TRIGGERING_PARAM_SEARCH_URL, new StringType("Patient?_id=P1"))
|
||||
.andParameter(ProviderConstants.SUBSCRIPTION_TRIGGERING_PARAM_SEARCH_URL, new StringType("Patient?_id=P2"))
|
||||
.execute();
|
||||
String responseValue = response.getParameter().get(0).getValue().primitiveValue();
|
||||
assertThat(responseValue, containsString("Subscription triggering job submitted as JOB ID"));
|
||||
|
@ -322,7 +323,7 @@ public class SubscriptionTriggeringDstu3Test extends BaseResourceProviderDstu3Te
|
|||
.operation()
|
||||
.onInstance(sub2id)
|
||||
.named(JpaConstants.OPERATION_TRIGGER_SUBSCRIPTION)
|
||||
.withParameter(Parameters.class, JpaConstants.SUBSCRIPTION_TRIGGERING_PARAM_SEARCH_URL, new StringType("Patient?_id=P0,P1,P2"))
|
||||
.withParameter(Parameters.class, ProviderConstants.SUBSCRIPTION_TRIGGERING_PARAM_SEARCH_URL, new StringType("Patient?_id=P0,P1,P2"))
|
||||
.execute();
|
||||
String responseValue = response.getParameter().get(0).getValue().primitiveValue();
|
||||
assertThat(responseValue, containsString("Subscription triggering job submitted as JOB ID"));
|
||||
|
@ -366,7 +367,7 @@ public class SubscriptionTriggeringDstu3Test extends BaseResourceProviderDstu3Te
|
|||
.operation()
|
||||
.onInstance(sub1id)
|
||||
.named(JpaConstants.OPERATION_TRIGGER_SUBSCRIPTION)
|
||||
.withParameter(Parameters.class, JpaConstants.SUBSCRIPTION_TRIGGERING_PARAM_SEARCH_URL, new StringType("Observation?_count=10"))
|
||||
.withParameter(Parameters.class, ProviderConstants.SUBSCRIPTION_TRIGGERING_PARAM_SEARCH_URL, new StringType("Observation?_count=10"))
|
||||
.execute();
|
||||
String responseValue = response.getParameter().get(0).getValue().primitiveValue();
|
||||
assertThat(responseValue, containsString("Subscription triggering job submitted as JOB ID"));
|
||||
|
@ -375,7 +376,7 @@ public class SubscriptionTriggeringDstu3Test extends BaseResourceProviderDstu3Te
|
|||
.operation()
|
||||
.onInstance(sub2id)
|
||||
.named(JpaConstants.OPERATION_TRIGGER_SUBSCRIPTION)
|
||||
.withParameter(Parameters.class, JpaConstants.SUBSCRIPTION_TRIGGERING_PARAM_SEARCH_URL, new StringType("Patient?_count=16"))
|
||||
.withParameter(Parameters.class, ProviderConstants.SUBSCRIPTION_TRIGGERING_PARAM_SEARCH_URL, new StringType("Patient?_count=16"))
|
||||
.execute();
|
||||
responseValue = response.getParameter().get(0).getValue().primitiveValue();
|
||||
assertThat(responseValue, containsString("Subscription triggering job submitted as JOB ID"));
|
||||
|
@ -398,7 +399,7 @@ public class SubscriptionTriggeringDstu3Test extends BaseResourceProviderDstu3Te
|
|||
.operation()
|
||||
.onType(Subscription.class)
|
||||
.named(JpaConstants.OPERATION_TRIGGER_SUBSCRIPTION)
|
||||
.withParameter(Parameters.class, JpaConstants.SUBSCRIPTION_TRIGGERING_PARAM_SEARCH_URL, new StringType("Observation"))
|
||||
.withParameter(Parameters.class, ProviderConstants.SUBSCRIPTION_TRIGGERING_PARAM_SEARCH_URL, new StringType("Observation"))
|
||||
.execute();
|
||||
fail();
|
||||
} catch (InvalidRequestException e) {
|
||||
|
@ -432,7 +433,7 @@ public class SubscriptionTriggeringDstu3Test extends BaseResourceProviderDstu3Te
|
|||
.operation()
|
||||
.onType(Subscription.class)
|
||||
.named(JpaConstants.OPERATION_TRIGGER_SUBSCRIPTION)
|
||||
.withParameter(Parameters.class, JpaConstants.SUBSCRIPTION_TRIGGERING_PARAM_SEARCH_URL, new StringType("Observation?"))
|
||||
.withParameter(Parameters.class, ProviderConstants.SUBSCRIPTION_TRIGGERING_PARAM_SEARCH_URL, new StringType("Observation?"))
|
||||
.execute();
|
||||
String responseValue = response.getParameter().get(0).getValue().primitiveValue();
|
||||
assertThat(responseValue, containsString("Subscription triggering job submitted as JOB ID"));
|
||||
|
@ -469,7 +470,7 @@ public class SubscriptionTriggeringDstu3Test extends BaseResourceProviderDstu3Te
|
|||
.operation()
|
||||
.onInstance(subscriptionId)
|
||||
.named(JpaConstants.OPERATION_TRIGGER_SUBSCRIPTION)
|
||||
.withParameter(Parameters.class, JpaConstants.SUBSCRIPTION_TRIGGERING_PARAM_RESOURCE_ID, new UriType(obsId.toUnqualifiedVersionless().getValue()))
|
||||
.withParameter(Parameters.class, ProviderConstants.SUBSCRIPTION_TRIGGERING_PARAM_RESOURCE_ID, new UriType(obsId.toUnqualifiedVersionless().getValue()))
|
||||
.execute();
|
||||
|
||||
String responseValue = response.getParameter().get(0).getValue().primitiveValue();
|
||||
|
|
|
@ -2,10 +2,10 @@ package ca.uhn.fhir.jpa.migrate;
|
|||
|
||||
import ca.uhn.fhir.jpa.migrate.taskdef.BaseTask;
|
||||
import ca.uhn.fhir.jpa.migrate.taskdef.DropIndexTask;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
@ -108,8 +108,8 @@ public class MigrationTaskSkipperTest {
|
|||
assertThat(taskVersions, equalTo(expectedVersions));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Stream<String> integersToVersions(Integer[] theVersions) {
|
||||
@Nonnull
|
||||
private Stream<String> integersToVersions(Integer[] theVersions) {
|
||||
return Stream.of(theVersions).map(s -> VERSION_PREFIX + s);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,9 +24,6 @@ import ca.uhn.fhir.rest.api.Constants;
|
|||
|
||||
public class JpaConstants {
|
||||
|
||||
public static final String SUBSCRIPTION_TRIGGERING_PARAM_RESOURCE_ID = "resourceId";
|
||||
public static final String SUBSCRIPTION_TRIGGERING_PARAM_SEARCH_URL = "searchUrl";
|
||||
|
||||
/**
|
||||
* Non-instantiable
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
package ca.uhn.fhir.jpa.model.util;
|
||||
|
||||
public class ProviderConstants {
|
||||
public static final String SUBSCRIPTION_TRIGGERING_PARAM_RESOURCE_ID = "resourceId";
|
||||
public static final String SUBSCRIPTION_TRIGGERING_PARAM_SEARCH_URL = "searchUrl";
|
||||
}
|
|
@ -38,7 +38,7 @@ public interface IChannelFactory {
|
|||
* @param theMessageType The object type that will be placed on this queue. Objects will be Jackson-annotated structures.
|
||||
* @param theConfig Contains the configuration for subscribers. Note that this parameter is provided for
|
||||
* both {@link #getOrCreateReceiver} and
|
||||
* {@link #getOrCreateSender(String, Class, ChannelConsumerOptions)}
|
||||
* {@link #getOrCreateProducer(String, Class, ChannelConsumerOptions)}
|
||||
* even though this object is used to configure the sender only. We do this because the factory
|
||||
* may want to create a single object to be used for both the sender and receiver, so this allows
|
||||
* the config details to be known regardless of which method is returned first.
|
||||
|
@ -57,11 +57,11 @@ public interface IChannelFactory {
|
|||
* @param theMessageType The object type that will be placed on this queue. Objects will be Jackson-annotated structures.
|
||||
* @param theConfig Contains the configuration for subscribers. Note that this parameter is provided for
|
||||
* both {@link #getOrCreateReceiver} and
|
||||
* {@link #getOrCreateSender(String, Class, ChannelConsumerOptions)}
|
||||
* {@link #getOrCreateProducer(String, Class, ChannelConsumerOptions)}
|
||||
* even though this object is used to configure the sender only. We do this because the factory
|
||||
* may want to create a single object to be used for both the sender and receiver, so this allows
|
||||
* the config details to be known regardless of which method is returned first.
|
||||
*/
|
||||
IChannelProducer getOrCreateSender(String theChannelName, Class<?> theMessageType, ChannelConsumerOptions theConfig);
|
||||
IChannelProducer getOrCreateProducer(String theChannelName, Class<?> theMessageType, ChannelConsumerOptions theConfig);
|
||||
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ import org.apache.commons.lang3.concurrent.BasicThreadFactory;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.annotation.PreDestroy;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
@ -42,8 +43,8 @@ import java.util.concurrent.TimeUnit;
|
|||
|
||||
public class LinkedBlockingChannelFactory implements IChannelFactory {
|
||||
|
||||
private Map<String, LinkedBlockingChannel> myChannels = Collections.synchronizedMap(new HashMap<>());
|
||||
private static final Logger ourLog = LoggerFactory.getLogger(LinkedBlockingChannelFactory.class);
|
||||
private Map<String, LinkedBlockingChannel> myChannels = Collections.synchronizedMap(new HashMap<>());
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
|
@ -58,7 +59,7 @@ public class LinkedBlockingChannelFactory implements IChannelFactory {
|
|||
}
|
||||
|
||||
@Override
|
||||
public IChannelProducer getOrCreateSender(String theChannelName, Class<?> theMessageType, ChannelConsumerOptions theConfig) {
|
||||
public IChannelProducer getOrCreateProducer(String theChannelName, Class<?> theMessageType, ChannelConsumerOptions theConfig) {
|
||||
return getOrCreateChannel(theChannelName, theConfig.getConcurrentConsumers());
|
||||
}
|
||||
|
||||
|
@ -99,4 +100,10 @@ public class LinkedBlockingChannelFactory implements IChannelFactory {
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
@PreDestroy
|
||||
public void stop() {
|
||||
myChannels.clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ public class SubscriptionChannelFactory {
|
|||
|
||||
public IChannelProducer newDeliverySendingChannel(String theChannelName, ChannelConsumerOptions theOptions) {
|
||||
ChannelConsumerOptions config = newConfigForDeliveryChannel(theOptions);
|
||||
return myQueueChannelFactory.getOrCreateSender(theChannelName, ResourceDeliveryJsonMessage.class, config);
|
||||
return myQueueChannelFactory.getOrCreateProducer(theChannelName, ResourceDeliveryJsonMessage.class, config);
|
||||
}
|
||||
|
||||
public IChannelReceiver newDeliveryReceivingChannel(String theChannelName, ChannelConsumerOptions theOptions) {
|
||||
|
@ -60,7 +60,7 @@ public class SubscriptionChannelFactory {
|
|||
|
||||
public IChannelProducer newMatchingSendingChannel(String theChannelName, ChannelConsumerOptions theOptions) {
|
||||
ChannelConsumerOptions config = newConfigForMatchingChannel(theOptions);
|
||||
return myQueueChannelFactory.getOrCreateSender(theChannelName, ResourceModifiedJsonMessage.class, config);
|
||||
return myQueueChannelFactory.getOrCreateProducer(theChannelName, ResourceModifiedJsonMessage.class, config);
|
||||
}
|
||||
|
||||
public IChannelReceiver newMatchingReceivingChannel(String theChannelName, ChannelConsumerOptions theOptions) {
|
||||
|
|
|
@ -36,19 +36,19 @@ public class SubscriptionDeliveryHandlerFactory {
|
|||
@Autowired
|
||||
private ApplicationContext myApplicationContext;
|
||||
|
||||
protected SubscriptionDeliveringEmailSubscriber getSubscriptionDeliveringEmailSubscriber(IEmailSender theEmailSender) {
|
||||
protected SubscriptionDeliveringEmailSubscriber newSubscriptionDeliveringEmailSubscriber(IEmailSender theEmailSender) {
|
||||
return myApplicationContext.getBean(SubscriptionDeliveringEmailSubscriber.class, theEmailSender);
|
||||
}
|
||||
|
||||
protected SubscriptionDeliveringRestHookSubscriber getSubscriptionDeliveringRestHookSubscriber() {
|
||||
protected SubscriptionDeliveringRestHookSubscriber newSubscriptionDeliveringRestHookSubscriber() {
|
||||
return myApplicationContext.getBean(SubscriptionDeliveringRestHookSubscriber.class);
|
||||
}
|
||||
|
||||
public Optional<MessageHandler> createDeliveryHandler(CanonicalSubscriptionChannelType theChannelType) {
|
||||
if (theChannelType == CanonicalSubscriptionChannelType.EMAIL) {
|
||||
return Optional.of(getSubscriptionDeliveringEmailSubscriber(myEmailSender));
|
||||
return Optional.of(newSubscriptionDeliveringEmailSubscriber(myEmailSender));
|
||||
} else if (theChannelType == CanonicalSubscriptionChannelType.RESTHOOK) {
|
||||
return Optional.of(getSubscriptionDeliveringRestHookSubscriber());
|
||||
return Optional.of(newSubscriptionDeliveringRestHookSubscriber());
|
||||
} else {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
|
|
@ -24,8 +24,6 @@ import ca.uhn.fhir.jpa.subscription.channel.subscription.SubscriptionChannelRegi
|
|||
import ca.uhn.fhir.jpa.subscription.channel.subscription.SubscriptionDeliveryChannelNamer;
|
||||
import ca.uhn.fhir.jpa.subscription.channel.subscription.SubscriptionDeliveryHandlerFactory;
|
||||
import ca.uhn.fhir.jpa.subscription.model.config.SubscriptionModelConfig;
|
||||
import ca.uhn.fhir.jpa.subscription.match.deliver.DaoResourceRetriever;
|
||||
import ca.uhn.fhir.jpa.subscription.match.deliver.IResourceRetriever;
|
||||
import ca.uhn.fhir.jpa.subscription.match.deliver.email.IEmailSender;
|
||||
import ca.uhn.fhir.jpa.subscription.match.deliver.email.SubscriptionDeliveringEmailSubscriber;
|
||||
import ca.uhn.fhir.jpa.subscription.match.deliver.resthook.SubscriptionDeliveringRestHookSubscriber;
|
||||
|
@ -88,11 +86,6 @@ public class SubscriptionProcessorConfig {
|
|||
return new DaoSubscriptionProvider();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public IResourceRetriever resourceRetriever() {
|
||||
return new DaoResourceRetriever();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SubscriptionLoader subscriptionLoader() {
|
||||
return new SubscriptionLoader();
|
||||
|
|
|
@ -1,64 +0,0 @@
|
|||
package ca.uhn.fhir.jpa.subscription.match.deliver;
|
||||
|
||||
/*-
|
||||
* #%L
|
||||
* HAPI FHIR Subscription Server
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2020 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.context.RuntimeResourceDefinition;
|
||||
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
|
||||
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
|
||||
import ca.uhn.fhir.jpa.subscription.match.registry.ActiveSubscription;
|
||||
import ca.uhn.fhir.rest.server.exceptions.ResourceGoneException;
|
||||
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 org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
public class DaoResourceRetriever implements IResourceRetriever {
|
||||
private static final Logger ourLog = LoggerFactory.getLogger(ActiveSubscription.class);
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public DaoResourceRetriever() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public DaoResourceRetriever(FhirContext theFhirContext, DaoRegistry theDaoRegistry) {
|
||||
myFhirContext = theFhirContext;
|
||||
myDaoRegistry = theDaoRegistry;
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private FhirContext myFhirContext;
|
||||
@Autowired
|
||||
private DaoRegistry myDaoRegistry;
|
||||
|
||||
@Override
|
||||
public IBaseResource getResource(IIdType payloadId) throws ResourceGoneException {
|
||||
RuntimeResourceDefinition resourceDef = myFhirContext.getResourceDefinition(payloadId.getResourceType());
|
||||
IFhirResourceDao dao = myDaoRegistry.getResourceDao(resourceDef.getImplementingClass());
|
||||
return dao.read(payloadId.toVersionless());
|
||||
}
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
package ca.uhn.fhir.jpa.subscription.match.deliver;
|
||||
|
||||
/*-
|
||||
* #%L
|
||||
* HAPI FHIR Subscription Server
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2020 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 org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
|
||||
public interface IResourceRetriever {
|
||||
IBaseResource getResource(IIdType theId);
|
||||
}
|
|
@ -37,7 +37,6 @@ import java.util.List;
|
|||
|
||||
import static org.apache.commons.lang3.StringUtils.*;
|
||||
|
||||
@Scope("prototype")
|
||||
public class SubscriptionDeliveringEmailSubscriber extends BaseSubscriptionDeliverySubscriber {
|
||||
private Logger ourLog = LoggerFactory.getLogger(SubscriptionDeliveringEmailSubscriber.class);
|
||||
|
||||
|
|
|
@ -20,15 +20,22 @@ package ca.uhn.fhir.jpa.subscription.match.deliver.resthook;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||
import ca.uhn.fhir.interceptor.api.HookParams;
|
||||
import ca.uhn.fhir.jpa.subscription.model.CanonicalSubscription;
|
||||
import ca.uhn.fhir.interceptor.api.Pointcut;
|
||||
import ca.uhn.fhir.jpa.subscription.model.ResourceDeliveryMessage;
|
||||
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
|
||||
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
|
||||
import ca.uhn.fhir.jpa.subscription.match.deliver.BaseSubscriptionDeliverySubscriber;
|
||||
import ca.uhn.fhir.jpa.subscription.match.deliver.IResourceRetriever;
|
||||
import ca.uhn.fhir.jpa.subscription.model.CanonicalSubscription;
|
||||
import ca.uhn.fhir.jpa.subscription.model.ResourceDeliveryMessage;
|
||||
import ca.uhn.fhir.rest.api.EncodingEnum;
|
||||
import ca.uhn.fhir.rest.api.RequestTypeEnum;
|
||||
import ca.uhn.fhir.rest.client.api.*;
|
||||
import ca.uhn.fhir.rest.client.api.Header;
|
||||
import ca.uhn.fhir.rest.client.api.IGenericClient;
|
||||
import ca.uhn.fhir.rest.client.api.IHttpClient;
|
||||
import ca.uhn.fhir.rest.client.api.IHttpRequest;
|
||||
import ca.uhn.fhir.rest.client.api.IHttpResponse;
|
||||
import ca.uhn.fhir.rest.client.api.ServerValidationModeEnum;
|
||||
import ca.uhn.fhir.rest.client.interceptor.SimpleRequestHeaderInterceptor;
|
||||
import ca.uhn.fhir.rest.gclient.IClientExecutable;
|
||||
import ca.uhn.fhir.rest.server.exceptions.ResourceGoneException;
|
||||
|
@ -43,16 +50,23 @@ import org.springframework.context.annotation.Scope;
|
|||
import org.springframework.messaging.MessagingException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
@Scope("prototype")
|
||||
public class SubscriptionDeliveringRestHookSubscriber extends BaseSubscriptionDeliverySubscriber {
|
||||
|
||||
@Autowired
|
||||
IResourceRetriever myResourceRetriever;
|
||||
private DaoRegistry myDaoRegistry;
|
||||
|
||||
private Logger ourLog = LoggerFactory.getLogger(SubscriptionDeliveringRestHookSubscriber.class);
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
|
@ -115,6 +129,13 @@ public class SubscriptionDeliveringRestHookSubscriber extends BaseSubscriptionDe
|
|||
}
|
||||
}
|
||||
|
||||
public IBaseResource getResource(IIdType payloadId) throws ResourceGoneException {
|
||||
RuntimeResourceDefinition resourceDef = myFhirContext.getResourceDefinition(payloadId.getResourceType());
|
||||
IFhirResourceDao dao = myDaoRegistry.getResourceDao(resourceDef.getImplementingClass());
|
||||
return dao.read(payloadId.toVersionless());
|
||||
}
|
||||
|
||||
|
||||
protected IBaseResource getAndMassagePayload(ResourceDeliveryMessage theMsg, CanonicalSubscription theSubscription) {
|
||||
IBaseResource payloadResource = theMsg.getPayload(myFhirContext);
|
||||
|
||||
|
@ -123,7 +144,7 @@ public class SubscriptionDeliveringRestHookSubscriber extends BaseSubscriptionDe
|
|||
|
||||
try {
|
||||
if (payloadId != null) {
|
||||
payloadResource = myResourceRetriever.getResource(payloadId.toVersionless());
|
||||
payloadResource = getResource(payloadId.toVersionless());
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -93,14 +93,9 @@ public class SubscriptionLoader {
|
|||
syncSubscriptions();
|
||||
}
|
||||
|
||||
public static class Job implements HapiJob {
|
||||
@Autowired
|
||||
private SubscriptionLoader myTarget;
|
||||
|
||||
@Override
|
||||
public void execute(JobExecutionContext theContext) {
|
||||
myTarget.syncSubscriptions();
|
||||
}
|
||||
@VisibleForTesting
|
||||
public void acquireSemaphoreForUnitTest() throws InterruptedException {
|
||||
mySyncSubscriptionsSemaphore.acquire();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
|
@ -161,5 +156,15 @@ public class SubscriptionLoader {
|
|||
}
|
||||
}
|
||||
|
||||
public static class Job implements HapiJob {
|
||||
@Autowired
|
||||
private SubscriptionLoader myTarget;
|
||||
|
||||
@Override
|
||||
public void execute(JobExecutionContext theContext) {
|
||||
myTarget.syncSubscriptions();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ import java.util.concurrent.ThreadPoolExecutor;
|
|||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static ca.uhn.fhir.jpa.model.util.JpaConstants.SUBSCRIPTION_TRIGGERING_PARAM_RESOURCE_ID;
|
||||
import static ca.uhn.fhir.jpa.model.util.ProviderConstants.SUBSCRIPTION_TRIGGERING_PARAM_RESOURCE_ID;
|
||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
package ca.uhn.fhir.jpa.subscription.module;
|
||||
|
||||
import ca.uhn.fhir.jpa.subscription.channel.subscription.SubscriptionChannelRegistry;
|
||||
import ca.uhn.fhir.jpa.subscription.match.registry.SubscriptionRegistry;
|
||||
import ca.uhn.fhir.jpa.subscription.module.config.TestSubscriptionDstu3Config;
|
||||
import ca.uhn.fhir.util.StopWatch;
|
||||
import org.hl7.fhir.dstu3.model.Subscription;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.awaitility.Awaitility.await;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
@ContextConfiguration(classes = {TestSubscriptionDstu3Config.class})
|
||||
public abstract class BaseSubscriptionDstu3Test extends BaseSubscriptionTest {
|
||||
@Autowired
|
||||
protected SubscriptionRegistry mySubscriptionRegistry;
|
||||
@Autowired
|
||||
protected SubscriptionChannelRegistry mySubscriptionChannelRegistry;
|
||||
|
||||
private final SubscriptionTestHelper mySubscriptionTestHelper = new SubscriptionTestHelper();
|
||||
|
||||
public static void waitForSize(int theTarget, List<?> theList) {
|
||||
StopWatch sw = new StopWatch();
|
||||
while (theList.size() != theTarget && sw.getMillis() <= 16000) {
|
||||
try {
|
||||
Thread.sleep(50);
|
||||
} catch (InterruptedException theE) {
|
||||
throw new Error(theE);
|
||||
}
|
||||
}
|
||||
if (sw.getMillis() >= 16000) {
|
||||
String describeResults = theList
|
||||
.stream()
|
||||
.map(t -> {
|
||||
if (t == null) {
|
||||
return "null";
|
||||
}
|
||||
if (t instanceof IBaseResource) {
|
||||
return ((IBaseResource) t).getIdElement().getValue();
|
||||
}
|
||||
return t.toString();
|
||||
})
|
||||
.collect(Collectors.joining(", "));
|
||||
fail("Size " + theList.size() + " is != target " + theTarget + " - Got: " + describeResults);
|
||||
}
|
||||
}
|
||||
|
||||
protected long nextId() {
|
||||
return mySubscriptionTestHelper.nextId();
|
||||
}
|
||||
|
||||
protected Subscription makeActiveSubscription(String theCriteria, String thePayload, String theEndpoint) {
|
||||
return mySubscriptionTestHelper.makeActiveSubscription(theCriteria, thePayload, theEndpoint);
|
||||
}
|
||||
|
||||
protected Subscription makeSubscriptionWithStatus(String theCriteria, String thePayload, String theEndpoint, Subscription.SubscriptionStatus status) {
|
||||
return mySubscriptionTestHelper.makeSubscriptionWithStatus(theCriteria, thePayload, theEndpoint, status);
|
||||
}
|
||||
|
||||
protected void clearRegistry() {
|
||||
mySubscriptionRegistry.unregisterAllSubscriptions();
|
||||
await().until(this::registryEmpty);
|
||||
}
|
||||
|
||||
private boolean registryEmpty() {
|
||||
return mySubscriptionRegistry.size() == 0 && mySubscriptionChannelRegistry.size() == 0;
|
||||
}
|
||||
|
||||
protected void assertRegistrySize(int theSize) {
|
||||
assertRegistrySize(theSize, theSize);
|
||||
}
|
||||
|
||||
protected void assertRegistrySize(int theSubscriptionRegistrySize, int theSubscriptionChannelRegistrySize) {
|
||||
assertEquals(theSubscriptionRegistrySize, mySubscriptionRegistry.size());
|
||||
assertEquals(theSubscriptionChannelRegistrySize, mySubscriptionChannelRegistry.size());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
package ca.uhn.fhir.jpa.subscription.module;
|
||||
|
||||
import ca.uhn.fhir.interceptor.api.IInterceptorService;
|
||||
import ca.uhn.fhir.interceptor.executor.InterceptorService;
|
||||
import ca.uhn.fhir.jpa.api.config.DaoConfig;
|
||||
import ca.uhn.fhir.jpa.searchparam.config.SearchParamConfig;
|
||||
import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry;
|
||||
import ca.uhn.fhir.jpa.subscription.channel.impl.LinkedBlockingChannelFactory;
|
||||
import ca.uhn.fhir.jpa.subscription.channel.subscription.SubscriptionChannelFactory;
|
||||
import ca.uhn.fhir.jpa.subscription.match.config.SubscriptionProcessorConfig;
|
||||
import ca.uhn.fhir.jpa.subscription.module.config.MockFhirClientSearchParamProvider;
|
||||
import ca.uhn.fhir.jpa.subscription.module.config.MockFhirClientSubscriptionProvider;
|
||||
import ca.uhn.fhir.jpa.subscription.module.config.TestSubscriptionConfig;
|
||||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||
import org.junit.After;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = {
|
||||
SearchParamConfig.class,
|
||||
SubscriptionProcessorConfig.class,
|
||||
TestSubscriptionConfig.class,
|
||||
BaseSubscriptionTest.MyConfig.class
|
||||
})
|
||||
public abstract class BaseSubscriptionTest {
|
||||
|
||||
@Autowired
|
||||
protected IInterceptorService myInterceptorRegistry;
|
||||
@Autowired
|
||||
MockFhirClientSubscriptionProvider myMockFhirClientSubscriptionProvider;
|
||||
|
||||
@Autowired
|
||||
ISearchParamRegistry mySearchParamRegistry;
|
||||
|
||||
@Autowired
|
||||
MockFhirClientSearchParamProvider myMockFhirClientSearchParamProvider;
|
||||
|
||||
@After
|
||||
public void afterClearAnonymousLambdas() {
|
||||
myInterceptorRegistry.unregisterAllInterceptors();
|
||||
}
|
||||
|
||||
public void initSearchParamRegistry(IBundleProvider theBundleProvider) {
|
||||
myMockFhirClientSearchParamProvider.setBundleProvider(theBundleProvider);
|
||||
mySearchParamRegistry.forceRefresh();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
public static class MyConfig {
|
||||
|
||||
@Bean
|
||||
public DaoConfig daoConfig() {
|
||||
return new DaoConfig();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SubscriptionChannelFactory mySubscriptionChannelFactory() {
|
||||
return new SubscriptionChannelFactory(new LinkedBlockingChannelFactory());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public IInterceptorService interceptorService() {
|
||||
return new InterceptorService();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package ca.uhn.fhir.jpa.subscription.module.cache;
|
||||
|
||||
import ca.uhn.fhir.jpa.subscription.module.BaseSubscriptionDstu3Test;
|
||||
import org.hl7.fhir.dstu3.model.Subscription;
|
||||
import org.junit.After;
|
||||
|
||||
public abstract class BaseSubscriptionRegistryTest extends BaseSubscriptionDstu3Test {
|
||||
public static final String SUBSCRIPTION_ID = "1";
|
||||
public static final String ORIG_CRITERIA = "Patient?";
|
||||
public static final String NEW_CRITERIA = "Observation?";
|
||||
|
||||
@After
|
||||
public void clearRegistryAfter() {
|
||||
super.clearRegistry();
|
||||
}
|
||||
|
||||
protected Subscription createSubscription() {
|
||||
Subscription subscription = new Subscription();
|
||||
subscription.setId(SUBSCRIPTION_ID);
|
||||
subscription.setCriteria(ORIG_CRITERIA);
|
||||
subscription.setStatus(Subscription.SubscriptionStatus.ACTIVE);
|
||||
setChannel(subscription, Subscription.SubscriptionChannelType.RESTHOOK);
|
||||
return subscription;
|
||||
}
|
||||
|
||||
protected void setChannel(Subscription theSubscription, Subscription.SubscriptionChannelType theResthook) {
|
||||
Subscription.SubscriptionChannelComponent channel = new Subscription.SubscriptionChannelComponent();
|
||||
channel.setType(theResthook);
|
||||
channel.setPayload("application/json");
|
||||
channel.setEndpoint("http://unused.test.endpoint/");
|
||||
theSubscription.setChannel(channel);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
package ca.uhn.fhir.jpa.subscription.module.cache;
|
||||
|
||||
import ca.uhn.fhir.jpa.subscription.match.registry.SubscriptionLoader;
|
||||
import ca.uhn.fhir.jpa.subscription.module.config.MockFhirClientSubscriptionProvider;
|
||||
import ca.uhn.fhir.jpa.subscription.module.standalone.BaseBlockingQueueSubscribableChannelDstu3Test;
|
||||
import org.hl7.fhir.dstu3.model.Subscription;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class SubscriptionLoaderTest extends BaseBlockingQueueSubscribableChannelDstu3Test {
|
||||
private static final int MOCK_FHIR_CLIENT_FAILURES = 3;
|
||||
@Autowired
|
||||
private MockFhirClientSubscriptionProvider myMockFhirClientSubscriptionProvider;
|
||||
|
||||
@Before
|
||||
public void setFailCount() {
|
||||
myMockFhirClientSubscriptionProvider.setFailCount(MOCK_FHIR_CLIENT_FAILURES);
|
||||
}
|
||||
|
||||
@After
|
||||
public void restoreFailCount() {
|
||||
myMockFhirClientSubscriptionProvider.setFailCount(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testSubscriptionLoaderFhirClientDown() throws Exception {
|
||||
String payload = "application/fhir+json";
|
||||
|
||||
String criteria1 = "Observation?code=SNOMED-CT|" + myCode + "&_format=xml";
|
||||
String criteria2 = "Observation?code=SNOMED-CT|" + myCode + "111&_format=xml";
|
||||
|
||||
List<Subscription> subs = new ArrayList<>();
|
||||
subs.add(makeActiveSubscription(criteria1, payload, ourListenerServerBase));
|
||||
subs.add(makeActiveSubscription(criteria2, payload, ourListenerServerBase));
|
||||
|
||||
mySubscriptionActivatedPost.setExpectedCount(2);
|
||||
initSubscriptionLoader(subs, "uuid");
|
||||
mySubscriptionActivatedPost.awaitExpected();
|
||||
assertEquals(0, myMockFhirClientSubscriptionProvider.getFailCount());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testMultipleThreadsDontBlock() throws InterruptedException {
|
||||
SubscriptionLoader svc = new SubscriptionLoader();
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
new Thread(()->{
|
||||
try {
|
||||
svc.acquireSemaphoreForUnitTest();
|
||||
latch.countDown();
|
||||
} catch (InterruptedException theE) {
|
||||
// ignore
|
||||
}
|
||||
}).start();
|
||||
|
||||
latch.await(10, TimeUnit.SECONDS);
|
||||
svc.syncSubscriptions();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package ca.uhn.fhir.jpa.subscription.module.cache;
|
||||
|
||||
import ca.uhn.fhir.jpa.subscription.channel.subscription.ISubscriptionDeliveryChannelNamer;
|
||||
import ca.uhn.fhir.jpa.subscription.model.CanonicalSubscription;
|
||||
import org.hl7.fhir.dstu3.model.Subscription;
|
||||
import org.junit.Test;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
|
||||
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
|
||||
@ContextConfiguration(classes = {
|
||||
SubscriptionRegistrySharedTest.SpringConfig.class
|
||||
})
|
||||
public class SubscriptionRegistrySharedTest extends BaseSubscriptionRegistryTest {
|
||||
|
||||
private static final String OTHER_ID = "OTHER_ID";
|
||||
|
||||
@Configuration
|
||||
public static class SpringConfig {
|
||||
|
||||
@Primary
|
||||
@Bean
|
||||
ISubscriptionDeliveryChannelNamer subscriptionDeliveryChannelNamer() {
|
||||
return new SharedNamer();
|
||||
}
|
||||
|
||||
private class SharedNamer implements ISubscriptionDeliveryChannelNamer {
|
||||
@Override
|
||||
public String nameFromSubscription(CanonicalSubscription theCanonicalSubscription) {
|
||||
return "shared";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTwoSubscriptionsOneChannel() {
|
||||
Subscription subscription = createSubscription();
|
||||
assertRegistrySize(0);
|
||||
mySubscriptionRegistry.registerSubscriptionUnlessAlreadyRegistered(subscription);
|
||||
assertRegistrySize(1);
|
||||
Subscription otherSubscription = createSubscription();
|
||||
otherSubscription.setId(OTHER_ID);
|
||||
mySubscriptionRegistry.registerSubscriptionUnlessAlreadyRegistered(otherSubscription);
|
||||
assertRegistrySize(2, 1);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
package ca.uhn.fhir.jpa.subscription.module.cache;
|
||||
|
||||
import ca.uhn.fhir.jpa.subscription.match.registry.ActiveSubscription;
|
||||
import org.hl7.fhir.dstu3.model.Subscription;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class SubscriptionRegistryTest extends BaseSubscriptionRegistryTest {
|
||||
@Test
|
||||
public void updateSubscriptionReusesActiveSubscription() {
|
||||
Subscription subscription = createSubscription();
|
||||
assertRegistrySize(0);
|
||||
mySubscriptionRegistry.registerSubscriptionUnlessAlreadyRegistered(subscription);
|
||||
assertRegistrySize(1);
|
||||
ActiveSubscription origActiveSubscription = mySubscriptionRegistry.get(SUBSCRIPTION_ID);
|
||||
assertEquals(ORIG_CRITERIA, origActiveSubscription.getCriteriaString());
|
||||
|
||||
subscription.setCriteria(NEW_CRITERIA);
|
||||
assertEquals(ORIG_CRITERIA, origActiveSubscription.getCriteriaString());
|
||||
mySubscriptionRegistry.registerSubscriptionUnlessAlreadyRegistered(subscription);
|
||||
assertRegistrySize(1);
|
||||
ActiveSubscription newActiveSubscription = mySubscriptionRegistry.get(SUBSCRIPTION_ID);
|
||||
assertEquals(NEW_CRITERIA, newActiveSubscription.getCriteriaString());
|
||||
// The same object
|
||||
assertTrue(newActiveSubscription == origActiveSubscription);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateSubscriptionDoesntReusesActiveSubscriptionWhenChannelChanges() {
|
||||
Subscription subscription = createSubscription();
|
||||
assertRegistrySize(0);
|
||||
mySubscriptionRegistry.registerSubscriptionUnlessAlreadyRegistered(subscription);
|
||||
assertRegistrySize(1);
|
||||
|
||||
ActiveSubscription origActiveSubscription = mySubscriptionRegistry.get(SUBSCRIPTION_ID);
|
||||
assertEquals(ORIG_CRITERIA, origActiveSubscription.getCriteriaString());
|
||||
|
||||
setChannel(subscription, Subscription.SubscriptionChannelType.EMAIL);
|
||||
|
||||
assertEquals(ORIG_CRITERIA, origActiveSubscription.getCriteriaString());
|
||||
mySubscriptionRegistry.registerSubscriptionUnlessAlreadyRegistered(subscription);
|
||||
assertRegistrySize(1);
|
||||
|
||||
ActiveSubscription newActiveSubscription = mySubscriptionRegistry.get(SUBSCRIPTION_ID);
|
||||
// A new object
|
||||
assertFalse(newActiveSubscription == origActiveSubscription);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateRemove() {
|
||||
Subscription subscription = createSubscription();
|
||||
assertRegistrySize(0);
|
||||
mySubscriptionRegistry.registerSubscriptionUnlessAlreadyRegistered(subscription);
|
||||
assertRegistrySize(1);
|
||||
mySubscriptionRegistry.unregisterSubscriptionIfRegistered(subscription.getId());
|
||||
assertRegistrySize(0);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package ca.uhn.fhir.jpa.subscription.module.config;
|
||||
|
||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||
import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamProvider;
|
||||
import ca.uhn.fhir.jpa.searchparam.registry.SearchParamRegistryImpl;
|
||||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
public class MockFhirClientSearchParamProvider implements ISearchParamProvider {
|
||||
private final MockProvider myMockProvider = new MockProvider();
|
||||
|
||||
@Autowired
|
||||
private SearchParamRegistryImpl mySearchParamRegistry;
|
||||
|
||||
public MockFhirClientSearchParamProvider() {
|
||||
super();
|
||||
}
|
||||
|
||||
public void setBundleProvider(IBundleProvider theBundleProvider) { myMockProvider.setBundleProvider(theBundleProvider); }
|
||||
|
||||
public void setFailCount(int theFailCount) { myMockProvider.setFailCount(theFailCount); }
|
||||
|
||||
public int getFailCount() { return myMockProvider.getFailCount(); }
|
||||
|
||||
@Override
|
||||
public IBundleProvider search(SearchParameterMap theParams) { return myMockProvider.search(theParams); }
|
||||
|
||||
@Override
|
||||
public int refreshCache(SearchParamRegistryImpl theSearchParamRegistry, long theRefreshInterval) {
|
||||
mySearchParamRegistry.doRefresh(0);
|
||||
return 0;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package ca.uhn.fhir.jpa.subscription.module.config;
|
||||
|
||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||
import ca.uhn.fhir.jpa.subscription.match.registry.ISubscriptionProvider;
|
||||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
|
||||
public class MockFhirClientSubscriptionProvider implements ISubscriptionProvider {
|
||||
private final MockProvider myMockProvider = new MockProvider();
|
||||
|
||||
public MockFhirClientSubscriptionProvider() {
|
||||
super();
|
||||
}
|
||||
|
||||
public void setBundleProvider(IBundleProvider theBundleProvider) { myMockProvider.setBundleProvider(theBundleProvider); }
|
||||
public void setFailCount(int theFailCount) { myMockProvider.setFailCount(theFailCount); }
|
||||
public int getFailCount() { return myMockProvider.getFailCount(); }
|
||||
|
||||
@Override
|
||||
public IBundleProvider search(SearchParameterMap theParams) { return myMockProvider.search(theParams); }
|
||||
|
||||
@Override
|
||||
public boolean loadSubscription(IBaseResource theResource) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package ca.uhn.fhir.jpa.subscription.module.config;
|
||||
|
||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||
import ca.uhn.fhir.rest.server.SimpleBundleProvider;
|
||||
|
||||
public class MockProvider {
|
||||
private IBundleProvider myBundleProvider = new SimpleBundleProvider();
|
||||
private int myFailCount = 0;
|
||||
|
||||
public void setBundleProvider(IBundleProvider theBundleProvider) {
|
||||
myBundleProvider = theBundleProvider;
|
||||
}
|
||||
|
||||
public IBundleProvider search(SearchParameterMap theParams) {
|
||||
if (myFailCount > 0) {
|
||||
--myFailCount;
|
||||
throw new RuntimeException("Mock Search Failed");
|
||||
}
|
||||
return myBundleProvider;
|
||||
}
|
||||
|
||||
public void setFailCount(int theFailCount) {
|
||||
myFailCount = theFailCount;
|
||||
}
|
||||
|
||||
public int getFailCount() {
|
||||
return myFailCount;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package ca.uhn.fhir.jpa.subscription.module.config;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.jpa.model.entity.ModelConfig;
|
||||
import ca.uhn.fhir.jpa.subscription.match.matcher.matching.ISubscriptionMatcher;
|
||||
import ca.uhn.fhir.jpa.subscription.match.matcher.matching.InMemorySubscriptionMatcher;
|
||||
import ca.uhn.fhir.rest.client.api.IGenericClient;
|
||||
import org.mockito.Mockito;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
|
||||
@Configuration
|
||||
@TestPropertySource(properties = {
|
||||
"scheduling_disabled=true"
|
||||
})
|
||||
public class TestSubscriptionConfig {
|
||||
|
||||
@Bean
|
||||
public ModelConfig modelConfig() {
|
||||
return new ModelConfig();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public IGenericClient fhirClient(FhirContext theFhirContext) {
|
||||
return Mockito.mock(IGenericClient.class);
|
||||
};
|
||||
|
||||
@Bean
|
||||
public InMemorySubscriptionMatcher inMemorySubscriptionMatcher() {
|
||||
return new InMemorySubscriptionMatcher();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
package ca.uhn.fhir.jpa.subscription.module.config;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.context.support.IValidationSupport;
|
||||
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
|
||||
import ca.uhn.fhir.jpa.model.sched.ISchedulerService;
|
||||
import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamProvider;
|
||||
import ca.uhn.fhir.jpa.subscription.match.registry.ISubscriptionProvider;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
@Configuration
|
||||
@Import(TestSubscriptionConfig.class)
|
||||
public class TestSubscriptionDstu3Config {
|
||||
|
||||
@Bean
|
||||
public FhirContext fhirContext() {
|
||||
return FhirContext.forDstu3();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public IValidationSupport validationSupport() {
|
||||
return FhirContext.forDstu3().getValidationSupport();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Primary
|
||||
public ISearchParamProvider searchParamProvider() {
|
||||
return new MockFhirClientSearchParamProvider();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Primary
|
||||
public ISubscriptionProvider subscriptionProvider() {
|
||||
return new MockFhirClientSubscriptionProvider();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ISchedulerService schedulerService() {
|
||||
return mock(ISchedulerService.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DaoRegistry daoRegistry() {
|
||||
return new DaoRegistry();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,649 @@
|
|||
package ca.uhn.fhir.jpa.subscription.module.matcher;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.jpa.model.entity.ModelConfig;
|
||||
import ca.uhn.fhir.jpa.searchparam.matcher.InMemoryMatchResult;
|
||||
import ca.uhn.fhir.jpa.searchparam.matcher.SearchParamMatcher;
|
||||
import ca.uhn.fhir.jpa.subscription.match.matcher.matching.SubscriptionMatchingStrategy;
|
||||
import ca.uhn.fhir.jpa.subscription.match.matcher.matching.SubscriptionStrategyEvaluator;
|
||||
import ca.uhn.fhir.jpa.subscription.module.BaseSubscriptionDstu3Test;
|
||||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||
import ca.uhn.fhir.rest.server.SimpleBundleProvider;
|
||||
import ca.uhn.fhir.util.UrlUtil;
|
||||
import org.hl7.fhir.dstu3.model.*;
|
||||
import org.hl7.fhir.dstu3.model.codesystems.MedicationRequestCategory;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class InMemorySubscriptionMatcherR3Test extends BaseSubscriptionDstu3Test {
|
||||
@Autowired
|
||||
SubscriptionStrategyEvaluator mySubscriptionStrategyEvaluator;
|
||||
@Autowired
|
||||
SearchParamMatcher mySearchParamMatcher;
|
||||
@Autowired
|
||||
ModelConfig myModelConfig;
|
||||
@Autowired
|
||||
FhirContext myFhirContext;
|
||||
|
||||
private void assertUnsupported(IBaseResource resource, String criteria) {
|
||||
assertFalse(mySearchParamMatcher.match(criteria, resource, null).supported());
|
||||
assertEquals(SubscriptionMatchingStrategy.DATABASE, mySubscriptionStrategyEvaluator.determineStrategy(criteria));
|
||||
}
|
||||
|
||||
private void assertMatched(IBaseResource resource, String criteria) {
|
||||
InMemoryMatchResult result = mySearchParamMatcher.match(criteria, resource, null);
|
||||
|
||||
assertTrue(result.supported());
|
||||
assertTrue(result.matched());
|
||||
assertEquals(SubscriptionMatchingStrategy.IN_MEMORY, mySubscriptionStrategyEvaluator.determineStrategy(criteria));
|
||||
}
|
||||
|
||||
private void assertNotMatched(IBaseResource resource, String criteria) {
|
||||
assertNotMatched(resource, criteria, SubscriptionMatchingStrategy.IN_MEMORY);
|
||||
}
|
||||
|
||||
private void assertNotMatched(IBaseResource resource, String criteria, SubscriptionMatchingStrategy theSubscriptionMatchingStrategy) {
|
||||
InMemoryMatchResult result = mySearchParamMatcher.match(criteria, resource, null);
|
||||
|
||||
assertTrue(result.supported());
|
||||
assertFalse(result.matched());
|
||||
|
||||
assertEquals(theSubscriptionMatchingStrategy, mySubscriptionStrategyEvaluator.determineStrategy(criteria));
|
||||
}
|
||||
|
||||
@After
|
||||
public void after() {
|
||||
myModelConfig.setTreatBaseUrlsAsLocal(new ModelConfig().getTreatBaseUrlsAsLocal());
|
||||
}
|
||||
|
||||
/**
|
||||
* Technically this is an invalid reference in most cases, but this shouldn't choke
|
||||
* the matcher in the case that it gets used.
|
||||
*/
|
||||
@Test
|
||||
public void testPlaceholderIdInReference() {
|
||||
|
||||
ProcedureRequest pr = new ProcedureRequest();
|
||||
pr.setId("ProcedureRequest/123");
|
||||
pr.setIntent(ProcedureRequest.ProcedureRequestIntent.ORIGINALORDER);
|
||||
|
||||
pr.setSubject(new Reference("urn:uuid:aaaaaaaaaa"));
|
||||
assertMatched(pr, "ProcedureRequest?intent=original-order");
|
||||
assertNotMatched(pr, "ProcedureRequest?subject=Patient/123");
|
||||
|
||||
pr.setSubject(new Reference("Foo/123"));
|
||||
assertMatched(pr, "ProcedureRequest?intent=original-order");
|
||||
assertNotMatched(pr, "ProcedureRequest?subject=Patient/123");
|
||||
|
||||
pr.setSubject(new Reference("Patient/"));
|
||||
assertMatched(pr, "ProcedureRequest?intent=original-order");
|
||||
assertNotMatched(pr, "ProcedureRequest?subject=Patient/123");
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testResourceById() {
|
||||
|
||||
ProcedureRequest pr = new ProcedureRequest();
|
||||
pr.setId("ProcedureRequest/123");
|
||||
pr.setIntent(ProcedureRequest.ProcedureRequestIntent.ORIGINALORDER);
|
||||
|
||||
assertMatched(pr, "ProcedureRequest?_id=123");
|
||||
assertMatched(pr, "ProcedureRequest?_id=ProcedureRequest/123");
|
||||
assertMatched(pr, "ProcedureRequest?_id=ProcedureRequest/123,ProcedureRequest/999");
|
||||
assertMatched(pr, "ProcedureRequest?_id=ProcedureRequest/123&_id=ProcedureRequest/123");
|
||||
assertNotMatched(pr, "ProcedureRequest?_id=ProcedureRequest/888");
|
||||
assertNotMatched(pr, "ProcedureRequest?_id=ProcedureRequest/888,ProcedureRequest/999");
|
||||
assertNotMatched(pr, "ProcedureRequest?_id=ProcedureRequest/123&_id=ProcedureRequest/888");
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
The following tests are copied from an e-mail from a site using HAPI FHIR
|
||||
*/
|
||||
|
||||
@Test
|
||||
public void testQuestionnaireResponse() {
|
||||
String criteria = "QuestionnaireResponse?questionnaire=HomeAbsenceHospitalizationRecord,ARIncenterAbsRecord";
|
||||
|
||||
{
|
||||
QuestionnaireResponse qr = new QuestionnaireResponse();
|
||||
qr.getQuestionnaire().setReference("Questionnaire/HomeAbsenceHospitalizationRecord");
|
||||
assertMatched(qr, criteria);
|
||||
}
|
||||
{
|
||||
QuestionnaireResponse qr = new QuestionnaireResponse();
|
||||
qr.getQuestionnaire().setReference("Questionnaire/Other");
|
||||
assertNotMatched(qr, criteria);
|
||||
}
|
||||
{
|
||||
QuestionnaireResponse qr = new QuestionnaireResponse();
|
||||
qr.getQuestionnaire().setDisplay("Questionnaire/HomeAbsenceHospitalizationRecord");
|
||||
assertNotMatched(qr, criteria);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCommunicationRequest() {
|
||||
String criteria = "CommunicationRequest?occurrence==2018-10-17";
|
||||
|
||||
{
|
||||
CommunicationRequest cr = new CommunicationRequest();
|
||||
cr.setOccurrence(new DateTimeType("2018-10-17"));
|
||||
assertMatched(cr, criteria);
|
||||
}
|
||||
{
|
||||
CommunicationRequest cr = new CommunicationRequest();
|
||||
cr.setOccurrence(new DateTimeType("2018-10-16"));
|
||||
assertNotMatched(cr, criteria);
|
||||
}
|
||||
{
|
||||
CommunicationRequest cr = new CommunicationRequest();
|
||||
cr.setOccurrence(new DateTimeType("2018-10-16"));
|
||||
assertNotMatched(cr, criteria);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcedureRequest() {
|
||||
String criteria = "ProcedureRequest?intent=original-order";
|
||||
|
||||
{
|
||||
ProcedureRequest pr = new ProcedureRequest();
|
||||
pr.setIntent(ProcedureRequest.ProcedureRequestIntent.ORIGINALORDER);
|
||||
assertMatched(pr, criteria);
|
||||
}
|
||||
{
|
||||
ProcedureRequest pr = new ProcedureRequest();
|
||||
pr.setIntent(ProcedureRequest.ProcedureRequestIntent.ORDER);
|
||||
assertNotMatched(pr, criteria);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testObservationContextTypeUnsupported() {
|
||||
String criteria = "Observation?code=17861-6&context.type=IHD";
|
||||
{
|
||||
Observation obs = new Observation();
|
||||
obs.getCode().addCoding().setCode("XXX");
|
||||
assertNotMatched(obs, criteria, SubscriptionMatchingStrategy.DATABASE);
|
||||
}
|
||||
{
|
||||
Observation obs = new Observation();
|
||||
obs.getCode().addCoding().setCode("17861-6");
|
||||
assertUnsupported(obs, criteria);
|
||||
}
|
||||
}
|
||||
|
||||
// Check that it still fails fast even if the chained parameter is first
|
||||
@Test
|
||||
public void testObservationContextTypeUnsupportedReverse() {
|
||||
String criteria = "Observation?context.type=IHD&code=17861-6";
|
||||
{
|
||||
Observation obs = new Observation();
|
||||
obs.getCode().addCoding().setCode("XXX");
|
||||
assertNotMatched(obs, criteria, SubscriptionMatchingStrategy.DATABASE);
|
||||
}
|
||||
{
|
||||
Observation obs = new Observation();
|
||||
obs.getCode().addCoding().setCode("17861-6");
|
||||
assertUnsupported(obs, criteria);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void medicationRequestOutpatient() {
|
||||
// Note the date== evaluates to date=eq which is a legacy format supported by hapi fhir
|
||||
String criteria = "MedicationRequest?intent=instance-order&category=outpatient&date==2018-10-19";
|
||||
|
||||
{
|
||||
MedicationRequest mr = new MedicationRequest();
|
||||
mr.setIntent(MedicationRequest.MedicationRequestIntent.INSTANCEORDER);
|
||||
mr.getCategory().addCoding().setCode(MedicationRequestCategory.OUTPATIENT.toCode());
|
||||
Dosage dosage = new Dosage();
|
||||
Timing timing = new Timing();
|
||||
timing.getEvent().add(new DateTimeType("2018-10-19"));
|
||||
dosage.setTiming(timing);
|
||||
mr.getDosageInstruction().add(dosage);
|
||||
assertMatched(mr, criteria);
|
||||
}
|
||||
|
||||
{
|
||||
MedicationRequest mr = new MedicationRequest();
|
||||
mr.setIntent(MedicationRequest.MedicationRequestIntent.INSTANCEORDER);
|
||||
mr.getCategory().addCoding().setCode(MedicationRequestCategory.INPATIENT.toCode());
|
||||
Dosage dosage = new Dosage();
|
||||
Timing timing = new Timing();
|
||||
timing.getEvent().add(new DateTimeType("2018-10-19"));
|
||||
dosage.setTiming(timing);
|
||||
mr.getDosageInstruction().add(dosage);
|
||||
assertNotMatched(mr, criteria);
|
||||
}
|
||||
|
||||
{
|
||||
MedicationRequest mr = new MedicationRequest();
|
||||
mr.setIntent(MedicationRequest.MedicationRequestIntent.INSTANCEORDER);
|
||||
mr.getCategory().addCoding().setCode(MedicationRequestCategory.OUTPATIENT.toCode());
|
||||
Dosage dosage = new Dosage();
|
||||
Timing timing = new Timing();
|
||||
timing.getEvent().add(new DateTimeType("2018-10-20"));
|
||||
dosage.setTiming(timing);
|
||||
mr.getDosageInstruction().add(dosage);
|
||||
assertNotMatched(mr, criteria);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMedicationRequestStatuses() {
|
||||
String criteria = "MedicationRequest?intent=plan&category=outpatient&status=suspended,entered-in-error,cancelled,stopped";
|
||||
|
||||
// Note suspended is an invalid status and will never match
|
||||
{
|
||||
MedicationRequest mr = new MedicationRequest();
|
||||
mr.setIntent(MedicationRequest.MedicationRequestIntent.PLAN);
|
||||
mr.getCategory().addCoding().setCode(MedicationRequestCategory.OUTPATIENT.toCode());
|
||||
mr.setStatus(MedicationRequest.MedicationRequestStatus.ENTEREDINERROR);
|
||||
assertMatched(mr, criteria);
|
||||
}
|
||||
{
|
||||
MedicationRequest mr = new MedicationRequest();
|
||||
mr.setIntent(MedicationRequest.MedicationRequestIntent.PLAN);
|
||||
mr.getCategory().addCoding().setCode(MedicationRequestCategory.OUTPATIENT.toCode());
|
||||
mr.setStatus(MedicationRequest.MedicationRequestStatus.CANCELLED);
|
||||
assertMatched(mr, criteria);
|
||||
}
|
||||
{
|
||||
MedicationRequest mr = new MedicationRequest();
|
||||
mr.setIntent(MedicationRequest.MedicationRequestIntent.PLAN);
|
||||
mr.getCategory().addCoding().setCode(MedicationRequestCategory.OUTPATIENT.toCode());
|
||||
mr.setStatus(MedicationRequest.MedicationRequestStatus.STOPPED);
|
||||
assertMatched(mr, criteria);
|
||||
}
|
||||
{
|
||||
MedicationRequest mr = new MedicationRequest();
|
||||
mr.setIntent(MedicationRequest.MedicationRequestIntent.PLAN);
|
||||
mr.getCategory().addCoding().setCode(MedicationRequestCategory.OUTPATIENT.toCode());
|
||||
mr.setStatus(MedicationRequest.MedicationRequestStatus.ACTIVE);
|
||||
assertNotMatched(mr, criteria);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBloodTest() {
|
||||
String criteria = "Observation?code=FR_Org1Blood2nd,FR_Org1Blood3rd,FR_Org%201BldCult,FR_Org2Blood2nd,FR_Org2Blood3rd,FR_Org%202BldCult,FR_Org3Blood2nd,FR_Org3Blood3rd,FR_Org3BldCult,FR_Org4Blood2nd,FR_Org4Blood3rd,FR_Org4BldCult,FR_Org5Blood2nd,FR_Org5Blood3rd,FR_Org%205BldCult,FR_Org6Blood2nd,FR_Org6Blood3rd,FR_Org6BldCult,FR_Org7Blood2nd,FR_Org7Blood3rd,FR_Org7BldCult,FR_Org8Blood2nd,FR_Org8Blood3rd,FR_Org8BldCult,FR_Org9Blood2nd,FR_Org9Blood3rd,FR_Org9BldCult,FR_Bld2ndCulture,FR_Bld3rdCulture,FR_Blood%20Culture,FR_Com1Bld3rd,FR_Com1BldCult,FR_Com2Bld2nd,FR_Com2Bld3rd,FR_Com2BldCult,FR_CultureBld2nd,FR_CultureBld3rd,FR_CultureBldCul,FR_GmStainBldCul,FR_GramStain2Bld,FR_GramStain3Bld,FR_GramStNegBac&context.type=IHD";
|
||||
|
||||
{
|
||||
Observation obs = new Observation();
|
||||
obs.getCode().addCoding().setCode("FR_Org1Blood2nd");
|
||||
assertUnsupported(obs, criteria);
|
||||
}
|
||||
{
|
||||
Observation obs = new Observation();
|
||||
obs.getCode().addCoding().setCode("XXX");
|
||||
assertNotMatched(obs, criteria, SubscriptionMatchingStrategy.DATABASE);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcedureHemodialysis() {
|
||||
String criteria = "Procedure?category=Hemodialysis";
|
||||
|
||||
{
|
||||
Procedure proc = new Procedure();
|
||||
proc.getCategory().addCoding().setCode("Hemodialysis");
|
||||
assertMatched(proc, criteria);
|
||||
}
|
||||
{
|
||||
Procedure proc = new Procedure();
|
||||
proc.getCategory().addCoding().setCode("XXX");
|
||||
assertNotMatched(proc, criteria);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcedureHDStandard() {
|
||||
String criteria = "Procedure?code=HD_Standard&status=completed&location=Lab123";
|
||||
|
||||
{
|
||||
Procedure proc = new Procedure();
|
||||
proc.getCode().addCoding().setCode("HD_Standard");
|
||||
proc.setStatus(Procedure.ProcedureStatus.COMPLETED);
|
||||
IIdType locId = new IdType("Location", "Lab123");
|
||||
proc.getLocation().setReference(locId.getValue());
|
||||
assertMatched(proc, criteria);
|
||||
}
|
||||
{
|
||||
Procedure proc = new Procedure();
|
||||
proc.getCode().addCoding().setCode("HD_Standard");
|
||||
proc.setStatus(Procedure.ProcedureStatus.COMPLETED);
|
||||
IIdType locId = new IdType("Location", "XXX");
|
||||
proc.getLocation().setReference(locId.getValue());
|
||||
assertNotMatched(proc, criteria);
|
||||
}
|
||||
{
|
||||
Procedure proc = new Procedure();
|
||||
proc.getCode().addCoding().setCode("XXX");
|
||||
proc.setStatus(Procedure.ProcedureStatus.COMPLETED);
|
||||
IIdType locId = new IdType("Location", "Lab123");
|
||||
proc.getLocation().setReference(locId.getValue());
|
||||
assertNotMatched(proc, criteria);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProvenance() {
|
||||
String criteria = "Provenance?activity=http://hl7.org/fhir/v3/DocumentCompletion%7CAU";
|
||||
|
||||
SearchParameter sp = new SearchParameter();
|
||||
sp.addBase("Provenance");
|
||||
sp.setCode("activity");
|
||||
sp.setType(Enumerations.SearchParamType.TOKEN);
|
||||
sp.setExpression("Provenance.activity");
|
||||
sp.setXpathUsage(SearchParameter.XPathUsageType.NORMAL);
|
||||
sp.setStatus(Enumerations.PublicationStatus.ACTIVE);
|
||||
|
||||
IBundleProvider bundle = new SimpleBundleProvider(Collections.singletonList(sp), "uuid");
|
||||
initSearchParamRegistry(bundle);
|
||||
|
||||
{
|
||||
Provenance prov = new Provenance();
|
||||
prov.setActivity(new Coding().setSystem("http://hl7.org/fhir/v3/DocumentCompletion").setCode("AU"));
|
||||
assertMatched(prov, criteria);
|
||||
}
|
||||
{
|
||||
Provenance prov = new Provenance();
|
||||
assertNotMatched(prov, criteria);
|
||||
}
|
||||
{
|
||||
Provenance prov = new Provenance();
|
||||
prov.setActivity(new Coding().setCode("XXX"));
|
||||
assertNotMatched(prov, criteria);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBodySite() {
|
||||
String criteria = "BodySite?accessType=Catheter,PD%20Catheter";
|
||||
|
||||
SearchParameter sp = new SearchParameter();
|
||||
sp.addBase("BodySite");
|
||||
sp.setCode("accessType");
|
||||
sp.setType(Enumerations.SearchParamType.TOKEN);
|
||||
sp.setExpression("BodySite.extension('BodySite#accessType')");
|
||||
sp.setXpathUsage(SearchParameter.XPathUsageType.NORMAL);
|
||||
sp.setStatus(Enumerations.PublicationStatus.ACTIVE);
|
||||
|
||||
IBundleProvider bundle = new SimpleBundleProvider(Collections.singletonList(sp), "uuid");
|
||||
initSearchParamRegistry(bundle);
|
||||
|
||||
{
|
||||
BodySite bodySite = new BodySite();
|
||||
bodySite.addExtension().setUrl("BodySite#accessType").setValue(new Coding().setCode("Catheter"));
|
||||
assertMatched(bodySite, criteria);
|
||||
}
|
||||
{
|
||||
BodySite bodySite = new BodySite();
|
||||
bodySite.addExtension().setUrl("BodySite#accessType").setValue(new Coding().setCode("PD Catheter"));
|
||||
assertMatched(bodySite, criteria);
|
||||
}
|
||||
{
|
||||
BodySite bodySite = new BodySite();
|
||||
assertNotMatched(bodySite, criteria);
|
||||
}
|
||||
{
|
||||
BodySite bodySite = new BodySite();
|
||||
bodySite.addExtension().setUrl("BodySite#accessType").setValue(new Coding().setCode("XXX"));
|
||||
assertNotMatched(bodySite, criteria);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcedureAnyLocation() {
|
||||
String criteria = "Procedure?code=HD_Standard&status=completed";
|
||||
{
|
||||
Procedure proc = new Procedure();
|
||||
proc.getCode().addCoding().setCode("HD_Standard");
|
||||
proc.setStatus(Procedure.ProcedureStatus.COMPLETED);
|
||||
IIdType locId = new IdType("Location", "Lab456");
|
||||
proc.getLocation().setReference(locId.getValue());
|
||||
assertMatched(proc, criteria);
|
||||
}
|
||||
{
|
||||
Procedure proc = new Procedure();
|
||||
proc.getCode().addCoding().setCode("HD_Standard");
|
||||
proc.setStatus(Procedure.ProcedureStatus.ABORTED);
|
||||
assertNotMatched(proc, criteria);
|
||||
}
|
||||
{
|
||||
Procedure proc = new Procedure();
|
||||
proc.getCode().addCoding().setCode("XXX");
|
||||
proc.setStatus(Procedure.ProcedureStatus.COMPLETED);
|
||||
assertNotMatched(proc, criteria);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQuestionnaireResponseLong() {
|
||||
String criteria = "QuestionnaireResponse?questionnaire=HomeAbsenceHospitalizationRecord,ARIncenterAbsRecord,FMCSWDepressionSymptomsScreener,FMCAKIComprehensiveSW,FMCSWIntensiveScreener,FMCESRDComprehensiveSW,FMCNutritionProgressNote,FMCAKIComprehensiveRN";
|
||||
|
||||
{
|
||||
QuestionnaireResponse qr = new QuestionnaireResponse();
|
||||
qr.getQuestionnaire().setReference("Questionnaire/HomeAbsenceHospitalizationRecord");
|
||||
assertMatched(qr, criteria);
|
||||
}
|
||||
{
|
||||
QuestionnaireResponse qr = new QuestionnaireResponse();
|
||||
qr.getQuestionnaire().setReference("Questionnaire/FMCSWIntensiveScreener");
|
||||
assertMatched(qr, criteria);
|
||||
}
|
||||
{
|
||||
QuestionnaireResponse qr = new QuestionnaireResponse();
|
||||
qr.getQuestionnaire().setReference("Questionnaire/FMCAKIComprehensiveRN");
|
||||
assertMatched(qr, criteria);
|
||||
}
|
||||
{
|
||||
QuestionnaireResponse qr = new QuestionnaireResponse();
|
||||
assertNotMatched(qr, criteria);
|
||||
}
|
||||
{
|
||||
QuestionnaireResponse qr = new QuestionnaireResponse();
|
||||
qr.getQuestionnaire().setReference("Questionnaire/FMCAKIComprehensiveRM");
|
||||
assertNotMatched(qr, criteria);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcedureRequestCategory() {
|
||||
String criteria = "ProcedureRequest?intent=instance-order&category=Laboratory,Ancillary%20Orders,Hemodialysis&occurrence==2018-10-19";
|
||||
|
||||
SearchParameter sp = new SearchParameter();
|
||||
sp.addBase("ProcedureRequest");
|
||||
sp.setCode("category");
|
||||
sp.setType(Enumerations.SearchParamType.TOKEN);
|
||||
sp.setExpression("ProcedureRequest.category");
|
||||
sp.setXpathUsage(SearchParameter.XPathUsageType.NORMAL);
|
||||
sp.setStatus(Enumerations.PublicationStatus.ACTIVE);
|
||||
|
||||
IBundleProvider bundle = new SimpleBundleProvider(Collections.singletonList(sp), "uuid");
|
||||
initSearchParamRegistry(bundle);
|
||||
|
||||
{
|
||||
ProcedureRequest pr = new ProcedureRequest();
|
||||
pr.setIntent(ProcedureRequest.ProcedureRequestIntent.INSTANCEORDER);
|
||||
CodeableConcept code = new CodeableConcept();
|
||||
code.addCoding().setCode("Laboratory");
|
||||
pr.getCategory().add(code);
|
||||
pr.setOccurrence(new DateTimeType("2018-10-19"));
|
||||
assertMatched(pr, criteria);
|
||||
}
|
||||
{
|
||||
ProcedureRequest pr = new ProcedureRequest();
|
||||
pr.setIntent(ProcedureRequest.ProcedureRequestIntent.INSTANCEORDER);
|
||||
CodeableConcept code = new CodeableConcept();
|
||||
code.addCoding().setCode("Ancillary Orders");
|
||||
pr.getCategory().add(code);
|
||||
pr.setOccurrence(new DateTimeType("2018-10-19"));
|
||||
assertMatched(pr, criteria);
|
||||
}
|
||||
{
|
||||
ProcedureRequest pr = new ProcedureRequest();
|
||||
pr.setIntent(ProcedureRequest.ProcedureRequestIntent.INSTANCEORDER);
|
||||
CodeableConcept code = new CodeableConcept();
|
||||
code.addCoding().setCode("Hemodialysis");
|
||||
pr.getCategory().add(code);
|
||||
pr.setOccurrence(new DateTimeType("2018-10-19"));
|
||||
assertMatched(pr, criteria);
|
||||
}
|
||||
{
|
||||
ProcedureRequest pr = new ProcedureRequest();
|
||||
pr.setIntent(ProcedureRequest.ProcedureRequestIntent.INSTANCEORDER);
|
||||
pr.setOccurrence(new DateTimeType("2018-10-19"));
|
||||
assertNotMatched(pr, criteria);
|
||||
}
|
||||
{
|
||||
ProcedureRequest pr = new ProcedureRequest();
|
||||
CodeableConcept code = new CodeableConcept();
|
||||
code.addCoding().setCode("Hemodialysis");
|
||||
pr.getCategory().add(code);
|
||||
pr.setOccurrence(new DateTimeType("2018-10-19"));
|
||||
assertNotMatched(pr, criteria);
|
||||
}
|
||||
{
|
||||
ProcedureRequest pr = new ProcedureRequest();
|
||||
pr.setIntent(ProcedureRequest.ProcedureRequestIntent.INSTANCEORDER);
|
||||
CodeableConcept code = new CodeableConcept();
|
||||
code.addCoding().setCode("Hemodialysis");
|
||||
pr.getCategory().add(code);
|
||||
assertNotMatched(pr, criteria);
|
||||
}
|
||||
{
|
||||
ProcedureRequest pr = new ProcedureRequest();
|
||||
pr.setIntent(ProcedureRequest.ProcedureRequestIntent.INSTANCEORDER);
|
||||
CodeableConcept code = new CodeableConcept();
|
||||
code.addCoding().setCode("XXX");
|
||||
pr.getCategory().add(code);
|
||||
pr.setOccurrence(new DateTimeType("2018-10-19"));
|
||||
assertNotMatched(pr, criteria);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEposideOfCare() {
|
||||
String criteria = "EpisodeOfCare?status=active";
|
||||
{
|
||||
EpisodeOfCare eoc = new EpisodeOfCare();
|
||||
eoc.setStatus(EpisodeOfCare.EpisodeOfCareStatus.ACTIVE);
|
||||
assertMatched(eoc, criteria);
|
||||
}
|
||||
{
|
||||
EpisodeOfCare eoc = new EpisodeOfCare();
|
||||
assertNotMatched(eoc, criteria);
|
||||
}
|
||||
{
|
||||
EpisodeOfCare eoc = new EpisodeOfCare();
|
||||
eoc.setStatus(EpisodeOfCare.EpisodeOfCareStatus.CANCELLED);
|
||||
assertNotMatched(eoc, criteria);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCommunicationRequestWithRefAndDate() {
|
||||
String criteria = "CommunicationRequest?requester=O1271,O1276&occurrence=ge2019-02-08T00:00:00-05:00&occurrence=le2019-02-09T00:00:00-05:00";
|
||||
CommunicationRequest cr = new CommunicationRequest();
|
||||
cr.getRequester().getAgent().setReference("Organization/O1276");
|
||||
cr.setOccurrence(new DateTimeType("2019-02-08T00:01:00-05:00"));
|
||||
assertMatched(cr, criteria);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testCommunicationRequestWithRef() {
|
||||
String criteria = "CommunicationRequest?requester=O1271,O1276";
|
||||
CommunicationRequest cr = new CommunicationRequest();
|
||||
cr.getRequester().getAgent().setReference("Organization/O1276");
|
||||
assertMatched(cr, criteria);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSystemWithNullValue() {
|
||||
String criteria = "Observation?code=17861-6";
|
||||
Observation observation = new Observation();
|
||||
CodeableConcept code = new CodeableConcept();
|
||||
observation.getCode().addCoding().setSystem("http://loinc.org");
|
||||
|
||||
assertNotMatched(observation, criteria);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullSystemNotNullValue() {
|
||||
String criteria = "Observation?code=17861-6";
|
||||
Observation observation = new Observation();
|
||||
CodeableConcept code = new CodeableConcept();
|
||||
observation.getCode().addCoding().setCode("look ma no system");
|
||||
|
||||
assertNotMatched(observation, criteria);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExternalReferenceMatches() {
|
||||
String goodReference = "http://example.com/base/Organization/FOO";
|
||||
String goodCriteria = "Patient?organization=" + UrlUtil.escapeUrlParam(goodReference);
|
||||
|
||||
String badReference1 = "http://example.com/bad/Organization/FOO";
|
||||
String badCriteria1 = "Patient?organization=" + UrlUtil.escapeUrlParam(badReference1);
|
||||
|
||||
String badReference2 = "http://example.org/base/Organization/FOO";
|
||||
String badCriteria2 = "Patient?organization=" + UrlUtil.escapeUrlParam(badReference2);
|
||||
|
||||
String badReference3 = "https://example.com/base/Organization/FOO";
|
||||
String badCriteria3 = "Patient?organization=" + UrlUtil.escapeUrlParam(badReference3);
|
||||
|
||||
String badReference4 = "http://example.com/base/Organization/GOO";
|
||||
String badCriteria4 = "Patient?organization=" + UrlUtil.escapeUrlParam(badReference4);
|
||||
|
||||
Set<String> urls = new HashSet<>();
|
||||
urls.add("http://example.com/base/");
|
||||
myModelConfig.setTreatBaseUrlsAsLocal(urls);
|
||||
|
||||
Patient patient = new Patient();
|
||||
patient.getManagingOrganization().setReference("Organization/FOO");
|
||||
|
||||
assertMatched(patient, goodCriteria);
|
||||
assertNotMatched(patient, badCriteria1);
|
||||
assertNotMatched(patient, badCriteria2);
|
||||
assertNotMatched(patient, badCriteria3);
|
||||
assertNotMatched(patient, badCriteria4);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLocationPositionNotSupported() {
|
||||
Location loc = new Location();
|
||||
double latitude = 30.0;
|
||||
double longitude = 40.0;
|
||||
Location.LocationPositionComponent position = new Location.LocationPositionComponent().setLatitude(latitude).setLongitude(longitude);
|
||||
loc.setPosition(position);
|
||||
double bigEnoughDistance = 100.0;
|
||||
String badCriteria =
|
||||
"Location?" +
|
||||
Location.SP_NEAR + "=" + latitude + ":" + longitude +
|
||||
"&" +
|
||||
Location.SP_NEAR_DISTANCE + "=" + bigEnoughDistance + "|http://unitsofmeasure.org|km";
|
||||
|
||||
assertUnsupported(loc, badCriteria);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
package ca.uhn.fhir.jpa.subscription.module.matcher;
|
||||
|
||||
import ca.uhn.fhir.jpa.subscription.match.matcher.matching.SubscriptionMatchingStrategy;
|
||||
import ca.uhn.fhir.jpa.subscription.match.matcher.matching.SubscriptionStrategyEvaluator;
|
||||
import ca.uhn.fhir.jpa.subscription.module.BaseSubscriptionDstu3Test;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.matchers.JUnitMatchers.containsString;
|
||||
|
||||
public class SubscriptionStrategyEvaluatorTest extends BaseSubscriptionDstu3Test {
|
||||
@Autowired
|
||||
SubscriptionStrategyEvaluator mySubscriptionStrategyEvaluator;
|
||||
|
||||
@Rule
|
||||
public ExpectedException exception = ExpectedException.none();
|
||||
|
||||
@Test
|
||||
public void testInMemory() {
|
||||
assertInMemory("Observation?");
|
||||
assertInMemory("QuestionnaireResponse?questionnaire=HomeAbsenceHospitalizationRecord,ARIncenterAbsRecord");
|
||||
assertInMemory("CommunicationRequest?occurrence==2018-10-17");
|
||||
assertInMemory("ProcedureRequest?intent=original-order");
|
||||
assertInMemory("MedicationRequest?intent=instance-order&category=outpatient&date==2018-10-19");
|
||||
assertInMemory("MedicationRequest?intent=plan&category=outpatient&status=suspended,entered-in-error,cancelled,stopped");
|
||||
assertDatabase("Observation?code=FR_Org1Blood2nd,FR_Org1Blood3rd,FR_Org%201BldCult,FR_Org2Blood2nd,FR_Org2Blood3rd,FR_Org%202BldCult,FR_Org3Blood2nd,FR_Org3Blood3rd,FR_Org3BldCult,FR_Org4Blood2nd,FR_Org4Blood3rd,FR_Org4BldCult,FR_Org5Blood2nd,FR_Org5Blood3rd,FR_Org%205BldCult,FR_Org6Blood2nd,FR_Org6Blood3rd,FR_Org6BldCult,FR_Org7Blood2nd,FR_Org7Blood3rd,FR_Org7BldCult,FR_Org8Blood2nd,FR_Org8Blood3rd,FR_Org8BldCult,FR_Org9Blood2nd,FR_Org9Blood3rd,FR_Org9BldCult,FR_Bld2ndCulture,FR_Bld3rdCulture,FR_Blood%20Culture,FR_Com1Bld3rd,FR_Com1BldCult,FR_Com2Bld2nd,FR_Com2Bld3rd,FR_Com2BldCult,FR_CultureBld2nd,FR_CultureBld3rd,FR_CultureBldCul,FR_GmStainBldCul,FR_GramStain2Bld,FR_GramStain3Bld,FR_GramStNegBac&context.type=IHD");
|
||||
assertInMemory("Procedure?category=Hemodialysis");
|
||||
assertInMemory("Procedure?code=HD_Standard&status=completed&location=Lab123");
|
||||
assertInMemory("Procedure?code=HD_Standard&status=completed");
|
||||
assertInMemory("QuestionnaireResponse?questionnaire=HomeAbsenceHospitalizationRecord,ARIncenterAbsRecord,FMCSWDepressionSymptomsScreener,FMCAKIComprehensiveSW,FMCSWIntensiveScreener,FMCESRDComprehensiveSW,FMCNutritionProgressNote,FMCAKIComprehensiveRN");
|
||||
assertInMemory("EpisodeOfCare?status=active");
|
||||
assertInMemory("Observation?code=111111111&_format=xml");
|
||||
assertInMemory("Observation?code=SNOMED-CT|123&_format=xml");
|
||||
|
||||
assertDatabase("Observation?code=17861-6&context.type=IHD");
|
||||
assertDatabase("Observation?context.type=IHD&code=17861-6");
|
||||
|
||||
exception.expect(InvalidRequestException.class);
|
||||
exception.expectMessage(containsString("Resource type Observation does not have a parameter with name: codeee"));
|
||||
assertInMemory("Observation?codeee=SNOMED-CT|123&_format=xml");
|
||||
}
|
||||
|
||||
private void assertDatabase(String theCriteria) {
|
||||
assertEquals(SubscriptionMatchingStrategy.DATABASE, mySubscriptionStrategyEvaluator.determineStrategy(theCriteria));
|
||||
}
|
||||
|
||||
private void assertInMemory(String theCriteria) {
|
||||
assertEquals(SubscriptionMatchingStrategy.IN_MEMORY, mySubscriptionStrategyEvaluator.determineStrategy(theCriteria));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,237 @@
|
|||
package ca.uhn.fhir.jpa.subscription.module.standalone;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.interceptor.api.HookParams;
|
||||
import ca.uhn.fhir.interceptor.api.IInterceptorService;
|
||||
import ca.uhn.fhir.interceptor.api.Pointcut;
|
||||
import ca.uhn.fhir.jpa.subscription.channel.api.ChannelConsumerOptions;
|
||||
import ca.uhn.fhir.jpa.subscription.channel.subscription.ISubscriptionDeliveryChannelNamer;
|
||||
import ca.uhn.fhir.jpa.subscription.channel.subscription.SubscriptionChannelFactory;
|
||||
import ca.uhn.fhir.jpa.subscription.match.registry.SubscriptionLoader;
|
||||
import ca.uhn.fhir.jpa.subscription.match.registry.SubscriptionRegistry;
|
||||
import ca.uhn.fhir.jpa.subscription.model.CanonicalSubscription;
|
||||
import ca.uhn.fhir.jpa.subscription.model.CanonicalSubscriptionChannelType;
|
||||
import ca.uhn.fhir.jpa.subscription.model.ResourceModifiedJsonMessage;
|
||||
import ca.uhn.fhir.jpa.subscription.model.ResourceModifiedMessage;
|
||||
import ca.uhn.fhir.jpa.subscription.module.BaseSubscriptionDstu3Test;
|
||||
import ca.uhn.fhir.jpa.subscription.module.config.MockFhirClientSubscriptionProvider;
|
||||
import ca.uhn.fhir.jpa.subscription.module.subscriber.SubscriptionMatchingSubscriberTest;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.annotation.Create;
|
||||
import ca.uhn.fhir.rest.annotation.ResourceParam;
|
||||
import ca.uhn.fhir.rest.annotation.Update;
|
||||
import ca.uhn.fhir.rest.api.Constants;
|
||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
import ca.uhn.fhir.rest.server.IResourceProvider;
|
||||
import ca.uhn.fhir.rest.server.RestfulServer;
|
||||
import ca.uhn.fhir.rest.server.SimpleBundleProvider;
|
||||
import ca.uhn.fhir.test.utilities.JettyUtil;
|
||||
import ca.uhn.test.concurrency.IPointcutLatch;
|
||||
import ca.uhn.test.concurrency.PointcutLatch;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
import org.hl7.fhir.dstu3.model.CodeableConcept;
|
||||
import org.hl7.fhir.dstu3.model.Coding;
|
||||
import org.hl7.fhir.dstu3.model.IdType;
|
||||
import org.hl7.fhir.dstu3.model.Observation;
|
||||
import org.hl7.fhir.dstu3.model.Subscription;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.messaging.MessageHandler;
|
||||
import org.springframework.messaging.SubscribableChannel;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class BaseBlockingQueueSubscribableChannelDstu3Test extends BaseSubscriptionDstu3Test {
|
||||
private static final Logger ourLog = LoggerFactory.getLogger(SubscriptionMatchingSubscriberTest.class);
|
||||
public static final ChannelConsumerOptions CONSUMER_OPTIONS = new ChannelConsumerOptions().setConcurrentConsumers(1);
|
||||
protected static ObservationListener ourObservationListener;
|
||||
|
||||
@Autowired
|
||||
FhirContext myFhirContext;
|
||||
|
||||
// Caused by: java.lang.IllegalStateException: Unable to register mock bean org.springframework.messaging.MessageHandler expected a single matching bean to replace but found [subscriptionActivatingSubscriber, subscriptionDeliveringEmailSubscriber, subscriptionDeliveringRestHookSubscriber, subscriptionMatchingSubscriber, subscriptionRegisteringSubscriber]
|
||||
|
||||
@Autowired
|
||||
@Qualifier("subscriptionActivatingSubscriber")
|
||||
MessageHandler mySubscriptionActivatingSubscriber;
|
||||
@Autowired
|
||||
@Qualifier("subscriptionRegisteringSubscriber")
|
||||
MessageHandler subscriptionRegisteringSubscriber;
|
||||
@Autowired
|
||||
@Qualifier("subscriptionMatchingSubscriber")
|
||||
MessageHandler subscriptionMatchingSubscriber;
|
||||
|
||||
@Autowired
|
||||
SubscriptionChannelFactory mySubscriptionChannelFactory;
|
||||
@Autowired
|
||||
IInterceptorService myInterceptorRegistry;
|
||||
@Autowired
|
||||
protected SubscriptionRegistry mySubscriptionRegistry;
|
||||
@Autowired
|
||||
private MockFhirClientSubscriptionProvider myMockFhirClientSubscriptionProvider;
|
||||
@Autowired
|
||||
private SubscriptionLoader mySubscriptionLoader;
|
||||
@Autowired
|
||||
private ISubscriptionDeliveryChannelNamer mySubscriptionDeliveryChannelNamer;
|
||||
|
||||
protected String myCode = "1000000050";
|
||||
|
||||
private static int ourListenerPort;
|
||||
private static RestfulServer ourListenerRestServer;
|
||||
private static Server ourListenerServer;
|
||||
protected static String ourListenerServerBase;
|
||||
protected static final List<Observation> ourCreatedObservations = Collections.synchronizedList(Lists.newArrayList());
|
||||
protected static final List<Observation> ourUpdatedObservations = Collections.synchronizedList(Lists.newArrayList());
|
||||
protected static final List<String> ourContentTypes = Collections.synchronizedList(new ArrayList<>());
|
||||
private static SubscribableChannel ourSubscribableChannel;
|
||||
protected final PointcutLatch mySubscriptionMatchingPost = new PointcutLatch(Pointcut.SUBSCRIPTION_AFTER_PERSISTED_RESOURCE_CHECKED);
|
||||
protected final PointcutLatch mySubscriptionActivatedPost = new PointcutLatch(Pointcut.SUBSCRIPTION_AFTER_ACTIVE_SUBSCRIPTION_REGISTERED);
|
||||
|
||||
@Before
|
||||
public void beforeReset() {
|
||||
ourCreatedObservations.clear();
|
||||
ourUpdatedObservations.clear();
|
||||
ourContentTypes.clear();
|
||||
CanonicalSubscription canonicalSubscription = new CanonicalSubscription();
|
||||
canonicalSubscription.setIdElement(new IdDt("test"));
|
||||
canonicalSubscription.setChannelType(CanonicalSubscriptionChannelType.RESTHOOK);
|
||||
mySubscriptionRegistry.unregisterAllSubscriptions();
|
||||
ourSubscribableChannel = mySubscriptionChannelFactory.newDeliveryReceivingChannel(mySubscriptionDeliveryChannelNamer.nameFromSubscription(canonicalSubscription), CONSUMER_OPTIONS);
|
||||
ourSubscribableChannel.subscribe(mySubscriptionActivatingSubscriber);
|
||||
ourSubscribableChannel.subscribe(subscriptionMatchingSubscriber);
|
||||
ourSubscribableChannel.subscribe(subscriptionRegisteringSubscriber);
|
||||
myInterceptorRegistry.registerAnonymousInterceptor(Pointcut.SUBSCRIPTION_AFTER_PERSISTED_RESOURCE_CHECKED, mySubscriptionMatchingPost);
|
||||
myInterceptorRegistry.registerAnonymousInterceptor(Pointcut.SUBSCRIPTION_AFTER_ACTIVE_SUBSCRIPTION_REGISTERED, mySubscriptionActivatedPost);
|
||||
}
|
||||
|
||||
@After
|
||||
public void cleanup() {
|
||||
myInterceptorRegistry.unregisterAllInterceptors();
|
||||
mySubscriptionMatchingPost.clear();
|
||||
mySubscriptionActivatedPost.clear();
|
||||
ourObservationListener.clear();
|
||||
super.clearRegistry();
|
||||
}
|
||||
|
||||
public <T extends IBaseResource> T sendResource(T theResource) throws InterruptedException {
|
||||
ResourceModifiedMessage msg = new ResourceModifiedMessage(myFhirContext, theResource, ResourceModifiedMessage.OperationTypeEnum.CREATE);
|
||||
ResourceModifiedJsonMessage message = new ResourceModifiedJsonMessage(msg);
|
||||
mySubscriptionMatchingPost.setExpectedCount(1);
|
||||
ourSubscribableChannel.send(message);
|
||||
mySubscriptionMatchingPost.awaitExpected();
|
||||
return theResource;
|
||||
}
|
||||
|
||||
protected void initSubscriptionLoader(List<Subscription> subscriptions, String uuid) throws InterruptedException {
|
||||
myMockFhirClientSubscriptionProvider.setBundleProvider(new SimpleBundleProvider(new ArrayList<>(subscriptions), uuid));
|
||||
mySubscriptionLoader.doSyncSubscriptionsForUnitTest();
|
||||
}
|
||||
|
||||
protected Subscription sendSubscription(String theCriteria, String thePayload, String theEndpoint) throws InterruptedException {
|
||||
Subscription subscription = makeActiveSubscription(theCriteria, thePayload, theEndpoint);
|
||||
mySubscriptionActivatedPost.setExpectedCount(1);
|
||||
Subscription retval = sendResource(subscription);
|
||||
mySubscriptionActivatedPost.awaitExpected();
|
||||
return retval;
|
||||
}
|
||||
|
||||
protected Observation sendObservation(String code, String system) throws InterruptedException {
|
||||
Observation observation = new Observation();
|
||||
IdType id = new IdType("Observation", nextId());
|
||||
observation.setId(id);
|
||||
|
||||
CodeableConcept codeableConcept = new CodeableConcept();
|
||||
observation.setCode(codeableConcept);
|
||||
Coding coding = codeableConcept.addCoding();
|
||||
coding.setCode(code);
|
||||
coding.setSystem(system);
|
||||
|
||||
observation.setStatus(Observation.ObservationStatus.FINAL);
|
||||
|
||||
return sendResource(observation);
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void startListenerServer() throws Exception {
|
||||
ourListenerRestServer = new RestfulServer(FhirContext.forDstu3());
|
||||
|
||||
ourObservationListener = new ObservationListener();
|
||||
ourListenerRestServer.setResourceProviders(ourObservationListener);
|
||||
|
||||
ourListenerServer = new Server(0);
|
||||
|
||||
ServletContextHandler proxyHandler = new ServletContextHandler();
|
||||
proxyHandler.setContextPath("/");
|
||||
|
||||
ServletHolder servletHolder = new ServletHolder();
|
||||
servletHolder.setServlet(ourListenerRestServer);
|
||||
proxyHandler.addServlet(servletHolder, "/fhir/context/*");
|
||||
|
||||
ourListenerServer.setHandler(proxyHandler);
|
||||
JettyUtil.startServer(ourListenerServer);
|
||||
ourListenerPort = JettyUtil.getPortForStartedServer(ourListenerServer);
|
||||
ourListenerServerBase = "http://localhost:" + ourListenerPort + "/fhir/context";
|
||||
FhirContext context = ourListenerRestServer.getFhirContext();
|
||||
//Preload structure definitions so the load doesn't happen during the test (first load can be a little slow)
|
||||
context.getValidationSupport().fetchAllStructureDefinitions();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void stopListenerServer() throws Exception {
|
||||
JettyUtil.closeServer(ourListenerServer);
|
||||
}
|
||||
|
||||
public static class ObservationListener implements IResourceProvider, IPointcutLatch {
|
||||
|
||||
private final PointcutLatch updateLatch = new PointcutLatch("Observation Update");
|
||||
|
||||
@Create
|
||||
public MethodOutcome create(@ResourceParam Observation theObservation, HttpServletRequest theRequest) {
|
||||
ourLog.info("Received Listener Create");
|
||||
ourContentTypes.add(theRequest.getHeader(ca.uhn.fhir.rest.api.Constants.HEADER_CONTENT_TYPE).replaceAll(";.*", ""));
|
||||
ourCreatedObservations.add(theObservation);
|
||||
return new MethodOutcome(new IdType("Observation/1"), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends IBaseResource> getResourceType() {
|
||||
return Observation.class;
|
||||
}
|
||||
|
||||
@Update
|
||||
public MethodOutcome update(@ResourceParam Observation theObservation, HttpServletRequest theRequest) {
|
||||
ourContentTypes.add(theRequest.getHeader(Constants.HEADER_CONTENT_TYPE).replaceAll(";.*", ""));
|
||||
ourUpdatedObservations.add(theObservation);
|
||||
updateLatch.invoke(null, new HookParams().add(Observation.class, theObservation));
|
||||
ourLog.info("Received Listener Update (now have {} updates)", ourUpdatedObservations.size());
|
||||
return new MethodOutcome(new IdType("Observation/1"), false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExpectedCount(int count) {
|
||||
updateLatch.setExpectedCount(count);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HookParams> awaitExpected() throws InterruptedException {
|
||||
return updateLatch.awaitExpected();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() { updateLatch.clear();}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,119 @@
|
|||
package ca.uhn.fhir.jpa.subscription.module.subscriber;
|
||||
|
||||
import ca.uhn.fhir.jpa.subscription.module.standalone.BaseBlockingQueueSubscribableChannelDstu3Test;
|
||||
import ca.uhn.fhir.rest.api.Constants;
|
||||
import org.hl7.fhir.dstu3.model.CodeableConcept;
|
||||
import org.hl7.fhir.dstu3.model.Coding;
|
||||
import org.hl7.fhir.dstu3.model.IdType;
|
||||
import org.hl7.fhir.dstu3.model.Observation;
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* Tests copied from jpa.subscription.resthook.RestHookTestDstu3Test
|
||||
*/
|
||||
public class SubscriptionCheckingSubscriberTest extends BaseBlockingQueueSubscribableChannelDstu3Test {
|
||||
private static final Logger ourLog = LoggerFactory.getLogger(SubscriptionCheckingSubscriberTest.class);
|
||||
|
||||
@Test
|
||||
public void testRestHookSubscriptionApplicationFhirJson() throws Exception {
|
||||
String payload = "application/fhir+json";
|
||||
|
||||
String code = "1000000050";
|
||||
String criteria1 = "Observation?code=SNOMED-CT|" + code + "&_format=xml";
|
||||
String criteria2 = "Observation?code=SNOMED-CT|" + code + "111&_format=xml";
|
||||
|
||||
sendSubscription(criteria1, payload, ourListenerServerBase);
|
||||
sendSubscription(criteria2, payload, ourListenerServerBase);
|
||||
|
||||
assertEquals(2, mySubscriptionRegistry.size());
|
||||
|
||||
ourObservationListener.setExpectedCount(1);
|
||||
sendObservation(code, "SNOMED-CT");
|
||||
ourObservationListener.awaitExpected();
|
||||
|
||||
assertEquals(1, ourContentTypes.size());
|
||||
assertEquals(Constants.CT_FHIR_JSON_NEW, ourContentTypes.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRestHookSubscriptionApplicationXmlJson() throws Exception {
|
||||
String payload = "application/fhir+xml";
|
||||
|
||||
String code = "1000000050";
|
||||
String criteria1 = "Observation?code=SNOMED-CT|" + code + "&_format=xml";
|
||||
String criteria2 = "Observation?code=SNOMED-CT|" + code + "111&_format=xml";
|
||||
|
||||
sendSubscription(criteria1, payload, ourListenerServerBase);
|
||||
sendSubscription(criteria2, payload, ourListenerServerBase);
|
||||
|
||||
assertEquals(2, mySubscriptionRegistry.size());
|
||||
|
||||
ourObservationListener.setExpectedCount(1);
|
||||
sendObservation(code, "SNOMED-CT");
|
||||
ourObservationListener.awaitExpected();
|
||||
|
||||
assertEquals(1, ourContentTypes.size());
|
||||
assertEquals(Constants.CT_FHIR_XML_NEW, ourContentTypes.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRestHookSubscriptionWithoutPayload() throws Exception {
|
||||
String payload = "";
|
||||
|
||||
String code = "1000000050";
|
||||
String criteria1 = "Observation?code=SNOMED-CT|" + code;
|
||||
String criteria2 = "Observation?code=SNOMED-CT|" + code + "111";
|
||||
|
||||
sendSubscription(criteria1, payload, ourListenerServerBase);
|
||||
sendSubscription(criteria2, payload, ourListenerServerBase);
|
||||
|
||||
assertEquals(2, mySubscriptionRegistry.size());
|
||||
|
||||
ourObservationListener.setExpectedCount(0);
|
||||
sendObservation(code, "SNOMED-CT");
|
||||
ourObservationListener.clear();
|
||||
|
||||
assertEquals(0, ourContentTypes.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReferenceWithDisplayOnly() throws Exception {
|
||||
String payload = "application/fhir+json";
|
||||
|
||||
String code = "1000000050";
|
||||
String criteria1 = "Observation?code=SNOMED-CT|" + code + "&_format=xml";
|
||||
String criteria2 = "Observation?code=SNOMED-CT|" + code + "111&_format=xml";
|
||||
|
||||
sendSubscription(criteria1, payload, ourListenerServerBase);
|
||||
sendSubscription(criteria2, payload, ourListenerServerBase);
|
||||
|
||||
assertEquals(2, mySubscriptionRegistry.size());
|
||||
|
||||
ourObservationListener.setExpectedCount(1);
|
||||
Observation observation = new Observation();
|
||||
IdType id = new IdType("Observation", nextId());
|
||||
observation.setId(id);
|
||||
|
||||
// Reference has display only!
|
||||
observation.getSubject().setDisplay("Mr Jones");
|
||||
|
||||
CodeableConcept codeableConcept = new CodeableConcept();
|
||||
observation.setCode(codeableConcept);
|
||||
Coding coding = codeableConcept.addCoding();
|
||||
coding.setCode(code);
|
||||
coding.setSystem("SNOMED-CT");
|
||||
|
||||
observation.setStatus(Observation.ObservationStatus.FINAL);
|
||||
|
||||
sendResource(observation);
|
||||
ourObservationListener.awaitExpected();
|
||||
|
||||
assertEquals(1, ourContentTypes.size());
|
||||
assertEquals(Constants.CT_FHIR_JSON_NEW, ourContentTypes.get(0));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
package ca.uhn.fhir.jpa.subscription.module.subscriber;
|
||||
|
||||
import ca.uhn.fhir.jpa.subscription.module.standalone.BaseBlockingQueueSubscribableChannelDstu3Test;
|
||||
import ca.uhn.fhir.rest.api.Constants;
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* Tests copied from jpa.subscription.resthook.RestHookTestDstu3Test
|
||||
*/
|
||||
public class SubscriptionMatchingSubscriberTest extends BaseBlockingQueueSubscribableChannelDstu3Test {
|
||||
private static final Logger ourLog = LoggerFactory.getLogger(SubscriptionMatchingSubscriberTest.class);
|
||||
|
||||
@Test
|
||||
public void testRestHookSubscriptionApplicationFhirJson() throws Exception {
|
||||
String payload = "application/fhir+json";
|
||||
|
||||
String code = "1000000050";
|
||||
String criteria1 = "Observation?code=SNOMED-CT|" + code + "&_format=xml";
|
||||
String criteria2 = "Observation?code=SNOMED-CT|" + code + "111&_format=xml";
|
||||
|
||||
sendSubscription(criteria1, payload, ourListenerServerBase);
|
||||
sendSubscription(criteria2, payload, ourListenerServerBase);
|
||||
|
||||
assertEquals(2, mySubscriptionRegistry.size());
|
||||
|
||||
ourObservationListener.setExpectedCount(1);
|
||||
sendObservation(code, "SNOMED-CT");
|
||||
ourObservationListener.awaitExpected();
|
||||
|
||||
assertEquals(1, ourContentTypes.size());
|
||||
assertEquals(Constants.CT_FHIR_JSON_NEW, ourContentTypes.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRestHookSubscriptionApplicationXmlJson() throws Exception {
|
||||
String payload = "application/fhir+xml";
|
||||
|
||||
String code = "1000000050";
|
||||
String criteria1 = "Observation?code=SNOMED-CT|" + code + "&_format=xml";
|
||||
String criteria2 = "Observation?code=SNOMED-CT|" + code + "111&_format=xml";
|
||||
|
||||
sendSubscription(criteria1, payload, ourListenerServerBase);
|
||||
sendSubscription(criteria2, payload, ourListenerServerBase);
|
||||
|
||||
assertEquals(2, mySubscriptionRegistry.size());
|
||||
|
||||
ourObservationListener.setExpectedCount(1);
|
||||
sendObservation(code, "SNOMED-CT");
|
||||
ourObservationListener.awaitExpected();
|
||||
|
||||
assertEquals(1, ourContentTypes.size());
|
||||
assertEquals(Constants.CT_FHIR_XML_NEW, ourContentTypes.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRestHookSubscriptionWithoutPayload() throws Exception {
|
||||
String payload = "";
|
||||
|
||||
String code = "1000000050";
|
||||
String criteria1 = "Observation?code=SNOMED-CT|" + code;
|
||||
String criteria2 = "Observation?code=SNOMED-CT|" + code + "111";
|
||||
|
||||
sendSubscription(criteria1, payload, ourListenerServerBase);
|
||||
sendSubscription(criteria2, payload, ourListenerServerBase);
|
||||
|
||||
assertEquals(2, mySubscriptionRegistry.size());
|
||||
|
||||
ourObservationListener.setExpectedCount(0);
|
||||
sendObservation(code, "SNOMED-CT");
|
||||
ourObservationListener.clear();
|
||||
|
||||
assertEquals(0, ourContentTypes.size());
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue