package ca.uhn.fhir.rest.client;
import java.io.InputStream;
import java.io.StringReader;
import java.nio.charset.Charset;
import org.apache.commons.io.input.ReaderInputStream;
import org.apache.http.HttpResponse;
import org.apache.http.ProtocolVersion;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicStatusLine;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.internal.stubbing.defaultanswers.ReturnsDeepStubs;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.dstu2.resource.Bundle;
import ca.uhn.fhir.model.dstu2.resource.MessageHeader;
import ca.uhn.fhir.model.dstu2.resource.OperationOutcome;
import ca.uhn.fhir.model.dstu2.valueset.BundleTypeEnum;
import ca.uhn.fhir.model.dstu2.valueset.ResponseTypeEnum;
import ca.uhn.fhir.rest.client.apache.ApacheRestfulClientFactory;
import ca.uhn.fhir.rest.server.Constants;
import ca.uhn.fhir.rest.server.EncodingEnum;
import ca.uhn.fhir.util.TestUtil;
import java.util.Date;
import java.util.UUID;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class MessageClientDstu2Test {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(MessageClientDstu2Test.class);
private FhirContext ourCtx;
private HttpClient myHttpClient;
private HttpResponse myHttpResponse;
@AfterClass
public static void afterClassClearContext() {
TestUtil.clearAllStaticFieldsForUnitTest();
}
@Before
public void before() {
ourCtx = FhirContext.forDstu2();
myHttpClient = mock(HttpClient.class, new ReturnsDeepStubs());
ourCtx.setRestfulClientFactory(new ApacheRestfulClientFactory(ourCtx));
ourCtx.getRestfulClientFactory().setConnectionRequestTimeout(10000);
ourCtx.getRestfulClientFactory().setConnectTimeout(10000);
ourCtx.getRestfulClientFactory().setPoolMaxPerRoute(100);
ourCtx.getRestfulClientFactory().setPoolMaxTotal(100);
ourCtx.getRestfulClientFactory().setHttpClient(myHttpClient);
ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER);
myHttpResponse = mock(HttpResponse.class, new ReturnsDeepStubs());
System.setProperty(BaseClient.HAPI_CLIENT_KEEPRESPONSES, "true");
}
@Test
public void testSendMessageAsync() throws Exception {
OperationOutcome oo = new OperationOutcome();
oo.addIssue().setDiagnostics("FOOBAR");
final String msg = ourCtx.newJsonParser().encodeResourceToString(oo);
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<InputStream>() {
@Override
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
return new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"));
}
});
IGenericClient client = ourCtx.getRestfulClientFactory().newGenericClient("http://192.168.4.93:83/fhirServer");
client.setEncoding(EncodingEnum.JSON);
// Create the input message to pass to the server
final Bundle msgBundle = getMessageBundle(
"myEvent", "Test Event",
"MySource", "http://myServer/fhir/", "MyDestination", "http://myDestinationServer/fhir/");
// Invoke $process-message
OperationOutcome response = client
.operation()
.processMessage()
.setResponseUrlParam("http://myserver/fhir")
.setMessageBundle(msgBundle)
.asynchronous(OperationOutcome.class)
.execute();
//System.out.println(response);
assertEquals("http://192.168.4.93:83/fhirServer/$process-message?async=true&response-url=http%3A%2F%2Fmyserver%2Ffhir&_format=json", capt.getAllValues().get(0).getURI().toASCIIString());
assertEquals("POST", capt.getAllValues().get(0).getRequestLine().getMethod());
//assertEquals("<Parameters xmlns=\"http://hl7.org/fhir\"><parameter><name value=\"resource\"/><resource><Patient xmlns=\"http://hl7.org/fhir\"><name><given value=\"GIVEN\"/></name></Patient></resource></parameter></Parameters>", extractBody(capt, 0));
//assertNotNull(response.getOperationOutcome());
assertEquals("FOOBAR", ((OperationOutcome) response).getIssueFirstRep().getDiagnosticsElement().getValue());
}
@Test
public void testSendMessage() throws Exception {
final Bundle msgBundleResponse = getMessageBundle(
"myEvent", "Test Event",
"MySource", "http://myServer/fhir/", "MyDestination", "http://myDestinationServer/fhir/");
((MessageHeader) msgBundleResponse.getEntryFirstRep().getResource()).getResponse().setCode(ResponseTypeEnum.OK);
final String msg = ourCtx.newJsonParser().encodeResourceToString(msgBundleResponse);
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<InputStream>() {
@Override
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
return new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"));
}
});
IGenericClient client = ourCtx.getRestfulClientFactory().newGenericClient("http://192.168.4.93:83/fhirServer");
client.setEncoding(EncodingEnum.JSON);
// Create the input message to pass to the server
final Bundle msgBundle = getMessageBundle(
"myEvent", "Test Event",
"MySource", "http://myServer/fhir/", "MyDestination", "http://myDestinationServer/fhir/");
// Invoke $process-message
Bundle response = client
.operation()
.processMessage()
.setMessageBundle(msgBundle)
.synchronous(Bundle.class)
.execute();
//System.out.println(response);
assertEquals("http://192.168.4.93:83/fhirServer/$process-message?async=false&_format=json", capt.getAllValues().get(0).getURI().toASCIIString());
assertEquals("POST", capt.getAllValues().get(0).getRequestLine().getMethod());
//assertEquals("<Parameters xmlns=\"http://hl7.org/fhir\"><parameter><name value=\"resource\"/><resource><Patient xmlns=\"http://hl7.org/fhir\"><name><given value=\"GIVEN\"/></name></Patient></resource></parameter></Parameters>", extractBody(capt, 0));
//assertNotNull(response.getOperationOutcome());
assertEquals("MessageHeader", ((Bundle) response).getEntryFirstRep().getResource().getResourceName());
}
/**
* Criar um FHIR Message Bundle pre-preenchido com os parametros
*
* @param eventCode
* @param eventDisplay
* @param sourceName
* @param sourceEnpoint
* @param destinationName
* @param destinationEndpoint
* @return Message Bundle
*/
public static Bundle getMessageBundle(String eventCode, String eventDisplay, String sourceName, String sourceEnpoint, String destinationName, String destinationEndpoint) {
/*
Init Bundle
*/
Bundle msgBundle = new Bundle();
msgBundle.getMeta().setLastUpdated(new Date());
msgBundle.setType(BundleTypeEnum.MESSAGE); //Document Type
msgBundle.setId(UUID.randomUUID().toString()); // Random ID
/*
Init MessageHeader
*/
MessageHeader msh = new MessageHeader();
msh.setId(UUID.randomUUID().toString());
msh.setTimestampWithMillisPrecision(new Date());
msh.getEvent().setSystem("http://mybServer/fhir/events");
msh.getEvent().setCode(eventCode);
msh.getEvent().setDisplay(eventDisplay);
msh.getSource().setName(sourceName);
msh.getSource().setEndpoint(sourceEnpoint);
msh.getDestinationFirstRep().setName(destinationName);
msh.getDestinationFirstRep().setEndpoint(destinationEndpoint);
Bundle.Entry entry = new Bundle.Entry();
entry.setFullUrl("http://mybase/fhirServer/Bundle/" + msh.getId().getValue());
entry.setResource(msh);
msgBundle.addEntry(entry);
return msgBundle;
}
}