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; } }