Fix subscriptions
This commit is contained in:
parent
be5c5ebecd
commit
04f16294aa
|
@ -1077,7 +1077,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
RuntimeResourceDefinition resourceDef = getContext().getResourceDefinition(theResourceType);
|
||||
|
||||
SearchParameterMap paramMap = translateMatchUrl(this, myContext, theMatchUrl, resourceDef);
|
||||
paramMap.setPersistResults(false);
|
||||
paramMap.setLoadSynchronous(true);
|
||||
|
||||
if (paramMap.isEmpty() && paramMap.getLastUpdated() == null) {
|
||||
throw new InvalidRequestException("Invalid match URL[" + theMatchUrl + "] - URL has no search parameters");
|
||||
|
|
|
@ -20,21 +20,26 @@ package ca.uhn.fhir.jpa.interceptor;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
|
||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||
import ca.uhn.fhir.jpa.dao.*;
|
||||
import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao;
|
||||
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
|
||||
import ca.uhn.fhir.jpa.dao.SearchParameterMap;
|
||||
import ca.uhn.fhir.jpa.provider.ServletSubRequestDetails;
|
||||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
import ca.uhn.fhir.rest.server.interceptor.ServerOperationInterceptorAdapter;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.concurrent.*;
|
||||
|
||||
public abstract class BaseRestHookSubscriptionInterceptor extends ServerOperationInterceptorAdapter {
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseRestHookSubscriptionInterceptor.class);
|
||||
|
||||
protected static final Integer MAX_SUBSCRIPTION_RESULTS = 10000;
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseRestHookSubscriptionInterceptor.class);
|
||||
protected ExecutorService myExecutor;
|
||||
private int myExecutorThreadCount = 1;
|
||||
|
||||
protected abstract IFhirResourceDao<?> getSubscriptionDao();
|
||||
|
||||
|
@ -47,6 +52,18 @@ public abstract class BaseRestHookSubscriptionInterceptor extends ServerOperatio
|
|||
}
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void postConstruct() {
|
||||
try {
|
||||
myExecutor = new ThreadPoolExecutor(myExecutorThreadCount, myExecutorThreadCount,
|
||||
0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(1000));
|
||||
|
||||
myExecutor = Executors.newFixedThreadPool(myExecutorThreadCount);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Unable to get DAO from PROXY");
|
||||
}
|
||||
}
|
||||
|
||||
private IBundleProvider executeSubscriptionCriteria(String theCriteria, IIdType idType) {
|
||||
String criteria = theCriteria;
|
||||
|
||||
|
@ -64,7 +81,7 @@ public abstract class BaseRestHookSubscriptionInterceptor extends ServerOperatio
|
|||
|
||||
/**
|
||||
* Search based on a query criteria
|
||||
*
|
||||
*
|
||||
* @param theCheckOnly Is this just a test that the search works
|
||||
*/
|
||||
protected IBundleProvider getBundleProvider(String theCriteria, boolean theCheckOnly) {
|
||||
|
@ -75,13 +92,13 @@ public abstract class BaseRestHookSubscriptionInterceptor extends ServerOperatio
|
|||
req.setSubRequest(true);
|
||||
|
||||
IFhirResourceDao<? extends IBaseResource> responseDao = getSubscriptionDao().getDao(responseResourceDef.getImplementingClass());
|
||||
|
||||
|
||||
if (theCheckOnly) {
|
||||
responseCriteriaUrl.setLoadSynchronousUpTo(1);
|
||||
} else {
|
||||
responseCriteriaUrl.setLoadSynchronousUpTo(MAX_SUBSCRIPTION_RESULTS);
|
||||
}
|
||||
|
||||
|
||||
IBundleProvider responseResults = responseDao.search(responseCriteriaUrl, req);
|
||||
return responseResults;
|
||||
}
|
||||
|
|
|
@ -20,25 +20,6 @@ package ca.uhn.fhir.jpa.interceptor;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.http.client.methods.*;
|
||||
import org.apache.http.entity.ContentType;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
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;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
|
||||
import ca.uhn.fhir.jpa.dao.SearchParameterMap;
|
||||
|
@ -49,24 +30,36 @@ import ca.uhn.fhir.model.dstu2.resource.Subscription;
|
|||
import ca.uhn.fhir.model.dstu2.valueset.SubscriptionChannelTypeEnum;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.SubscriptionStatusEnum;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.api.*;
|
||||
import ca.uhn.fhir.rest.api.Constants;
|
||||
import ca.uhn.fhir.rest.api.EncodingEnum;
|
||||
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
|
||||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
import ca.uhn.fhir.rest.param.TokenParam;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.client.methods.HttpPut;
|
||||
import org.apache.http.client.methods.HttpUriRequest;
|
||||
import org.apache.http.entity.ContentType;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
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;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class RestHookSubscriptionDstu2Interceptor extends BaseRestHookSubscriptionInterceptor {
|
||||
|
||||
private static volatile ExecutorService executor;
|
||||
private final static int MAX_THREADS = 1;
|
||||
|
||||
private static final Logger ourLog = LoggerFactory.getLogger(RestHookSubscriptionDstu2Interceptor.class);
|
||||
|
||||
private final List<Subscription> myRestHookSubscriptions = new ArrayList<>();
|
||||
@Autowired
|
||||
private FhirContext myFhirContext;
|
||||
|
||||
private boolean myNotifyOnDelete = false;
|
||||
|
||||
private final List<Subscription> myRestHookSubscriptions = new ArrayList<Subscription>();
|
||||
@Autowired
|
||||
@Qualifier("mySubscriptionDaoDstu2")
|
||||
private IFhirResourceDao<Subscription> mySubscriptionDao;
|
||||
|
@ -117,14 +110,13 @@ public class RestHookSubscriptionDstu2Interceptor extends BaseRestHookSubscripti
|
|||
ourLog.info("Found match: queueing rest-hook notification for resource: {}", next.getIdElement());
|
||||
HttpUriRequest request = createRequest(subscription, next, theOperation);
|
||||
if (request != null) {
|
||||
executor.submit(new HttpRequestDstu2Job(request, subscription));
|
||||
myExecutor.submit(new HttpRequestDstu2Job(request, subscription));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Creates an HTTP Post for a subscription
|
||||
*/
|
||||
|
@ -242,6 +234,10 @@ public class RestHookSubscriptionDstu2Interceptor extends BaseRestHookSubscripti
|
|||
return mySubscriptionDao;
|
||||
}
|
||||
|
||||
public void setSubscriptionDao(IFhirResourceDao<Subscription> theSubscriptionDao) {
|
||||
mySubscriptionDao = theSubscriptionDao;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void incomingRequestPreHandled(RestOperationTypeEnum theOperation, ActionRequestDetails theDetails) {
|
||||
// check the subscription criteria to see if its valid before creating or updating a subscription
|
||||
|
@ -286,6 +282,10 @@ public class RestHookSubscriptionDstu2Interceptor extends BaseRestHookSubscripti
|
|||
return myNotifyOnDelete;
|
||||
}
|
||||
|
||||
public void setNotifyOnDelete(boolean notifyOnDelete) {
|
||||
this.myNotifyOnDelete = notifyOnDelete;
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses may override
|
||||
*/
|
||||
|
@ -293,15 +293,6 @@ public class RestHookSubscriptionDstu2Interceptor extends BaseRestHookSubscripti
|
|||
return theCriteria;
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void postConstruct() {
|
||||
try {
|
||||
executor = Executors.newFixedThreadPool(MAX_THREADS);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Unable to get DAO from PROXY");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove subscription from cache
|
||||
*
|
||||
|
@ -330,8 +321,8 @@ public class RestHookSubscriptionDstu2Interceptor extends BaseRestHookSubscripti
|
|||
if (theResource instanceof Subscription) {
|
||||
Subscription subscription = (Subscription) theResource;
|
||||
if (subscription.getChannel() != null
|
||||
&& subscription.getChannel().getTypeElement().getValueAsEnum() == SubscriptionChannelTypeEnum.REST_HOOK
|
||||
&& subscription.getStatusElement().getValueAsEnum() == SubscriptionStatusEnum.REQUESTED) {
|
||||
&& subscription.getChannel().getTypeElement().getValueAsEnum() == SubscriptionChannelTypeEnum.REST_HOOK
|
||||
&& subscription.getStatusElement().getValueAsEnum() == SubscriptionStatusEnum.REQUESTED) {
|
||||
removeLocalSubscription(subscription.getIdElement().getIdPart());
|
||||
subscription.setStatus(SubscriptionStatusEnum.ACTIVE);
|
||||
myRestHookSubscriptions.add(subscription);
|
||||
|
@ -345,16 +336,13 @@ public class RestHookSubscriptionDstu2Interceptor extends BaseRestHookSubscripti
|
|||
/**
|
||||
* Check subscriptions to see if there is a matching subscription when there is delete
|
||||
*
|
||||
* @param theRequest
|
||||
* A bean containing details about the request that is about to be processed, including details such as the
|
||||
* resource type and logical ID (if any) and other FHIR-specific aspects of the request which have been
|
||||
* pulled out of the {@link HttpServletRequest servlet request}.
|
||||
* @param theRequest
|
||||
* The incoming request
|
||||
* @param theResource
|
||||
* The response. Note that interceptors may choose to provide a response (i.e. by calling
|
||||
* {@link HttpServletResponse#getWriter()}) but in that case it is important to return <code>false</code>
|
||||
* to indicate that the server itself should not also provide a response.
|
||||
* @param theRequest A bean containing details about the request that is about to be processed, including details such as the
|
||||
* resource type and logical ID (if any) and other FHIR-specific aspects of the request which have been
|
||||
* pulled out of the {@link HttpServletRequest servlet request}.
|
||||
* @param theRequest The incoming request
|
||||
* @param theResource The response. Note that interceptors may choose to provide a response (i.e. by calling
|
||||
* {@link HttpServletResponse#getWriter()}) but in that case it is important to return <code>false</code>
|
||||
* to indicate that the server itself should not also provide a response.
|
||||
*/
|
||||
@Override
|
||||
public void resourceDeleted(RequestDetails theRequest, IBaseResource theResource) {
|
||||
|
@ -401,12 +389,4 @@ public class RestHookSubscriptionDstu2Interceptor extends BaseRestHookSubscripti
|
|||
myFhirContext = theFhirContext;
|
||||
}
|
||||
|
||||
public void setNotifyOnDelete(boolean notifyOnDelete) {
|
||||
this.myNotifyOnDelete = notifyOnDelete;
|
||||
}
|
||||
|
||||
public void setSubscriptionDao(IFhirResourceDao<Subscription> theSubscriptionDao) {
|
||||
mySubscriptionDao = theSubscriptionDao;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package ca.uhn.fhir.jpa.interceptor;
|
||||
|
||||
/*-
|
||||
|
@ -21,47 +20,42 @@ package ca.uhn.fhir.jpa.interceptor;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.http.client.methods.*;
|
||||
import org.apache.http.entity.ContentType;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.hl7.fhir.dstu3.model.Subscription;
|
||||
import org.hl7.fhir.instance.model.api.*;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
|
||||
import ca.uhn.fhir.jpa.dao.SearchParameterMap;
|
||||
import ca.uhn.fhir.jpa.provider.ServletSubRequestDetails;
|
||||
import ca.uhn.fhir.jpa.thread.HttpRequestDstu3Job;
|
||||
import ca.uhn.fhir.rest.api.*;
|
||||
import ca.uhn.fhir.rest.api.Constants;
|
||||
import ca.uhn.fhir.rest.api.EncodingEnum;
|
||||
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
|
||||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
import ca.uhn.fhir.rest.param.TokenParam;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.client.methods.HttpPut;
|
||||
import org.apache.http.client.methods.HttpUriRequest;
|
||||
import org.apache.http.entity.ContentType;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.hl7.fhir.dstu3.model.Subscription;
|
||||
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.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class RestHookSubscriptionDstu3Interceptor extends BaseRestHookSubscriptionInterceptor {
|
||||
|
||||
private static volatile ExecutorService executor;
|
||||
|
||||
private final static int MAX_THREADS = 1;
|
||||
private static final Logger ourLog = LoggerFactory.getLogger(RestHookSubscriptionDstu3Interceptor.class);
|
||||
|
||||
private final List<Subscription> myRestHookSubscriptions = new ArrayList<Subscription>();
|
||||
@Autowired
|
||||
private FhirContext myFhirContext;
|
||||
|
||||
private final List<Subscription> myRestHookSubscriptions = new ArrayList<Subscription>();
|
||||
|
||||
@Autowired
|
||||
@Qualifier("mySubscriptionDaoDstu3")
|
||||
private IFhirResourceDao<Subscription> mySubscriptionDao;
|
||||
|
@ -78,7 +72,7 @@ public class RestHookSubscriptionDstu3Interceptor extends BaseRestHookSubscripti
|
|||
private void checkSubscriptions(IIdType idType, String resourceType, RestOperationTypeEnum theOperation) {
|
||||
//avoid a ConcurrentModificationException by copying to an array
|
||||
for (Object object : myRestHookSubscriptions.toArray()) {
|
||||
//for (Subscription subscription : myRestHookSubscriptions) {
|
||||
//for (Subscription subscription : myRestHookSubscriptions) {
|
||||
if (object == null) {
|
||||
continue;
|
||||
}
|
||||
|
@ -114,7 +108,7 @@ public class RestHookSubscriptionDstu3Interceptor extends BaseRestHookSubscripti
|
|||
ourLog.info("Found match: queueing rest-hook notification for resource: {}", next.getIdElement());
|
||||
HttpUriRequest request = createRequest(subscription, next, theOperation);
|
||||
if (request != null) {
|
||||
executor.submit(new HttpRequestDstu3Job(request, subscription));
|
||||
myExecutor.submit(new HttpRequestDstu3Job(request, subscription));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -230,6 +224,10 @@ public class RestHookSubscriptionDstu3Interceptor extends BaseRestHookSubscripti
|
|||
return mySubscriptionDao;
|
||||
}
|
||||
|
||||
public void setSubscriptionDao(IFhirResourceDao<Subscription> theSubscriptionDao) {
|
||||
mySubscriptionDao = theSubscriptionDao;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void incomingRequestPreHandled(RestOperationTypeEnum theOperation, ActionRequestDetails theDetails) {
|
||||
// check the subscription criteria to see if its valid before creating or updating a subscription
|
||||
|
@ -274,6 +272,10 @@ public class RestHookSubscriptionDstu3Interceptor extends BaseRestHookSubscripti
|
|||
return notifyOnDelete;
|
||||
}
|
||||
|
||||
public void setNotifyOnDelete(boolean notifyOnDelete) {
|
||||
this.notifyOnDelete = notifyOnDelete;
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses may override
|
||||
*/
|
||||
|
@ -281,15 +283,6 @@ public class RestHookSubscriptionDstu3Interceptor extends BaseRestHookSubscripti
|
|||
return theCriteria;
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void postConstruct() {
|
||||
try {
|
||||
executor = Executors.newFixedThreadPool(MAX_THREADS);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Unable to get DAO from PROXY");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove subscription from cache
|
||||
*
|
||||
|
@ -318,8 +311,8 @@ public class RestHookSubscriptionDstu3Interceptor extends BaseRestHookSubscripti
|
|||
if (theResource instanceof Subscription) {
|
||||
Subscription subscription = (Subscription) theResource;
|
||||
if (subscription.getChannel() != null
|
||||
&& subscription.getChannel().getType() == Subscription.SubscriptionChannelType.RESTHOOK
|
||||
&& subscription.getStatus() == Subscription.SubscriptionStatus.REQUESTED) {
|
||||
&& subscription.getChannel().getType() == Subscription.SubscriptionChannelType.RESTHOOK
|
||||
&& subscription.getStatus() == Subscription.SubscriptionStatus.REQUESTED) {
|
||||
removeLocalSubscription(subscription.getIdElement().getIdPart());
|
||||
subscription.setStatus(Subscription.SubscriptionStatus.ACTIVE);
|
||||
myRestHookSubscriptions.add(subscription);
|
||||
|
@ -333,16 +326,13 @@ public class RestHookSubscriptionDstu3Interceptor extends BaseRestHookSubscripti
|
|||
/**
|
||||
* Check subscriptions to see if there is a matching subscription when there is a delete
|
||||
*
|
||||
* @param theRequest
|
||||
* A bean containing details about the request that is about to be processed, including details such as the
|
||||
* resource type and logical ID (if any) and other FHIR-specific aspects of the request which have been
|
||||
* pulled out of the {@link HttpServletRequest servlet request}.
|
||||
* @param theRequest
|
||||
* The incoming request
|
||||
* @param theResource
|
||||
* The response. Note that interceptors may choose to provide a response (i.e. by calling
|
||||
* {@link HttpServletResponse#getWriter()}) but in that case it is important to return <code>false</code>
|
||||
* to indicate that the server itself should not also provide a response.
|
||||
* @param theRequest A bean containing details about the request that is about to be processed, including details such as the
|
||||
* resource type and logical ID (if any) and other FHIR-specific aspects of the request which have been
|
||||
* pulled out of the {@link HttpServletRequest servlet request}.
|
||||
* @param theRequest The incoming request
|
||||
* @param theResource The response. Note that interceptors may choose to provide a response (i.e. by calling
|
||||
* {@link HttpServletResponse#getWriter()}) but in that case it is important to return <code>false</code>
|
||||
* to indicate that the server itself should not also provide a response.
|
||||
*/
|
||||
@Override
|
||||
public void resourceDeleted(RequestDetails theRequest, IBaseResource theResource) {
|
||||
|
@ -389,12 +379,4 @@ public class RestHookSubscriptionDstu3Interceptor extends BaseRestHookSubscripti
|
|||
myFhirContext = theFhirContext;
|
||||
}
|
||||
|
||||
public void setNotifyOnDelete(boolean notifyOnDelete) {
|
||||
this.notifyOnDelete = notifyOnDelete;
|
||||
}
|
||||
|
||||
public void setSubscriptionDao(IFhirResourceDao<Subscription> theSubscriptionDao) {
|
||||
mySubscriptionDao = theSubscriptionDao;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package ca.uhn.fhir.jpa.interceptor.r4;
|
||||
|
||||
/*-
|
||||
|
@ -21,48 +20,43 @@ package ca.uhn.fhir.jpa.interceptor.r4;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.http.client.methods.*;
|
||||
import org.apache.http.entity.ContentType;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.hl7.fhir.instance.model.api.*;
|
||||
import org.hl7.fhir.r4.model.Subscription;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
|
||||
import ca.uhn.fhir.jpa.dao.SearchParameterMap;
|
||||
import ca.uhn.fhir.jpa.interceptor.BaseRestHookSubscriptionInterceptor;
|
||||
import ca.uhn.fhir.jpa.provider.ServletSubRequestDetails;
|
||||
import ca.uhn.fhir.jpa.thread.HttpRequestR4Job;
|
||||
import ca.uhn.fhir.rest.api.*;
|
||||
import ca.uhn.fhir.rest.api.Constants;
|
||||
import ca.uhn.fhir.rest.api.EncodingEnum;
|
||||
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
|
||||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
import ca.uhn.fhir.rest.param.TokenParam;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.client.methods.HttpPut;
|
||||
import org.apache.http.client.methods.HttpUriRequest;
|
||||
import org.apache.http.entity.ContentType;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
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.hl7.fhir.r4.model.Subscription;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class RestHookSubscriptionR4Interceptor extends BaseRestHookSubscriptionInterceptor {
|
||||
|
||||
private static volatile ExecutorService executor;
|
||||
|
||||
private final static int MAX_THREADS = 1;
|
||||
private static final Logger ourLog = LoggerFactory.getLogger(RestHookSubscriptionR4Interceptor.class);
|
||||
|
||||
private final List<Subscription> myRestHookSubscriptions = new ArrayList<Subscription>();
|
||||
@Autowired
|
||||
private FhirContext myFhirContext;
|
||||
|
||||
private final List<Subscription> myRestHookSubscriptions = new ArrayList<Subscription>();
|
||||
|
||||
@Autowired
|
||||
@Qualifier("mySubscriptionDaoR4")
|
||||
private IFhirResourceDao<Subscription> mySubscriptionDao;
|
||||
|
@ -109,7 +103,7 @@ public class RestHookSubscriptionR4Interceptor extends BaseRestHookSubscriptionI
|
|||
ourLog.info("Found match: queueing rest-hook notification for resource: {}", next.getIdElement());
|
||||
HttpUriRequest request = createRequest(subscription, next, theOperation);
|
||||
if (request != null) {
|
||||
executor.submit(new HttpRequestR4Job(request, subscription));
|
||||
myExecutor.submit(new HttpRequestR4Job(request, subscription));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -225,6 +219,10 @@ public class RestHookSubscriptionR4Interceptor extends BaseRestHookSubscriptionI
|
|||
return mySubscriptionDao;
|
||||
}
|
||||
|
||||
public void setSubscriptionDao(IFhirResourceDao<Subscription> theSubscriptionDao) {
|
||||
mySubscriptionDao = theSubscriptionDao;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void incomingRequestPreHandled(RestOperationTypeEnum theOperation, ActionRequestDetails theDetails) {
|
||||
// check the subscription criteria to see if its valid before creating or updating a subscription
|
||||
|
@ -269,6 +267,10 @@ public class RestHookSubscriptionR4Interceptor extends BaseRestHookSubscriptionI
|
|||
return notifyOnDelete;
|
||||
}
|
||||
|
||||
public void setNotifyOnDelete(boolean notifyOnDelete) {
|
||||
this.notifyOnDelete = notifyOnDelete;
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses may override
|
||||
*/
|
||||
|
@ -276,15 +278,6 @@ public class RestHookSubscriptionR4Interceptor extends BaseRestHookSubscriptionI
|
|||
return theCriteria;
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void postConstruct() {
|
||||
try {
|
||||
executor = Executors.newFixedThreadPool(MAX_THREADS);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Unable to get DAO from PROXY");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove subscription from cache
|
||||
*
|
||||
|
@ -313,8 +306,8 @@ public class RestHookSubscriptionR4Interceptor extends BaseRestHookSubscriptionI
|
|||
if (theResource instanceof Subscription) {
|
||||
Subscription subscription = (Subscription) theResource;
|
||||
if (subscription.getChannel() != null
|
||||
&& subscription.getChannel().getType() == Subscription.SubscriptionChannelType.RESTHOOK
|
||||
&& subscription.getStatus() == Subscription.SubscriptionStatus.REQUESTED) {
|
||||
&& subscription.getChannel().getType() == Subscription.SubscriptionChannelType.RESTHOOK
|
||||
&& subscription.getStatus() == Subscription.SubscriptionStatus.REQUESTED) {
|
||||
removeLocalSubscription(subscription.getIdElement().getIdPart());
|
||||
myRestHookSubscriptions.add(subscription);
|
||||
subscription.setStatus(Subscription.SubscriptionStatus.ACTIVE);
|
||||
|
@ -328,16 +321,13 @@ public class RestHookSubscriptionR4Interceptor extends BaseRestHookSubscriptionI
|
|||
/**
|
||||
* Check subscriptions to see if there is a matching subscription when there is a delete
|
||||
*
|
||||
* @param theRequest
|
||||
* A bean containing details about the request that is about to be processed, including details such as the
|
||||
* resource type and logical ID (if any) and other FHIR-specific aspects of the request which have been
|
||||
* pulled out of the {@link HttpServletRequest servlet request}.
|
||||
* @param theRequest
|
||||
* The incoming request
|
||||
* @param theResource
|
||||
* The response. Note that interceptors may choose to provide a response (i.e. by calling
|
||||
* {@link HttpServletResponse#getWriter()}) but in that case it is important to return <code>false</code>
|
||||
* to indicate that the server itself should not also provide a response.
|
||||
* @param theRequest A bean containing details about the request that is about to be processed, including details such as the
|
||||
* resource type and logical ID (if any) and other FHIR-specific aspects of the request which have been
|
||||
* pulled out of the {@link HttpServletRequest servlet request}.
|
||||
* @param theRequest The incoming request
|
||||
* @param theResource The response. Note that interceptors may choose to provide a response (i.e. by calling
|
||||
* {@link HttpServletResponse#getWriter()}) but in that case it is important to return <code>false</code>
|
||||
* to indicate that the server itself should not also provide a response.
|
||||
*/
|
||||
@Override
|
||||
public void resourceDeleted(RequestDetails theRequest, IBaseResource theResource) {
|
||||
|
@ -384,12 +374,4 @@ public class RestHookSubscriptionR4Interceptor extends BaseRestHookSubscriptionI
|
|||
myFhirContext = theFhirContext;
|
||||
}
|
||||
|
||||
public void setNotifyOnDelete(boolean notifyOnDelete) {
|
||||
this.notifyOnDelete = notifyOnDelete;
|
||||
}
|
||||
|
||||
public void setSubscriptionDao(IFhirResourceDao<Subscription> theSubscriptionDao) {
|
||||
mySubscriptionDao = theSubscriptionDao;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,30 +1,10 @@
|
|||
package ca.uhn.fhir.jpa.provider;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
import org.junit.*;
|
||||
import org.springframework.web.context.ContextLoader;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
|
||||
import org.springframework.web.context.support.GenericWebApplicationContext;
|
||||
import org.springframework.web.servlet.DispatcherServlet;
|
||||
|
||||
import ca.uhn.fhir.jpa.config.WebsocketDstu2Config;
|
||||
import ca.uhn.fhir.jpa.config.WebsocketDstu2DispatcherConfig;
|
||||
import ca.uhn.fhir.jpa.dao.dstu2.BaseJpaDstu2Test;
|
||||
import ca.uhn.fhir.jpa.interceptor.RestHookSubscriptionDstu2Interceptor;
|
||||
import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider;
|
||||
import ca.uhn.fhir.jpa.testutil.RandomServerPortProvider;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Bundle;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Bundle.Entry;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
|
@ -35,6 +15,27 @@ import ca.uhn.fhir.rest.client.api.ServerValidationModeEnum;
|
|||
import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor;
|
||||
import ca.uhn.fhir.rest.server.RestfulServer;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.springframework.web.context.ContextLoader;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
|
||||
import org.springframework.web.context.support.GenericWebApplicationContext;
|
||||
import org.springframework.web.servlet.DispatcherServlet;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static ca.uhn.fhir.jpa.testutil.RandomServerPortProvider.findFreePort;
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
public abstract class BaseResourceProviderDstu2Test extends BaseJpaDstu2Test {
|
||||
|
||||
|
@ -58,74 +59,74 @@ public abstract class BaseResourceProviderDstu2Test extends BaseJpaDstu2Test {
|
|||
myFhirCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.ONCE);
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
@Before
|
||||
public void before() throws Exception {
|
||||
myFhirCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER);
|
||||
myFhirCtx.getRestfulClientFactory().setSocketTimeout(1200 * 1000);
|
||||
|
||||
|
||||
if (ourServer == null) {
|
||||
ourPort = RandomServerPortProvider.findFreePort();
|
||||
|
||||
ourPort = findFreePort();
|
||||
|
||||
ourRestServer = new RestfulServer(myFhirCtx);
|
||||
|
||||
|
||||
ourServerBase = "http://localhost:" + ourPort + "/fhir/context";
|
||||
|
||||
ourRestServer.setResourceProviders((List)myResourceProviders);
|
||||
|
||||
|
||||
ourRestServer.setResourceProviders((List) myResourceProviders);
|
||||
|
||||
ourRestServer.getFhirContext().setNarrativeGenerator(new DefaultThymeleafNarrativeGenerator());
|
||||
|
||||
|
||||
ourRestServer.setPlainProviders(mySystemProvider);
|
||||
|
||||
|
||||
JpaConformanceProviderDstu2 confProvider = new JpaConformanceProviderDstu2(ourRestServer, mySystemDao, myDaoConfig);
|
||||
confProvider.setImplementationDescription("THIS IS THE DESC");
|
||||
ourRestServer.setServerConformanceProvider(confProvider);
|
||||
|
||||
|
||||
ourPagingProvider = myAppCtx.getBean(DatabaseBackedPagingProvider.class);
|
||||
ourRestServer.setPagingProvider(ourPagingProvider);
|
||||
|
||||
|
||||
Server server = new Server(ourPort);
|
||||
|
||||
|
||||
ServletContextHandler proxyHandler = new ServletContextHandler();
|
||||
proxyHandler.setContextPath("/");
|
||||
|
||||
|
||||
ServletHolder servletHolder = new ServletHolder();
|
||||
servletHolder.setServlet(ourRestServer);
|
||||
proxyHandler.addServlet(servletHolder, "/fhir/context/*");
|
||||
|
||||
|
||||
ourWebApplicationContext = new GenericWebApplicationContext();
|
||||
ourWebApplicationContext.setParent(myAppCtx);
|
||||
ourWebApplicationContext.refresh();
|
||||
|
||||
ourRestHookSubscriptionInterceptor = ourWebApplicationContext.getBean(RestHookSubscriptionDstu2Interceptor.class);
|
||||
|
||||
proxyHandler.getServletContext().setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, ourWebApplicationContext);
|
||||
|
||||
|
||||
proxyHandler.getServletContext().setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, ourWebApplicationContext);
|
||||
|
||||
DispatcherServlet dispatcherServlet = new DispatcherServlet();
|
||||
dispatcherServlet.setContextClass(AnnotationConfigWebApplicationContext.class);
|
||||
ServletHolder subsServletHolder = new ServletHolder();
|
||||
subsServletHolder.setServlet(dispatcherServlet);
|
||||
subsServletHolder.setInitParameter(
|
||||
ContextLoader.CONFIG_LOCATION_PARAM,
|
||||
WebsocketDstu2Config.class.getName() + "\n" +
|
||||
ContextLoader.CONFIG_LOCATION_PARAM,
|
||||
WebsocketDstu2Config.class.getName() + "\n" +
|
||||
WebsocketDstu2DispatcherConfig.class.getName());
|
||||
proxyHandler.addServlet(subsServletHolder, "/*");
|
||||
|
||||
|
||||
|
||||
server.setHandler(proxyHandler);
|
||||
server.start();
|
||||
|
||||
|
||||
ourClient = myFhirCtx.newRestfulGenericClient(ourServerBase);
|
||||
ourClient.registerInterceptor(new LoggingInterceptor());
|
||||
|
||||
|
||||
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(5000, TimeUnit.MILLISECONDS);
|
||||
HttpClientBuilder builder = HttpClientBuilder.create();
|
||||
builder.setConnectionManager(connectionManager);
|
||||
ourHttpClient = builder.build();
|
||||
|
||||
|
||||
ourServer = server;
|
||||
}
|
||||
|
||||
|
||||
ourRestServer.setPagingProvider(ourPagingProvider);
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,8 @@ import static org.junit.Assert.assertEquals;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import ca.uhn.fhir.model.dstu2.resource.Bundle;
|
||||
import ca.uhn.fhir.util.BundleUtil;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
|
@ -55,10 +57,10 @@ public class RestHookTestWithInterceptorRegisteredToDaoConfigDstu2Test extends B
|
|||
public void afterUnregisterRestHookListener() {
|
||||
myDaoConfig.setAllowMultipleDelete(true);
|
||||
ourLog.info("Deleting all subscriptions");
|
||||
ourClient.delete().resourceConditionalByUrl("Subscription?status=requested").execute();// TODO: this shouldn't be neccesary
|
||||
ourClient.delete().resourceConditionalByUrl("Subscription?status=active").execute();
|
||||
ourLog.info("Done deleting all subscriptions");
|
||||
myDaoConfig.setAllowMultipleDelete(new DaoConfig().isAllowMultipleDelete());
|
||||
|
||||
myDaoConfig.getInterceptors().remove(ourRestHookSubscriptionInterceptor);
|
||||
}
|
||||
|
||||
|
@ -71,12 +73,18 @@ public class RestHookTestWithInterceptorRegisteredToDaoConfigDstu2Test extends B
|
|||
public void beforeReset() {
|
||||
ourCreatedObservations.clear();
|
||||
ourUpdatedObservations.clear();
|
||||
myDaoConfig.setAllowMultipleDelete(true);
|
||||
for (IBaseResource next : BundleUtil.toListOfResources(myFhirCtx, ourClient.search().forResource("Subscription").returnBundle(Bundle.class).execute())) {
|
||||
ourClient.delete().resource(next).execute();
|
||||
}
|
||||
ourClient.delete().resourceConditionalByUrl("Subscription?type=rest-hook").execute();
|
||||
myDaoConfig.setAllowMultipleDelete(new DaoConfig().isAllowMultipleDelete());
|
||||
}
|
||||
|
||||
private Subscription createSubscription(String criteria, String payload, String endpoint) {
|
||||
Subscription subscription = new Subscription();
|
||||
subscription.setReason("Monitor new neonatal function (note, age will be determined by the monitor)");
|
||||
subscription.setStatus(SubscriptionStatusEnum.ACTIVE);
|
||||
subscription.setStatus(SubscriptionStatusEnum.REQUESTED);
|
||||
subscription.setCriteria(criteria);
|
||||
|
||||
Channel channel = new Channel();
|
||||
|
@ -138,7 +146,7 @@ public class RestHookTestWithInterceptorRegisteredToDaoConfigDstu2Test extends B
|
|||
|
||||
// Should see two subscription notifications
|
||||
Thread.sleep(500);
|
||||
assertEquals(3, ourCreatedObservations.size());
|
||||
assertEquals(2, ourCreatedObservations.size());
|
||||
assertEquals(0, ourUpdatedObservations.size());
|
||||
|
||||
ourClient.delete().resourceById(new IdDt("Subscription/"+ subscription2.getId())).execute();
|
||||
|
@ -147,7 +155,7 @@ public class RestHookTestWithInterceptorRegisteredToDaoConfigDstu2Test extends B
|
|||
|
||||
// Should see only one subscription notification
|
||||
Thread.sleep(500);
|
||||
assertEquals(4, ourCreatedObservations.size());
|
||||
assertEquals(3, ourCreatedObservations.size());
|
||||
assertEquals(0, ourUpdatedObservations.size());
|
||||
|
||||
Observation observation3 = ourClient.read(Observation.class, observationTemp3.getId());
|
||||
|
@ -160,7 +168,7 @@ public class RestHookTestWithInterceptorRegisteredToDaoConfigDstu2Test extends B
|
|||
|
||||
// Should see no subscription notification
|
||||
Thread.sleep(500);
|
||||
assertEquals(4, ourCreatedObservations.size());
|
||||
assertEquals(3, ourCreatedObservations.size());
|
||||
assertEquals(0, ourUpdatedObservations.size());
|
||||
|
||||
Observation observation3a = ourClient.read(Observation.class, observationTemp3.getId());
|
||||
|
@ -174,7 +182,7 @@ public class RestHookTestWithInterceptorRegisteredToDaoConfigDstu2Test extends B
|
|||
|
||||
// Should see only one subscription notification
|
||||
Thread.sleep(500);
|
||||
assertEquals(4, ourCreatedObservations.size());
|
||||
assertEquals(3, ourCreatedObservations.size());
|
||||
assertEquals(1, ourUpdatedObservations.size());
|
||||
|
||||
Assert.assertFalse(subscription1.getId().equals(subscription2.getId()));
|
||||
|
@ -209,9 +217,9 @@ public class RestHookTestWithInterceptorRegisteredToDaoConfigDstu2Test extends B
|
|||
|
||||
Observation observation2 = sendObservation(code, "SNOMED-CT");
|
||||
|
||||
// Should see two subscription notifications
|
||||
// Should see one subscription notification
|
||||
Thread.sleep(500);
|
||||
assertEquals(3, ourCreatedObservations.size());
|
||||
assertEquals(2, ourCreatedObservations.size());
|
||||
assertEquals(0, ourUpdatedObservations.size());
|
||||
|
||||
ourClient.delete().resourceById(new IdDt("Subscription/"+ subscription2.getId())).execute();
|
||||
|
@ -220,7 +228,7 @@ public class RestHookTestWithInterceptorRegisteredToDaoConfigDstu2Test extends B
|
|||
|
||||
// Should see only one subscription notification
|
||||
Thread.sleep(500);
|
||||
assertEquals(4, ourCreatedObservations.size());
|
||||
assertEquals(3, ourCreatedObservations.size());
|
||||
assertEquals(0, ourUpdatedObservations.size());
|
||||
|
||||
Observation observation3 = ourClient.read(Observation.class, observationTemp3.getId());
|
||||
|
@ -233,7 +241,7 @@ public class RestHookTestWithInterceptorRegisteredToDaoConfigDstu2Test extends B
|
|||
|
||||
// Should see no subscription notification
|
||||
Thread.sleep(500);
|
||||
assertEquals(4, ourCreatedObservations.size());
|
||||
assertEquals(3, ourCreatedObservations.size());
|
||||
assertEquals(0, ourUpdatedObservations.size());
|
||||
|
||||
Observation observation3a = ourClient.read(Observation.class, observationTemp3.getId());
|
||||
|
@ -247,7 +255,7 @@ public class RestHookTestWithInterceptorRegisteredToDaoConfigDstu2Test extends B
|
|||
|
||||
// Should see only one subscription notification
|
||||
Thread.sleep(500);
|
||||
assertEquals(4, ourCreatedObservations.size());
|
||||
assertEquals(3, ourCreatedObservations.size());
|
||||
assertEquals(1, ourUpdatedObservations.size());
|
||||
|
||||
Assert.assertFalse(subscription1.getId().equals(subscription2.getId()));
|
||||
|
|
|
@ -46,10 +46,10 @@ public class RestHookTestWithInterceptorRegisteredToDaoConfigDstu3Test extends B
|
|||
public void afterUnregisterRestHookListener() {
|
||||
myDaoConfig.setAllowMultipleDelete(true);
|
||||
ourLog.info("Deleting all subscriptions");
|
||||
ourClient.delete().resourceConditionalByUrl("Subscription?status=requested").execute();// TODO: this shouldn't be neccesary
|
||||
ourClient.delete().resourceConditionalByUrl("Subscription?status=active").execute();
|
||||
ourLog.info("Done deleting all subscriptions");
|
||||
myDaoConfig.setAllowMultipleDelete(new DaoConfig().isAllowMultipleDelete());
|
||||
|
||||
myDaoConfig.getInterceptors().remove(ourRestHookSubscriptionInterceptor);
|
||||
}
|
||||
|
||||
|
@ -67,7 +67,7 @@ public class RestHookTestWithInterceptorRegisteredToDaoConfigDstu3Test extends B
|
|||
private Subscription createSubscription(String criteria, String payload, String endpoint) {
|
||||
Subscription subscription = new Subscription();
|
||||
subscription.setReason("Monitor new neonatal function (note, age will be determined by the monitor)");
|
||||
subscription.setStatus(Subscription.SubscriptionStatus.ACTIVE);
|
||||
subscription.setStatus(Subscription.SubscriptionStatus.REQUESTED);
|
||||
subscription.setCriteria(criteria);
|
||||
|
||||
Subscription.SubscriptionChannelComponent channel = new Subscription.SubscriptionChannelComponent();
|
||||
|
@ -129,7 +129,7 @@ public class RestHookTestWithInterceptorRegisteredToDaoConfigDstu3Test extends B
|
|||
|
||||
// Should see two subscription notifications
|
||||
Thread.sleep(500);
|
||||
assertEquals(3, ourCreatedObservations.size());
|
||||
assertEquals(2, ourCreatedObservations.size());
|
||||
assertEquals(0, ourUpdatedObservations.size());
|
||||
|
||||
ourClient.delete().resourceById(new IdDt("Subscription", subscription2.getId())).execute();
|
||||
|
@ -138,7 +138,7 @@ public class RestHookTestWithInterceptorRegisteredToDaoConfigDstu3Test extends B
|
|||
|
||||
// Should see only one subscription notification
|
||||
Thread.sleep(500);
|
||||
assertEquals(4, ourCreatedObservations.size());
|
||||
assertEquals(3, ourCreatedObservations.size());
|
||||
assertEquals(0, ourUpdatedObservations.size());
|
||||
|
||||
Observation observation3 = ourClient.read(Observation.class, observationTemp3.getId());
|
||||
|
@ -151,7 +151,7 @@ public class RestHookTestWithInterceptorRegisteredToDaoConfigDstu3Test extends B
|
|||
|
||||
// Should see no subscription notification
|
||||
Thread.sleep(500);
|
||||
assertEquals(4, ourCreatedObservations.size());
|
||||
assertEquals(3, ourCreatedObservations.size());
|
||||
assertEquals(0, ourUpdatedObservations.size());
|
||||
|
||||
Observation observation3a = ourClient.read(Observation.class, observationTemp3.getId());
|
||||
|
@ -165,7 +165,7 @@ public class RestHookTestWithInterceptorRegisteredToDaoConfigDstu3Test extends B
|
|||
|
||||
// Should see only one subscription notification
|
||||
Thread.sleep(500);
|
||||
assertEquals(4, ourCreatedObservations.size());
|
||||
assertEquals(3, ourCreatedObservations.size());
|
||||
assertEquals(1, ourUpdatedObservations.size());
|
||||
|
||||
Assert.assertFalse(subscription1.getId().equals(subscription2.getId()));
|
||||
|
@ -202,7 +202,7 @@ public class RestHookTestWithInterceptorRegisteredToDaoConfigDstu3Test extends B
|
|||
|
||||
// Should see two subscription notifications
|
||||
Thread.sleep(500);
|
||||
assertEquals(3, ourCreatedObservations.size());
|
||||
assertEquals(2, ourCreatedObservations.size());
|
||||
assertEquals(0, ourUpdatedObservations.size());
|
||||
|
||||
ourClient.delete().resourceById(new IdDt("Subscription", subscription2.getId())).execute();
|
||||
|
@ -211,7 +211,7 @@ public class RestHookTestWithInterceptorRegisteredToDaoConfigDstu3Test extends B
|
|||
|
||||
// Should see only one subscription notification
|
||||
Thread.sleep(500);
|
||||
assertEquals(4, ourCreatedObservations.size());
|
||||
assertEquals(3, ourCreatedObservations.size());
|
||||
assertEquals(0, ourUpdatedObservations.size());
|
||||
|
||||
Observation observation3 = ourClient.read(Observation.class, observationTemp3.getId());
|
||||
|
@ -224,7 +224,7 @@ public class RestHookTestWithInterceptorRegisteredToDaoConfigDstu3Test extends B
|
|||
|
||||
// Should see no subscription notification
|
||||
Thread.sleep(500);
|
||||
assertEquals(4, ourCreatedObservations.size());
|
||||
assertEquals(3, ourCreatedObservations.size());
|
||||
assertEquals(0, ourUpdatedObservations.size());
|
||||
|
||||
Observation observation3a = ourClient.read(Observation.class, observationTemp3.getId());
|
||||
|
@ -238,7 +238,7 @@ public class RestHookTestWithInterceptorRegisteredToDaoConfigDstu3Test extends B
|
|||
|
||||
// Should see only one subscription notification
|
||||
Thread.sleep(500);
|
||||
assertEquals(4, ourCreatedObservations.size());
|
||||
assertEquals(3, ourCreatedObservations.size());
|
||||
assertEquals(1, ourUpdatedObservations.size());
|
||||
|
||||
Assert.assertFalse(subscription1.getId().equals(subscription2.getId()));
|
||||
|
|
|
@ -1,40 +1,39 @@
|
|||
|
||||
package ca.uhn.fhir.jpa.subscription.r4;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
import org.hl7.fhir.r4.model.*;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.junit.*;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.jpa.dao.DaoConfig;
|
||||
import ca.uhn.fhir.jpa.provider.r4.BaseResourceProviderR4Test;
|
||||
import ca.uhn.fhir.jpa.testutil.RandomServerPortProvider;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.annotation.*;
|
||||
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.MethodOutcome;
|
||||
import ca.uhn.fhir.rest.server.IResourceProvider;
|
||||
import ca.uhn.fhir.rest.server.RestfulServer;
|
||||
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.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.r4.model.*;
|
||||
import org.junit.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* Test the rest-hook subscriptions
|
||||
*/
|
||||
public class RestHookTestWithInterceptorRegisteredToDaoConfigR4Test extends BaseResourceProviderR4Test {
|
||||
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(RestHookTestWithInterceptorRegisteredToDaoConfigR4Test.class);
|
||||
private static List<Observation> ourCreatedObservations = Lists.newArrayList();
|
||||
private static int ourListenerPort;
|
||||
private static RestfulServer ourListenerRestServer;
|
||||
private static Server ourListenerServer;
|
||||
private static String ourListenerServerBase;
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(RestHookTestWithInterceptorRegisteredToDaoConfigR4Test.class);
|
||||
private static List<Observation> ourUpdatedObservations = Lists.newArrayList();
|
||||
|
||||
@Override
|
||||
|
@ -46,10 +45,10 @@ public class RestHookTestWithInterceptorRegisteredToDaoConfigR4Test extends Base
|
|||
public void afterUnregisterRestHookListener() {
|
||||
myDaoConfig.setAllowMultipleDelete(true);
|
||||
ourLog.info("Deleting all subscriptions");
|
||||
ourClient.delete().resourceConditionalByUrl("Subscription?status=requested").execute();// TODO: this shouldn't be neccesary
|
||||
ourClient.delete().resourceConditionalByUrl("Subscription?status=active").execute();
|
||||
ourLog.info("Done deleting all subscriptions");
|
||||
myDaoConfig.setAllowMultipleDelete(new DaoConfig().isAllowMultipleDelete());
|
||||
|
||||
myDaoConfig.getInterceptors().remove(ourRestHookSubscriptionInterceptor);
|
||||
}
|
||||
|
||||
|
@ -67,7 +66,7 @@ public class RestHookTestWithInterceptorRegisteredToDaoConfigR4Test extends Base
|
|||
private Subscription createSubscription(String criteria, String payload, String endpoint) {
|
||||
Subscription subscription = new Subscription();
|
||||
subscription.setReason("Monitor new neonatal function (note, age will be determined by the monitor)");
|
||||
subscription.setStatus(Subscription.SubscriptionStatus.ACTIVE);
|
||||
subscription.setStatus(Subscription.SubscriptionStatus.REQUESTED);
|
||||
subscription.setCriteria(criteria);
|
||||
|
||||
Subscription.SubscriptionChannelComponent channel = new Subscription.SubscriptionChannelComponent();
|
||||
|
@ -117,7 +116,7 @@ public class RestHookTestWithInterceptorRegisteredToDaoConfigR4Test extends Base
|
|||
Thread.sleep(500);
|
||||
assertEquals(1, ourCreatedObservations.size());
|
||||
assertEquals(0, ourUpdatedObservations.size());
|
||||
|
||||
|
||||
Subscription subscriptionTemp = ourClient.read(Subscription.class, subscription2.getId());
|
||||
Assert.assertNotNull(subscriptionTemp);
|
||||
|
||||
|
@ -129,16 +128,16 @@ public class RestHookTestWithInterceptorRegisteredToDaoConfigR4Test extends Base
|
|||
|
||||
// Should see two subscription notifications
|
||||
Thread.sleep(500);
|
||||
assertEquals(3, ourCreatedObservations.size());
|
||||
assertEquals(2, ourCreatedObservations.size());
|
||||
assertEquals(0, ourUpdatedObservations.size());
|
||||
|
||||
|
||||
ourClient.delete().resourceById(new IdDt("Subscription", subscription2.getId())).execute();
|
||||
|
||||
Observation observationTemp3 = sendObservation(code, "SNOMED-CT");
|
||||
|
||||
// Should see only one subscription notification
|
||||
Thread.sleep(500);
|
||||
assertEquals(4, ourCreatedObservations.size());
|
||||
assertEquals(3, ourCreatedObservations.size());
|
||||
assertEquals(0, ourUpdatedObservations.size());
|
||||
|
||||
Observation observation3 = ourClient.read(Observation.class, observationTemp3.getId());
|
||||
|
@ -151,7 +150,7 @@ public class RestHookTestWithInterceptorRegisteredToDaoConfigR4Test extends Base
|
|||
|
||||
// Should see no subscription notification
|
||||
Thread.sleep(500);
|
||||
assertEquals(4, ourCreatedObservations.size());
|
||||
assertEquals(3, ourCreatedObservations.size());
|
||||
assertEquals(0, ourUpdatedObservations.size());
|
||||
|
||||
Observation observation3a = ourClient.read(Observation.class, observationTemp3.getId());
|
||||
|
@ -165,7 +164,7 @@ public class RestHookTestWithInterceptorRegisteredToDaoConfigR4Test extends Base
|
|||
|
||||
// Should see only one subscription notification
|
||||
Thread.sleep(500);
|
||||
assertEquals(4, ourCreatedObservations.size());
|
||||
assertEquals(3, ourCreatedObservations.size());
|
||||
assertEquals(1, ourUpdatedObservations.size());
|
||||
|
||||
Assert.assertFalse(subscription1.getId().equals(subscription2.getId()));
|
||||
|
@ -190,7 +189,7 @@ public class RestHookTestWithInterceptorRegisteredToDaoConfigR4Test extends Base
|
|||
Thread.sleep(500);
|
||||
assertEquals(1, ourCreatedObservations.size());
|
||||
assertEquals(0, ourUpdatedObservations.size());
|
||||
|
||||
|
||||
Subscription subscriptionTemp = ourClient.read(Subscription.class, subscription2.getId());
|
||||
Assert.assertNotNull(subscriptionTemp);
|
||||
|
||||
|
@ -202,16 +201,16 @@ public class RestHookTestWithInterceptorRegisteredToDaoConfigR4Test extends Base
|
|||
|
||||
// Should see two subscription notifications
|
||||
Thread.sleep(500);
|
||||
assertEquals(3, ourCreatedObservations.size());
|
||||
assertEquals(2, ourCreatedObservations.size());
|
||||
assertEquals(0, ourUpdatedObservations.size());
|
||||
|
||||
|
||||
ourClient.delete().resourceById(new IdDt("Subscription", subscription2.getId())).execute();
|
||||
|
||||
Observation observationTemp3 = sendObservation(code, "SNOMED-CT");
|
||||
|
||||
// Should see only one subscription notification
|
||||
Thread.sleep(500);
|
||||
assertEquals(4, ourCreatedObservations.size());
|
||||
assertEquals(3, ourCreatedObservations.size());
|
||||
assertEquals(0, ourUpdatedObservations.size());
|
||||
|
||||
Observation observation3 = ourClient.read(Observation.class, observationTemp3.getId());
|
||||
|
@ -224,7 +223,7 @@ public class RestHookTestWithInterceptorRegisteredToDaoConfigR4Test extends Base
|
|||
|
||||
// Should see no subscription notification
|
||||
Thread.sleep(500);
|
||||
assertEquals(4, ourCreatedObservations.size());
|
||||
assertEquals(3, ourCreatedObservations.size());
|
||||
assertEquals(0, ourUpdatedObservations.size());
|
||||
|
||||
Observation observation3a = ourClient.read(Observation.class, observationTemp3.getId());
|
||||
|
@ -238,7 +237,7 @@ public class RestHookTestWithInterceptorRegisteredToDaoConfigR4Test extends Base
|
|||
|
||||
// Should see only one subscription notification
|
||||
Thread.sleep(500);
|
||||
assertEquals(4, ourCreatedObservations.size());
|
||||
assertEquals(3, ourCreatedObservations.size());
|
||||
assertEquals(1, ourUpdatedObservations.size());
|
||||
|
||||
Assert.assertFalse(subscription1.getId().equals(subscription2.getId()));
|
||||
|
|
|
@ -6,7 +6,23 @@
|
|||
<title>HAPI FHIR Changelog</title>
|
||||
</properties>
|
||||
<body>
|
||||
<release version="3.0" date="TBD">
|
||||
<release version="3.0.0" date="TBD">
|
||||
<action type="add">
|
||||
<![CDATA[
|
||||
<ul>
|
||||
<li>AddProfileTagEnum moved from package ca.uhn.fhir.rest.server to package ca.uhn.fhir.context.api</li>
|
||||
<li>IVersionSpecificBundleFactory moved from package ca.uhn.fhir.rest.server to package ca.uhn.fhir.context.api</li>
|
||||
<li>BundleInclusionRule moved from package ca.uhn.fhir.rest.server to package ca.uhn.fhir.context.api</li>
|
||||
<li>RestSearchParameterTypeEnum moved from package ca.uhn.fhir.rest.server to package ca.uhn.fhir.rest.api</li>
|
||||
<li>EncodingEnum moved from package ca.uhn.fhir.rest.server to package ca.uhn.fhir.rest.api</li>
|
||||
<li>Constants moved from package ca.uhn.fhir.rest.server to package ca.uhn.fhir.rest.api</li>
|
||||
<li>IClientInterceptor moved from package ca.uhn.fhir.rest.client to package ca.uhn.fhir.rest.client.api</li>
|
||||
<li>IGenericClient moved from package ca.uhn.fhir.rest.client to package ca.uhn.fhir.rest.client.api</li>
|
||||
<li>IRestfulClient moved from package ca.uhn.fhir.rest.client to package ca.uhn.fhir.rest.client.api</li>
|
||||
<li>ITestingUiClientFactory moved from package ca.uhn.fhir.util to package ca.uhn.fhir.rest.server.util</li>
|
||||
</ul>
|
||||
]]>
|
||||
</action>
|
||||
<action type="add">
|
||||
Bump the version of a few dependencies to the
|
||||
latest versions (dependent HAPI modules listed in brackets):
|
||||
|
@ -46,22 +62,6 @@
|
|||
FHIR DSTU2. The presence of these headers sometimes caused parsed resource instances
|
||||
to contain duplicate tags
|
||||
</action>
|
||||
</release>
|
||||
<release version="2.6" date="TBD">
|
||||
<action type="add">
|
||||
<ul>
|
||||
<li>AddProfileTagEnum moved from package ca.uhn.fhir.rest.server to package ca.uhn.fhir.context.api</li>
|
||||
<li>IVersionSpecificBundleFactory moved from package ca.uhn.fhir.rest.server to package ca.uhn.fhir.context.api</li>
|
||||
<li>BundleInclusionRule moved from package ca.uhn.fhir.rest.server to package ca.uhn.fhir.context.api</li>
|
||||
<li>RestSearchParameterTypeEnum moved from package ca.uhn.fhir.rest.server to package ca.uhn.fhir.rest.api</li>
|
||||
<li>EncodingEnum moved from package ca.uhn.fhir.rest.server to package ca.uhn.fhir.rest.api</li>
|
||||
<li>Constants moved from package ca.uhn.fhir.rest.server to package ca.uhn.fhir.rest.api</li>
|
||||
<li>IClientInterceptor moved from package ca.uhn.fhir.rest.client to package ca.uhn.fhir.rest.client.api</li>
|
||||
<li>IGenericClient moved from package ca.uhn.fhir.rest.client to package ca.uhn.fhir.rest.client.api</li>
|
||||
<li>IRestfulClient moved from package ca.uhn.fhir.rest.client to package ca.uhn.fhir.rest.client.api</li>
|
||||
<li>ITestingUiClientFactory moved from package ca.uhn.fhir.util to package ca.uhn.fhir.rest.server.util</li>
|
||||
</ul>
|
||||
</action>
|
||||
<action type="fix" issue="667">
|
||||
When using the AuthorizationInterceptor with the JPA server, when a client is updating a resource
|
||||
from A to B, the user now needs to have write permission for both A and B. This is particularly
|
||||
|
@ -254,7 +254,7 @@
|
|||
<![CDATA[<code>Bundle.entry.response.outcome</code>]]>
|
||||
instead of the previous
|
||||
<![CDATA[<code>Bundle.entry.resource</code>]]>
|
||||
<action>
|
||||
</action>
|
||||
<action type="fix" issue="696">
|
||||
An issue was corrected where search parameters containing negative numbers
|
||||
were sometimes treated as positive numbers when processing the search. Thanks
|
||||
|
|
Loading…
Reference in New Issue