http://git-wip-us.apache.org/repos/asf/camel/blob/bd1661b2/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTcpClientProducerTest.java ---------------------------------------------------------------------- diff --git a/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTcpClientProducerTest.java b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTcpClientProducerTest.java new file mode 100644 index 0000000..616e2d9 --- /dev/null +++ b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTcpClientProducerTest.java @@ -0,0 +1,249 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package org.apache.camel.component.mllp; + +import java.util.concurrent.TimeUnit; + +import org.apache.camel.CamelContext; +import org.apache.camel.EndpointInject; +import org.apache.camel.LoggingLevel; +import org.apache.camel.ProducerTemplate; +import org.apache.camel.builder.NotifyBuilder; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.impl.DefaultCamelContext; +import org.apache.camel.test.AvailablePortFinder; +import org.apache.camel.test.junit.rule.mllp.MllpServerResource; +import org.apache.camel.test.junit4.CamelTestSupport; +import org.junit.Rule; +import org.junit.Test; + +import static org.apache.camel.test.mllp.Hl7MessageGenerator.generateMessage; + +public class MllpTcpClientProducerTest extends CamelTestSupport { + @Rule + public MllpServerResource mllpServer = new MllpServerResource(AvailablePortFinder.getNextAvailable()); + + @EndpointInject(uri = "direct://source") + ProducerTemplate source; + + @EndpointInject(uri = "mock://acknowledged") + MockEndpoint acknowledged; + + @EndpointInject(uri = "mock://timeout-ex") + MockEndpoint timeout; + + @EndpointInject(uri = "mock://frame-ex") + MockEndpoint frame; + + @Override + public String isMockEndpoints() { + return "log://netty-mllp-sender-throughput*"; + } + + @Override + protected CamelContext createCamelContext() throws Exception { + DefaultCamelContext context = (DefaultCamelContext) super.createCamelContext(); + + context.setUseMDCLogging(true); + context.setName(this.getClass().getSimpleName()); + + return context; + } + + @Override + protected RouteBuilder createRouteBuilder() { + + return new RouteBuilder() { + int connectTimeout = 1000; + int responseTimeout = 1000; + + @Override + public void configure() throws Exception { + errorHandler( + defaultErrorHandler().allowRedeliveryWhileStopping(false)); + + onException(MllpCorruptFrameException.class) + .handled(true) + .logHandled(false) + .to(frame); + + onException(MllpTimeoutException.class) + .handled(true) + .logHandled(false) + .to(timeout); + + onCompletion() + .onFailureOnly().log(LoggingLevel.ERROR, "Processing Failed"); + + from(source.getDefaultEndpoint()) + .routeId("mllp-sender-test-route") + .log(LoggingLevel.INFO, "Sending Message: $simple{header[CamelHL7MessageControl]}") + .toF("mllp://%s:%d?connectTimeout=%d&responseTimeout=%d", + "0.0.0.0", mllpServer.getListenPort(), connectTimeout, responseTimeout) + .to(acknowledged); + + from("direct://handle-timeout") + .log(LoggingLevel.ERROR, "Response Timeout") + .rollback(); + + } + }; + + } + + @Test + public void testSendSingleMessage() throws Exception { + acknowledged.setExpectedMessageCount(1); + timeout.setExpectedMessageCount(0); + frame.setExpectedMessageCount(0); + + source.sendBody(generateMessage()); + + assertMockEndpointsSatisfied(15, TimeUnit.SECONDS); + } + + + @Test + public void testSendMultipleMessages() throws Exception { + int messageCount = 5; + acknowledged.setExpectedMessageCount(messageCount); + timeout.setExpectedMessageCount(0); + frame.setExpectedMessageCount(0); + + NotifyBuilder[] complete = new NotifyBuilder[messageCount]; + for (int i = 0; i < messageCount; ++i) { + complete[i] = new NotifyBuilder(context).whenDone(i + 1).create(); + } + + for (int i = 0; i < messageCount; ++i) { + source.sendBody(generateMessage(i + 1)); + assertTrue("Messege " + i + " not completed", complete[i].matches(1, TimeUnit.SECONDS)); + } + + assertMockEndpointsSatisfied(15, TimeUnit.SECONDS); + } + + + @Test + public void testNoResponseOnFirstMessage() throws Exception { + int sendMessageCount = 5; + acknowledged.setExpectedMessageCount(sendMessageCount - 1); + timeout.expectedMessageCount(1); + frame.setExpectedMessageCount(0); + + NotifyBuilder[] complete = new NotifyBuilder[sendMessageCount]; + for (int i = 0; i < sendMessageCount; ++i) { + complete[i] = new NotifyBuilder(context).whenDone(i + 1).create(); + } + + mllpServer.disableResponse(); + + source.sendBody(generateMessage(1)); + assertTrue("Messege 1 not completed", complete[0].matches(1, TimeUnit.SECONDS)); + + mllpServer.enableResponse(); + + for (int i = 1; i < sendMessageCount; ++i) { + source.sendBody(generateMessage(i + 1)); + assertTrue("Messege " + i + " not completed", complete[i].matches(1, TimeUnit.SECONDS)); + } + + assertMockEndpointsSatisfied(15, TimeUnit.SECONDS); + } + + @Test + public void testNoResponseOnNthMessage() throws Exception { + int sendMessageCount = 3; + acknowledged.setExpectedMessageCount(sendMessageCount - 1); + timeout.expectedMessageCount(1); + frame.setExpectedMessageCount(0); + + NotifyBuilder[] complete = new NotifyBuilder[sendMessageCount]; + for (int i = 0; i < sendMessageCount; ++i) { + complete[i] = new NotifyBuilder(context).whenDone(i + 1).create(); + } + + mllpServer.disableResponse(sendMessageCount); + + for (int i = 0; i < sendMessageCount; ++i) { + source.sendBody(generateMessage(i + 1)); + assertTrue("Messege " + i + " not completed", complete[i].matches(1, TimeUnit.SECONDS)); + } + + assertMockEndpointsSatisfied(15, TimeUnit.SECONDS); + } + + @Test + public void testMissingEndOfDataByte() throws Exception { + int sendMessageCount = 3; + acknowledged.setExpectedMessageCount(sendMessageCount - 1); + + NotifyBuilder[] complete = new NotifyBuilder[sendMessageCount]; + for (int i = 0; i < sendMessageCount; ++i) { + complete[i] = new NotifyBuilder(context).whenDone(i + 1).create(); + } + + mllpServer.setExcludeEndOfDataModulus(sendMessageCount); + + for (int i = 0; i < sendMessageCount; ++i) { + source.sendBody(generateMessage(i + 1)); + assertTrue("Messege " + i + " not completed", complete[i].matches(1, TimeUnit.SECONDS)); + } + + assertMockEndpointsSatisfied(15, TimeUnit.SECONDS); + } + + @Test + public void testMissingEndOfBlockByte() throws Exception { + int sendMessageCount = 3; + acknowledged.setExpectedMessageCount(sendMessageCount - 1); + + NotifyBuilder[] complete = new NotifyBuilder[sendMessageCount]; + for (int i = 0; i < sendMessageCount; ++i) { + complete[i] = new NotifyBuilder(context).whenDone(i + 1).create(); + } + + mllpServer.setExcludeEndOfBlockModulus(sendMessageCount); + + for (int i = 0; i < sendMessageCount; ++i) { + source.sendBody(generateMessage(i + 1)); + assertTrue("Messege " + i + " not completed", complete[i].matches(1, TimeUnit.SECONDS)); + } + + assertMockEndpointsSatisfied(15, TimeUnit.SECONDS); + } + + @Test + public void testApplicationAcceptAcknowledgement() throws Exception { + int sendMessageCount = 5; + acknowledged.setExpectedMessageCount(sendMessageCount); + + NotifyBuilder[] complete = new NotifyBuilder[sendMessageCount]; + for (int i = 0; i < sendMessageCount; ++i) { + complete[i] = new NotifyBuilder(context).whenDone(i + 1).create(); + } + + for (int i = 0; i < sendMessageCount; ++i) { + source.sendBody(generateMessage(i + 1)); + assertTrue("Messege " + i + " not completed", complete[i].matches(1, TimeUnit.SECONDS)); + } + + assertMockEndpointsSatisfied(15, TimeUnit.SECONDS); + } + +} \ No newline at end of file
http://git-wip-us.apache.org/repos/asf/camel/blob/bd1661b2/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTcpServerConsumerBlueprintTest.java ---------------------------------------------------------------------- diff --git a/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTcpServerConsumerBlueprintTest.java b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTcpServerConsumerBlueprintTest.java new file mode 100644 index 0000000..c7dd2c9 --- /dev/null +++ b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTcpServerConsumerBlueprintTest.java @@ -0,0 +1,101 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package org.apache.camel.component.mllp; + +import java.util.Dictionary; +import java.util.Map; +import java.util.Properties; +import java.util.concurrent.TimeUnit; + +import org.apache.camel.EndpointInject; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.impl.DefaultComponentResolver; +import org.apache.camel.spi.ComponentResolver; +import org.apache.camel.test.AvailablePortFinder; +import org.apache.camel.test.blueprint.CamelBlueprintTestSupport; +import org.apache.camel.test.junit.rule.mllp.MllpClientResource; +import org.apache.camel.util.KeyValueHolder; +import org.junit.Rule; +import org.junit.Test; + +import static org.apache.camel.test.mllp.Hl7MessageGenerator.generateMessage; + +public class MllpTcpServerConsumerBlueprintTest extends CamelBlueprintTestSupport { + @Rule + public MllpClientResource mllpClient = new MllpClientResource(); + + final String receivedUri = "mock://received"; + + @EndpointInject(uri = receivedUri) + MockEndpoint received; + + + @Override + protected String getBlueprintDescriptor() { + return "OSGI-INF/blueprint/mllp-tcp-server-consumer-test.xml"; + } + + @Override + protected void addServicesOnStartup(Map<String, KeyValueHolder<Object, Dictionary>> services) { + ComponentResolver testResolver = new DefaultComponentResolver(); + + services.put(ComponentResolver.class.getName(), asService(testResolver, "component", "mllp")); + } + + + @Override + protected Properties useOverridePropertiesWithPropertiesComponent() { + mllpClient.setMllpPort(AvailablePortFinder.getNextAvailable()); + + Properties props = new Properties(); + + props.setProperty("receivedUri", receivedUri); + props.setProperty("mllp.port", Integer.toString(mllpClient.getMllpPort())); + + return props; + } + + /* + This doesn't seem to work + @Override + protected String useOverridePropertiesWithConfigAdmin(Dictionary props) throws Exception { + mllpClient.setMllpPort(AvailablePortFinder.getNextAvailable()); + + props.put("mllp.port", mllpClient.getMllpPort() ); + + return "MllpTcpServerConsumerBlueprintTest"; + } + */ + + @Test + public void testReceiveMultipleMessages() throws Exception { + int sendMessageCount = 5; + received.expectedMinimumMessageCount(5); + + mllpClient.connect(); + + for (int i = 1; i <= sendMessageCount; ++i) { + mllpClient.sendMessageAndWaitForAcknowledgement(generateMessage(i)); + } + + mllpClient.close(); + + assertMockEndpointsSatisfied(10, TimeUnit.SECONDS); + } + + +} http://git-wip-us.apache.org/repos/asf/camel/blob/bd1661b2/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTcpServerConsumerConnectionTest.java ---------------------------------------------------------------------- diff --git a/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTcpServerConsumerConnectionTest.java b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTcpServerConsumerConnectionTest.java new file mode 100644 index 0000000..fab33a5 --- /dev/null +++ b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTcpServerConsumerConnectionTest.java @@ -0,0 +1,102 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package org.apache.camel.component.mllp; + +import java.net.InetSocketAddress; +import java.net.Socket; +import java.net.SocketAddress; +import java.util.concurrent.TimeUnit; + +import org.apache.camel.EndpointInject; +import org.apache.camel.LoggingLevel; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.test.AvailablePortFinder; +import org.apache.camel.test.junit4.CamelTestSupport; +import org.junit.Test; + +public class MllpTcpServerConsumerConnectionTest extends CamelTestSupport { + int mllpPort; + @EndpointInject(uri = "mock://result") + MockEndpoint result; + + @Override + protected RouteBuilder createRouteBuilder() throws Exception { + mllpPort = AvailablePortFinder.getNextAvailable(); + + return new RouteBuilder() { + String routeId = "mllp-receiver"; + + String host = "0.0.0.0"; + int port = mllpPort; + + public void configure() { + fromF("mllp:%d?autoAck=false", port) + .log(LoggingLevel.INFO, routeId, "Receiving: ${body}") + .to(result); + } + }; + + } + + /** + * Simulate a Load Balancer Probe + * <p/> + * Load Balancers check the status of a port by establishing and closing a TCP connection periodically. The time + * between these probes can normally be configured, but it is typically set to about 15-sec. Since there could be + * a large number of port that are being probed, the logging from the connect/disconnect operations can drown-out + * more useful information. + * <p/> + * Watch the logs when running this test to verify that the log output will be acceptable when a load balancer + * is probing the port. + * <p/> + * TODO: Need to add a custom Log4j Appender that can verify the logging is acceptable + * + * @throws Exception + */ + @Test + public void testConnectWithoutData() throws Exception { + result.setExpectedCount(0); + int connectionCount = 10; + + Socket dummyLoadBalancerSocket = null; + SocketAddress address = new InetSocketAddress("localhost", mllpPort); + int connectTimeout = 5000; + try { + for (int i = 1; i <= connectionCount; ++i) { + log.debug("Creating connection #{}", i); + dummyLoadBalancerSocket = new Socket(); + dummyLoadBalancerSocket.connect(address, connectTimeout); + log.debug("Closing connection #{}", i); + dummyLoadBalancerSocket.close(); + Thread.sleep(1000); + } + } finally { + if (null != dummyLoadBalancerSocket) { + try { + dummyLoadBalancerSocket.close(); + } catch (Exception ex) { + log.warn("Exception encountered closing dummy load balancer socket", ex); + } + } + } + + assertMockEndpointsSatisfied(15, TimeUnit.SECONDS); + } + + +} http://git-wip-us.apache.org/repos/asf/camel/blob/bd1661b2/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTcpServerConsumerMulitpleTcpPacketTest.java ---------------------------------------------------------------------- diff --git a/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTcpServerConsumerMulitpleTcpPacketTest.java b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTcpServerConsumerMulitpleTcpPacketTest.java new file mode 100644 index 0000000..afb3080 --- /dev/null +++ b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTcpServerConsumerMulitpleTcpPacketTest.java @@ -0,0 +1,120 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package org.apache.camel.component.mllp; + +import java.util.concurrent.TimeUnit; + +import org.apache.camel.CamelContext; +import org.apache.camel.EndpointInject; +import org.apache.camel.LoggingLevel; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.impl.DefaultCamelContext; +import org.apache.camel.test.AvailablePortFinder; +import org.apache.camel.test.junit.rule.mllp.MllpClientResource; +import org.apache.camel.test.junit4.CamelTestSupport; +import org.apache.camel.test.mllp.PassthroughProcessor; +import org.hamcrest.CoreMatchers; +import org.junit.Assert; +import org.junit.Rule; +import org.junit.Test; + +import static org.apache.camel.test.mllp.Hl7MessageGenerator.generateMessage; + +public class MllpTcpServerConsumerMulitpleTcpPacketTest extends CamelTestSupport { + @Rule + public MllpClientResource mllpClient = new MllpClientResource(); + + @EndpointInject(uri = "mock://result") + MockEndpoint result; + + @Override + protected CamelContext createCamelContext() throws Exception { + DefaultCamelContext context = (DefaultCamelContext) super.createCamelContext(); + + context.setUseMDCLogging(true); + context.setName(this.getClass().getSimpleName()); + + return context; + } + + @Override + protected RouteBuilder createRouteBuilder() { + final int groupInterval = 1000; + final boolean groupActiveOnly = false; + + mllpClient.setMllpHost("localhost"); + mllpClient.setMllpPort(AvailablePortFinder.getNextAvailable()); + + + return new RouteBuilder() { + String routeId = "mllp-receiver"; + + @Override + public void configure() throws Exception { + + onCompletion() + .log(LoggingLevel.DEBUG, routeId, "Test route complete"); + + fromF("mllp://%s:%d", + mllpClient.getMllpHost(), mllpClient.getMllpPort()) + .routeId(routeId) + .process(new PassthroughProcessor("Before send to result")) + .to(result) + .toF("log://%s?level=INFO&groupInterval=%d&groupActiveOnly=%b", routeId, groupInterval, groupActiveOnly) + .log(LoggingLevel.DEBUG, routeId, "Test route received message"); + + } + }; + } + + @Test + public void testReceiveSingleMessage() throws Exception { + mllpClient.connect(); + + String message = generateMessage(); + result.expectedBodiesReceived(message); + + mllpClient.sendFramedDataInMultiplePackets(message, (byte) '\r'); + String acknowledgement = mllpClient.receiveFramedData(); + + assertMockEndpointsSatisfied(10, TimeUnit.SECONDS); + + Assert.assertThat("Should be acknowledgment for message 1", acknowledgement, CoreMatchers.containsString(String.format("MSA|AA|00001"))); + } + + + @Test + public void testReceiveMultipleMessages() throws Exception { + int sendMessageCount = 1000; + result.expectedMinimumMessageCount(5); + + mllpClient.connect(); + + for (int i = 1; i <= sendMessageCount; ++i) { + String testMessage = generateMessage(i); + result.message(i - 1).body().isEqualTo(testMessage); + mllpClient.sendFramedDataInMultiplePackets(testMessage, (byte) '\r'); + String acknowledgement = mllpClient.receiveFramedData(); + Assert.assertThat("Should be acknowledgment for message " + i, acknowledgement, CoreMatchers.containsString(String.format("MSA|AA|%05d", i))); + } + + assertMockEndpointsSatisfied(10, TimeUnit.SECONDS); + } + + +} http://git-wip-us.apache.org/repos/asf/camel/blob/bd1661b2/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTcpServerConsumerTest.java ---------------------------------------------------------------------- diff --git a/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTcpServerConsumerTest.java b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTcpServerConsumerTest.java new file mode 100644 index 0000000..2ddd25c --- /dev/null +++ b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTcpServerConsumerTest.java @@ -0,0 +1,169 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package org.apache.camel.component.mllp; + +import java.util.concurrent.TimeUnit; + +import org.apache.camel.CamelContext; +import org.apache.camel.EndpointInject; +import org.apache.camel.LoggingLevel; +import org.apache.camel.builder.NotifyBuilder; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.impl.DefaultCamelContext; +import org.apache.camel.test.AvailablePortFinder; +import org.apache.camel.test.junit.rule.mllp.MllpClientResource; +import org.apache.camel.test.junit.rule.mllp.MllpJUnitResourceException; +import org.apache.camel.test.junit4.CamelTestSupport; +import org.junit.Rule; +import org.junit.Test; + +import static org.apache.camel.test.mllp.Hl7MessageGenerator.generateMessage; + +public class MllpTcpServerConsumerTest extends CamelTestSupport { + @Rule + public MllpClientResource mllpClient = new MllpClientResource(); + + @EndpointInject(uri = "mock://result") + MockEndpoint result; + + @Override + protected CamelContext createCamelContext() throws Exception { + DefaultCamelContext context = (DefaultCamelContext) super.createCamelContext(); + + context.setUseMDCLogging(true); + context.setName(this.getClass().getSimpleName()); + + return context; + } + + @Override + protected RouteBuilder createRouteBuilder() { + + mllpClient.setMllpHost("localhost"); + mllpClient.setMllpPort(AvailablePortFinder.getNextAvailable()); + + return new RouteBuilder() { + int connectTimeout = 500; + int responseTimeout = 5000; + + @Override + public void configure() throws Exception { + String routeId = "mllp-test-receiver-route"; + + onCompletion() + .toF("log:%s?level=INFO&showAll=true", routeId) + .log(LoggingLevel.INFO, routeId, "Test route complete"); + + fromF("mllp://%s:%d?autoAck=true&connectTimeout=%d&responseTimeout=%d", + mllpClient.getMllpHost(), mllpClient.getMllpPort(), connectTimeout, responseTimeout) + .routeId(routeId) + .log(LoggingLevel.INFO, routeId, "Test route received message") + .to(result); + + } + }; + } + + @Test + public void testReceiveSingleMessage() throws Exception { + result.expectedMessageCount(1); + + mllpClient.connect(); + + mllpClient.sendMessageAndWaitForAcknowledgement(generateMessage(), 10000); + + assertMockEndpointsSatisfied(10, TimeUnit.SECONDS); + } + + @Test + public void testReceiveSingleMessageWithDelayAfterConnection() throws Exception { + result.expectedMinimumMessageCount(1); + + mllpClient.connect(); + + Thread.sleep(5000); + mllpClient.sendMessageAndWaitForAcknowledgement(generateMessage(), 10000); + + assertMockEndpointsSatisfied(10, TimeUnit.SECONDS); + } + + @Test + public void testReceiveMultipleMessages() throws Exception { + int sendMessageCount = 5; + result.expectedMinimumMessageCount(5); + + mllpClient.connect(); + + for (int i = 1; i <= sendMessageCount; ++i) { + mllpClient.sendMessageAndWaitForAcknowledgement(generateMessage(i)); + } + + assertMockEndpointsSatisfied(10, TimeUnit.SECONDS); + } + + @Test + public void testOpenMllpEnvelopeWithReset() throws Exception { + result.expectedMessageCount(4); + NotifyBuilder notify1 = new NotifyBuilder(context).whenDone(2).create(); + NotifyBuilder notify2 = new NotifyBuilder(context).whenDone(5).create(); + + mllpClient.connect(); + mllpClient.setSoTimeout(10000); + + log.info("Sending TEST_MESSAGE_1"); + String acknowledgement1 = mllpClient.sendMessageAndWaitForAcknowledgement(generateMessage(1)); + + log.info("Sending TEST_MESSAGE_2"); + String acknowledgement2 = mllpClient.sendMessageAndWaitForAcknowledgement(generateMessage(2)); + + assertTrue("First two normal exchanges did not complete", notify1.matches(10, TimeUnit.SECONDS)); + + log.info("Sending TEST_MESSAGE_3"); + mllpClient.setSendEndOfBlock(false); + mllpClient.setSendEndOfData(false); + // Acknowledgement won't come here + try { + mllpClient.sendMessageAndWaitForAcknowledgement(generateMessage(3)); + } catch (MllpJUnitResourceException resourceEx) { + log.info("Expected exception reading response"); + } + mllpClient.disconnect(); + Thread.sleep(1000); + mllpClient.connect(); + + log.info("Sending TEST_MESSAGE_4"); + mllpClient.setSendEndOfBlock(true); + mllpClient.setSendEndOfData(true); + String acknowledgement4 = mllpClient.sendMessageAndWaitForAcknowledgement(generateMessage(4)); + + log.info("Sending TEST_MESSAGE_5"); + String acknowledgement5 = mllpClient.sendMessageAndWaitForAcknowledgement(generateMessage(5)); + + assertTrue("Remaining exchanges did not complete", notify2.matches(10, TimeUnit.SECONDS)); + + assertMockEndpointsSatisfied(10, TimeUnit.SECONDS); + + assertTrue("Should be acknowledgment for message 1", acknowledgement1.contains("MSA|AA|00001")); + assertTrue("Should be acknowledgment for message 2", acknowledgement2.contains("MSA|AA|00002")); + // assertTrue("Should be acknowledgment for message 3", acknowledgement3.contains("MSA|AA|00003")); + assertTrue("Should be acknowledgment for message 4", acknowledgement4.contains("MSA|AA|00004")); + assertTrue("Should be acknowledgment for message 5", acknowledgement5.contains("MSA|AA|00005")); + } + +} + http://git-wip-us.apache.org/repos/asf/camel/blob/bd1661b2/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTcpServerProducerBlueprintTest.java ---------------------------------------------------------------------- diff --git a/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTcpServerProducerBlueprintTest.java b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTcpServerProducerBlueprintTest.java new file mode 100644 index 0000000..dc796a5 --- /dev/null +++ b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTcpServerProducerBlueprintTest.java @@ -0,0 +1,35 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package org.apache.camel.component.mllp; + +import org.apache.camel.EndpointInject; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.test.blueprint.CamelBlueprintTestSupport; +import org.junit.Ignore; + +@Ignore(value = "Not Yet Implemented") +// TODO: Implement this +public class MllpTcpServerProducerBlueprintTest extends CamelBlueprintTestSupport { + @EndpointInject(uri = "mock://target") + MockEndpoint target; + + @Override + protected String getBlueprintDescriptor() { + return "OSGI-INF/blueprint/mllp-tcp-server-producer.xml"; + } + +} http://git-wip-us.apache.org/repos/asf/camel/blob/bd1661b2/components/camel-mllp/src/test/java/org/apache/camel/test/junit/rule/mllp/MllpClientResource.java ---------------------------------------------------------------------- diff --git a/components/camel-mllp/src/test/java/org/apache/camel/test/junit/rule/mllp/MllpClientResource.java b/components/camel-mllp/src/test/java/org/apache/camel/test/junit/rule/mllp/MllpClientResource.java new file mode 100644 index 0000000..8157e69 --- /dev/null +++ b/components/camel-mllp/src/test/java/org/apache/camel/test/junit/rule/mllp/MllpClientResource.java @@ -0,0 +1,461 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package org.apache.camel.test.junit.rule.mllp; + +import java.io.BufferedOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.net.SocketException; +import java.net.SocketTimeoutException; + +import org.junit.rules.ExternalResource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * MLLP Test Client packaged as a JUnit Rule + * + * The client can be configured to simulate a large number + * of error conditions. + */ +public class MllpClientResource extends ExternalResource { + + static final char START_OF_BLOCK = 0x0b; + static final char END_OF_BLOCK = 0x1c; + static final char END_OF_DATA = 0x0d; + static final int END_OF_STREAM = -1; + + Logger log = LoggerFactory.getLogger(this.getClass()); + + Socket clientSocket; + InputStream inputStream; + OutputStream outputStream; + + String mllpHost = "0.0.0.0"; + int mllpPort = -1; + + boolean sendStartOfBlock = true; + boolean sendEndOfBlock = true; + boolean sendEndOfData = true; + + int connectTimeout = 5000; + int soTimeout = 5000; + boolean reuseAddress; + boolean tcpNoDelay = true; + + + /** + * Use this constructor to avoid having the connection started by JUnit (since the port is still -1) + */ + public MllpClientResource() { + + } + + public MllpClientResource(int port) { + this.mllpPort = port; + } + + public MllpClientResource(String host, int port) { + this.mllpHost = host; + this.mllpPort = port; + } + + @Override + protected void before() throws Throwable { + if (0 < mllpPort) { + this.connect(); + } + + super.before(); + } + + @Override + protected void after() { + super.after(); + this.disconnect(); + } + + public void connect() { + this.connect(this.connectTimeout); + } + + public void connect(int connectTimeout) { + try { + clientSocket = new Socket(); + + clientSocket.connect(new InetSocketAddress(mllpHost, mllpPort), connectTimeout); + + clientSocket.setSoTimeout(soTimeout); + clientSocket.setSoLinger(false, -1); + clientSocket.setReuseAddress(reuseAddress); + clientSocket.setTcpNoDelay(tcpNoDelay); + + inputStream = clientSocket.getInputStream(); + outputStream = new BufferedOutputStream(clientSocket.getOutputStream(), 2048); + } catch (IOException e) { + String errorMessage = String.format("Unable to establish connection to %s:%s", mllpHost, mllpPort); + log.error(errorMessage, e); + throw new MllpJUnitResourceException(errorMessage, e); + } + } + + public void close() { + this.disconnect(); + return; + } + + public void reset() { + try { + clientSocket.setSoLinger(true, 0); + } catch (SocketException socketEx) { + log.warn("Exception encountered setting set SO_LINGER to force a TCP reset", socketEx); + } + this.disconnect(); + return; + } + + public void disconnect() { + try { + if (null != inputStream) { + clientSocket.close(); + } + } catch (IOException e) { + log.warn(String.format("Exception encountered closing connection to {}:{}", mllpHost, mllpPort), e); + } finally { + inputStream = null; + outputStream = null; + clientSocket = null; + } + } + + public boolean isConnected() { + return clientSocket.isConnected() && !clientSocket.isClosed(); + } + + public void sendData(String data) { + boolean disconnectAfterSend = false; + this.sendData(data, disconnectAfterSend); + } + + public void sendData(String data, boolean disconnectAfterSend) { + byte[] payloadBytes = data.getBytes(); + + try { + outputStream.write(payloadBytes, 0, payloadBytes.length); + } catch (IOException e) { + log.error("Unable to send raw string", e); + throw new MllpJUnitResourceException("Unable to send raw string", e); + } + + if (disconnectAfterSend) { + log.warn("Closing TCP connection"); + disconnect(); + } + } + + public void sendFramedData(String hl7Message) { + boolean disconnectAfterSend = false; + this.sendFramedData(hl7Message, disconnectAfterSend); + } + + public void sendFramedData(String hl7Message, boolean disconnectAfterSend) { + if (null == clientSocket) { + this.connect(); + } + + if (!clientSocket.isConnected()) { + throw new MllpJUnitResourceException("Cannot send message - client is not connected"); + } + if (null == outputStream) { + throw new MllpJUnitResourceException("Cannot send message - output stream is null"); + } + byte[] payloadBytes = hl7Message.getBytes(); + try { + if (sendStartOfBlock) { + outputStream.write(START_OF_BLOCK); + } else { + log.warn("Not sending START_OF_BLOCK"); + } + outputStream.write(payloadBytes, 0, payloadBytes.length); + if (sendEndOfBlock) { + outputStream.write(END_OF_BLOCK); + } else { + log.warn("Not sending END_OF_BLOCK"); + } + if (sendEndOfData) { + outputStream.write(END_OF_DATA); + } else { + log.warn("Not sending END_OF_DATA"); + } + outputStream.flush(); + } catch (IOException e) { + log.error("Unable to send HL7 message", e); + throw new MllpJUnitResourceException("Unable to send HL7 message", e); + } + + if (disconnectAfterSend) { + log.warn("Closing TCP connection"); + disconnect(); + } + } + + public void sendFramedDataInMultiplePackets(String hl7Message, byte flushByte) { + sendFramedDataInMultiplePackets(hl7Message, flushByte, false); + } + + public void sendFramedDataInMultiplePackets(String hl7Message, byte flushByte, boolean disconnectAfterSend) { + if (null == clientSocket) { + this.connect(); + } + + if (!clientSocket.isConnected()) { + throw new MllpJUnitResourceException("Cannot send message - client is not connected"); + } + if (null == outputStream) { + throw new MllpJUnitResourceException("Cannot send message - output stream is null"); + } + byte[] payloadBytes = hl7Message.getBytes(); + try { + if (sendStartOfBlock) { + outputStream.write(START_OF_BLOCK); + } else { + log.warn("Not sending START_OF_BLOCK"); + } + for (int i = 0; i < payloadBytes.length; ++i) { + outputStream.write(payloadBytes[i]); + if (flushByte == payloadBytes[i]) { + outputStream.flush(); + } + } + if (sendEndOfBlock) { + outputStream.write(END_OF_BLOCK); + } else { + log.warn("Not sending END_OF_BLOCK"); + } + if (sendEndOfData) { + outputStream.write(END_OF_DATA); + } else { + log.warn("Not sending END_OF_DATA"); + } + outputStream.flush(); + } catch (IOException e) { + log.error("Unable to send HL7 message", e); + throw new MllpJUnitResourceException("Unable to send HL7 message", e); + } + + if (disconnectAfterSend) { + log.warn("Closing TCP connection"); + disconnect(); + } + } + + public String receiveFramedData() throws SocketException, SocketTimeoutException { + return receiveFramedData(soTimeout); + } + + public String receiveFramedData(int timout) throws SocketException, SocketTimeoutException { + if (!isConnected()) { + throw new MllpJUnitResourceException("Cannot receive acknowledgement - client is not connected"); + } + if (null == outputStream) { + throw new MllpJUnitResourceException("Cannot receive acknowledgement - output stream is null"); + } + + clientSocket.setSoTimeout(timout); + StringBuilder acknowledgement = new StringBuilder(); + try { + int firstByte = inputStream.read(); + if (START_OF_BLOCK != firstByte) { + if (isConnected()) { + if (END_OF_STREAM == firstByte) { + log.warn("END_OF_STREAM reached while waiting for START_OF_BLOCK - closing socket"); + try { + clientSocket.close(); + } catch (Exception ex) { + log.warn("Exception encountered closing socket after receiving END_OF_STREAM while waiting for START_OF_BLOCK"); + } + return ""; + } else { + log.error("Acknowledgement did not start with START_OF_BLOCK: {}", firstByte); + throw new MllpJUnitResourceCorruptFrameException("Message did not start with START_OF_BLOCK"); + } + } else { + throw new MllpJUnitResourceException("Connection terminated"); + } + } + boolean readingMessage = true; + while (readingMessage) { + int nextByte = inputStream.read(); + switch (nextByte) { + case -1: + throw new MllpJUnitResourceCorruptFrameException("Reached end of stream before END_OF_BLOCK"); + case START_OF_BLOCK: + throw new MllpJUnitResourceCorruptFrameException("Received START_OF_BLOCK before END_OF_BLOCK"); + case END_OF_BLOCK: + if (END_OF_DATA != inputStream.read()) { + throw new MllpJUnitResourceCorruptFrameException("END_OF_BLOCK was not followed by END_OF_DATA"); + } + readingMessage = false; + break; + default: + acknowledgement.append((char) nextByte); + } + } + } catch (SocketTimeoutException timeoutEx) { + if (0 < acknowledgement.length()) { + log.error("Timeout waiting for acknowledgement", timeoutEx); + } else { + log.error("Timeout while reading acknowledgement\n" + acknowledgement.toString().replace('\r', '\n'), timeoutEx); + } + throw new MllpJUnitResourceTimeoutException("Timeout while reading acknowledgement", timeoutEx); + } catch (IOException e) { + log.error("Unable to read HL7 acknowledgement", e); + throw new MllpJUnitResourceException("Unable to read HL7 acknowledgement", e); + } + + return acknowledgement.toString(); + } + + public String receiveData() throws SocketException, SocketTimeoutException { + return receiveData(soTimeout); + } + + public String receiveData(int timeout) throws SocketException, SocketTimeoutException { + clientSocket.setSoTimeout(timeout); + StringBuilder availableInput = new StringBuilder(); + + try { + do { + availableInput.append((char) inputStream.read()); + } while (0 < inputStream.available()); + } catch (SocketTimeoutException timeoutEx) { + log.error("Timeout while receiving available input", timeoutEx); + throw new MllpJUnitResourceTimeoutException("Timeout while receiving available input", timeoutEx); + } catch (IOException e) { + log.warn("Exception encountered eating available input", e); + throw new MllpJUnitResourceException("Exception encountered eating available input", e); + } + + return availableInput.toString(); + } + + public String eatData() throws SocketException, SocketTimeoutException { + return eatData(soTimeout); + } + + public String eatData(int timeout) throws SocketException { + clientSocket.setSoTimeout(timeout); + + StringBuilder availableInput = new StringBuilder(); + try { + while (0 < inputStream.available()) { + availableInput.append((char) inputStream.read()); + } + } catch (IOException e) { + log.warn("Exception encountered eating available input", e); + throw new MllpJUnitResourceException("Exception encountered eating available input", e); + } + + return availableInput.toString(); + } + + public String sendMessageAndWaitForAcknowledgement(String hl7Data) throws SocketException, SocketTimeoutException { + sendFramedData(hl7Data); + return receiveFramedData(); + } + + public String sendMessageAndWaitForAcknowledgement(String hl7Data, int acknwoledgementTimeout) throws SocketException, SocketTimeoutException { + sendFramedData(hl7Data); + return receiveFramedData(acknwoledgementTimeout); + } + + public String getMllpHost() { + return mllpHost; + } + + public void setMllpHost(String mllpHost) { + this.mllpHost = mllpHost; + } + + public int getMllpPort() { + return mllpPort; + } + + public void setMllpPort(int mllpPort) { + this.mllpPort = mllpPort; + } + + public boolean isSendStartOfBlock() { + return sendStartOfBlock; + } + + public void setSendStartOfBlock(boolean sendStartOfBlock) { + this.sendStartOfBlock = sendStartOfBlock; + } + + public boolean isSendEndOfBlock() { + return sendEndOfBlock; + } + + public void setSendEndOfBlock(boolean sendEndOfBlock) { + this.sendEndOfBlock = sendEndOfBlock; + } + + public boolean isSendEndOfData() { + return sendEndOfData; + } + + public void setSendEndOfData(boolean sendEndOfData) { + this.sendEndOfData = sendEndOfData; + } + + public int getConnectTimeout() { + return connectTimeout; + } + + public void setConnectTimeout(int connectTimeout) { + this.connectTimeout = connectTimeout; + } + + public int getSoTimeout() { + return soTimeout; + } + + public void setSoTimeout(int soTimeout) { + this.soTimeout = soTimeout; + } + + public boolean isReuseAddress() { + return reuseAddress; + } + + public void setReuseAddress(boolean reuseAddress) { + this.reuseAddress = reuseAddress; + } + + public boolean isTcpNoDelay() { + return tcpNoDelay; + } + + public void setTcpNoDelay(boolean tcpNoDelay) { + this.tcpNoDelay = tcpNoDelay; + } + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/camel/blob/bd1661b2/components/camel-mllp/src/test/java/org/apache/camel/test/junit/rule/mllp/MllpJUnitResourceCorruptFrameException.java ---------------------------------------------------------------------- diff --git a/components/camel-mllp/src/test/java/org/apache/camel/test/junit/rule/mllp/MllpJUnitResourceCorruptFrameException.java b/components/camel-mllp/src/test/java/org/apache/camel/test/junit/rule/mllp/MllpJUnitResourceCorruptFrameException.java new file mode 100644 index 0000000..9fbbdfe --- /dev/null +++ b/components/camel-mllp/src/test/java/org/apache/camel/test/junit/rule/mllp/MllpJUnitResourceCorruptFrameException.java @@ -0,0 +1,38 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package org.apache.camel.test.junit.rule.mllp; + +/** + * Thrown when one of the MLLP JUnit Rules encounters a corrupt MLLP Frame + */ +public class MllpJUnitResourceCorruptFrameException extends MllpJUnitResourceException { + public MllpJUnitResourceCorruptFrameException(String message) { + super(message); + } + + public MllpJUnitResourceCorruptFrameException(String message, Throwable cause) { + super(message, cause); + } + + public MllpJUnitResourceCorruptFrameException(Throwable cause) { + super(cause); + } + + public MllpJUnitResourceCorruptFrameException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/bd1661b2/components/camel-mllp/src/test/java/org/apache/camel/test/junit/rule/mllp/MllpJUnitResourceException.java ---------------------------------------------------------------------- diff --git a/components/camel-mllp/src/test/java/org/apache/camel/test/junit/rule/mllp/MllpJUnitResourceException.java b/components/camel-mllp/src/test/java/org/apache/camel/test/junit/rule/mllp/MllpJUnitResourceException.java new file mode 100644 index 0000000..e5a6c4e --- /dev/null +++ b/components/camel-mllp/src/test/java/org/apache/camel/test/junit/rule/mllp/MllpJUnitResourceException.java @@ -0,0 +1,38 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package org.apache.camel.test.junit.rule.mllp; + +/** + * Base Exception for MLLP JUnit Rules + */ +public class MllpJUnitResourceException extends RuntimeException { + public MllpJUnitResourceException(String message) { + super(message); + } + + public MllpJUnitResourceException(String message, Throwable cause) { + super(message, cause); + } + + public MllpJUnitResourceException(Throwable cause) { + super(cause); + } + + public MllpJUnitResourceException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/bd1661b2/components/camel-mllp/src/test/java/org/apache/camel/test/junit/rule/mllp/MllpJUnitResourceTimeoutException.java ---------------------------------------------------------------------- diff --git a/components/camel-mllp/src/test/java/org/apache/camel/test/junit/rule/mllp/MllpJUnitResourceTimeoutException.java b/components/camel-mllp/src/test/java/org/apache/camel/test/junit/rule/mllp/MllpJUnitResourceTimeoutException.java new file mode 100644 index 0000000..8e6a2f6 --- /dev/null +++ b/components/camel-mllp/src/test/java/org/apache/camel/test/junit/rule/mllp/MllpJUnitResourceTimeoutException.java @@ -0,0 +1,38 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package org.apache.camel.test.junit.rule.mllp; + +/** + * Thrown when one of the MLLP JUnit Rules encounters an unexpected timeout + */ +public class MllpJUnitResourceTimeoutException extends MllpJUnitResourceException { + public MllpJUnitResourceTimeoutException(String message) { + super(message); + } + + public MllpJUnitResourceTimeoutException(String message, Throwable cause) { + super(message, cause); + } + + public MllpJUnitResourceTimeoutException(Throwable cause) { + super(cause); + } + + public MllpJUnitResourceTimeoutException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +}