diff --git a/src/main/java/com/linuxforhealth/connect/builder/CareKitRouteBuilder.java b/src/main/java/com/linuxforhealth/connect/builder/CareKitRouteBuilder.java new file mode 100644 index 0000000..c5196b3 --- /dev/null +++ b/src/main/java/com/linuxforhealth/connect/builder/CareKitRouteBuilder.java @@ -0,0 +1,50 @@ +/* + * (C) Copyright IBM Corp. 2021 + * + * SPDX-License-Identifier: Apache-2.0 + */ +package com.linuxforhealth.connect.builder; + +import com.linuxforhealth.connect.processor.MetaDataProcessor; +import com.linuxforhealth.connect.support.CamelContextSupport; +import org.apache.camel.Exchange; +import org.apache.http.entity.ContentType; +import org.json.JSONObject; + +/** + * Supports Apple CareKit JSON Transactions + */ +public class CareKitRouteBuilder extends BaseRouteBuilder { + + public final static String ROUTE_ID = "carekit"; + private final static String ORIGINAL_MESSAGE_PROPERTY = "originalMessage"; + + @Override + protected String getRoutePropertyNamespace() { + return "lfh.connect.carekit"; + } + + + @Override + protected void buildRoute(String routePropertyNamespace) { + CamelContextSupport ctxSupport = new CamelContextSupport(getContext()); + String carekitUri = ctxSupport.getProperty("lfh.connect.carekit.uri"); + rest(carekitUri) + .post("/{resource}") + .route() + .routeId(ROUTE_ID) + .setProperty(ORIGINAL_MESSAGE_PROPERTY, simple("${body}")) + .process(new MetaDataProcessor(routePropertyNamespace)) + .to(LinuxForHealthRouteBuilder.STORE_AND_NOTIFY_CONSUMER_URI) + .removeHeaders("*") + .setHeader("Accept", constant("application/json")) + .setHeader(Exchange.HTTP_METHOD, constant("POST")) + .setHeader(Exchange.CONTENT_TYPE, constant(ContentType.APPLICATION_JSON)) + .process(exchange -> { + String careKitMessage = exchange.getProperty(ORIGINAL_MESSAGE_PROPERTY, String.class); + JSONObject json = new JSONObject(careKitMessage); + exchange.getIn().setBody(json.toString()); + }) + .to("{{lfh.connect.carekit.external.uri}}"); + } +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 14951c6..c9167c3 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -56,6 +56,12 @@ lfh.connect.orthanc.messagetype=Image lfh.connect.orthanc.server.uri=http://localhost:{{lfh.orthanc.port}}/instances lfh.connect.orthanc.image.uri=jetty:http://{{lfh.connect.host}}:{{lfh.connect.http.port}}/orthanc/images?httpMethodRestrict=GET +# Apple CareKit Integration +lfh.connect.carekit.uri=/carekit +lfh.connect.carekit.dataformat=carekit +lfh.connect.carekit.messagetype=\${header.resource} +lfh.connect.carekit.external.uri=mock:carekit + # X12 lfh.connect.x12.uri=/x12 lfh.connect.x12.dataformat=x12 diff --git a/src/test/java/com/linuxforhealth/connect/builder/CareKitRouteTest.java b/src/test/java/com/linuxforhealth/connect/builder/CareKitRouteTest.java new file mode 100644 index 0000000..1d478b3 --- /dev/null +++ b/src/test/java/com/linuxforhealth/connect/builder/CareKitRouteTest.java @@ -0,0 +1,101 @@ +/* + * (C) Copyright IBM Corp. 2021 + * + * SPDX-License-Identifier: Apache-2.0 + */ +package com.linuxforhealth.connect.builder; + +import com.linuxforhealth.connect.support.LinuxForHealthAssertions; +import com.linuxforhealth.connect.support.TestUtils; +import java.nio.charset.StandardCharsets; +import java.util.Base64; +import java.util.Properties; +import java.util.UUID; +import org.apache.camel.Exchange; +import org.apache.camel.RoutesBuilder; +import org.apache.camel.component.mock.MockEndpoint; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +/** + * Tests {@link CareKitRouteBuilder} + */ +public class CareKitRouteTest extends RouteTestSupport { + + private MockEndpoint mockStoreAndNotify; + private MockEndpoint mockExternalEndpoint; + + @Override + protected RoutesBuilder createRouteBuilder() throws Exception { + return new CareKitRouteBuilder(); + } + + @Override + protected Properties useOverridePropertiesWithPropertiesComponent() { + Properties props = super.useOverridePropertiesWithPropertiesComponent(); + props.setProperty("lfh.connect.carekit.uri", "/carekit"); + props.setProperty("lfh.connect.carekit.dataformat", "carekit"); + props.setProperty("lfh.connect.carekit.messagetype", "${header.resource}"); + props.setProperty("lfh.connect.carekit.external.uri", "mock:carekit"); + return props; + } + + /** + * Overridden to register beans, apply advice, and register a mock endpoint + * @throws Exception if an error occurs applying advice + */ + @BeforeEach + @Override + protected void configureContext() throws Exception { + mockStoreAndNotify = mockProducerEndpoint(CareKitRouteBuilder.ROUTE_ID, + LinuxForHealthRouteBuilder.STORE_AND_NOTIFY_CONSUMER_URI, + "mock:storeAndNotify"); + + mockExternalEndpoint = mockProducerEndpoint(CareKitRouteBuilder.ROUTE_ID, + LinuxForHealthRouteBuilder.STORE_AND_NOTIFY_CONSUMER_URI, + "mock:carekit"); + + super.configureContext(); + + } + + @Test + void testRoute() throws Exception { + String testMessage = context + .getTypeConverter() + .convertTo(String.class, TestUtils.getMessage("carekit", "patient.json")) + .replace(System.lineSeparator(), ""); + + String expectedMessage = Base64.getEncoder().encodeToString(testMessage.getBytes(StandardCharsets.UTF_8)); + + mockStoreAndNotify.expectedMessageCount(1); + mockStoreAndNotify.expectedBodiesReceived(expectedMessage); + mockStoreAndNotify.expectedPropertyReceived("dataStoreUri", "kafka:CAREKIT_PATIENT?brokers=localhost:9094"); + mockStoreAndNotify.expectedPropertyReceived("dataFormat", "CAREKIT"); + mockStoreAndNotify.expectedPropertyReceived("messageType", "PATIENT"); + mockStoreAndNotify.expectedPropertyReceived("routeId", "carekit"); + + mockExternalEndpoint.expectedMessageCount(1); + mockExternalEndpoint.expectedBodiesReceived(expectedMessage); + + fluentTemplate.to("http://0.0.0.0:8080/carekit/patient") + .withBody(testMessage) + .send(); + + mockStoreAndNotify.assertIsSatisfied(); + + String expectedRouteUri = "jetty:http://0.0.0.0:8080/carekit/patient?httpMethodRestrict=POST"; + String actualRouteUri = mockStoreAndNotify.getExchanges().get(0).getProperty("routeUri", String.class); + LinuxForHealthAssertions.assertEndpointUriSame(expectedRouteUri, actualRouteUri); + + Exchange mockExchange = mockStoreAndNotify.getExchanges().get(0); + + Long actualTimestamp = mockExchange.getProperty("timestamp", Long.class); + Assertions.assertNotNull(actualTimestamp); + Assertions.assertTrue(actualTimestamp > 0); + + UUID actualUuid = UUID.fromString(mockExchange.getProperty("uuid", String.class)); + Assertions.assertEquals(36, actualUuid.toString().length()); + } +} diff --git a/src/test/resources/messages/carekit/patient.json b/src/test/resources/messages/carekit/patient.json new file mode 100644 index 0000000..c84ced5 --- /dev/null +++ b/src/test/resources/messages/carekit/patient.json @@ -0,0 +1 @@ +{"id": "A","timezone": {"identifier": "America\/Sao_Paulo"},"name": {"familyName": "Frost","givenName": "Mary"},"effectiveDate": 607214692.32828295} \ No newline at end of file