CAMEL-6302: Mina udp codec should use byte[] instead of String. Thanks to Thomas Termin for the patches. git-svn-id: https://svn.apache.org/repos/asf/camel/trunk@1476113 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/components/camel-mina/src/main/java/org/apache/camel/component/mina/MinaComponent.java b/components/camel-mina/src/main/java/org/apache/camel/component/mina/MinaComponent.java index c197e66..68375d5 100644 --- a/components/camel-mina/src/main/java/org/apache/camel/component/mina/MinaComponent.java +++ b/components/camel-mina/src/main/java/org/apache/camel/component/mina/MinaComponent.java
@@ -330,12 +330,10 @@ protected void configureDataGramCodecFactory(final String type, final IoServiceConfig config, final MinaConfiguration configuration) { ProtocolCodecFactory codecFactory = configuration.getCodec(); if (codecFactory == null) { - final Charset charset = getEncodingParameter(type, configuration); - - codecFactory = new MinaUdpProtocolCodecFactory(getCamelContext(), charset); + codecFactory = new MinaUdpProtocolCodecFactory(getCamelContext()); if (LOG.isDebugEnabled()) { - LOG.debug("{}: Using CodecFactory: {} using encoding: {}", new Object[]{type, codecFactory, charset}); + LOG.debug("{}: Using CodecFactory: {}", new Object[]{type, codecFactory}); } }
diff --git a/components/camel-mina/src/main/java/org/apache/camel/component/mina/MinaUdpProtocolCodecFactory.java b/components/camel-mina/src/main/java/org/apache/camel/component/mina/MinaUdpProtocolCodecFactory.java index f15275d..9465930 100644 --- a/components/camel-mina/src/main/java/org/apache/camel/component/mina/MinaUdpProtocolCodecFactory.java +++ b/components/camel-mina/src/main/java/org/apache/camel/component/mina/MinaUdpProtocolCodecFactory.java
@@ -17,8 +17,6 @@ package org.apache.camel.component.mina; import java.nio.charset.CharacterCodingException; -import java.nio.charset.Charset; -import java.nio.charset.CharsetEncoder; import org.apache.camel.CamelContext; import org.apache.camel.NoTypeConversionAvailableException; @@ -31,27 +29,21 @@ import org.apache.mina.filter.codec.ProtocolEncoderOutput; /** - * @version + * @version */ public class MinaUdpProtocolCodecFactory implements ProtocolCodecFactory { - private final Charset charset; private final CamelContext context; - public MinaUdpProtocolCodecFactory(CamelContext context, Charset charset) { + public MinaUdpProtocolCodecFactory(CamelContext context) { this.context = context; - this.charset = charset; } public ProtocolEncoder getEncoder() throws Exception { return new ProtocolEncoder() { - private CharsetEncoder encoder; public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception { - if (encoder == null) { - encoder = charset.newEncoder(); - } - ByteBuffer buf = toByteBuffer(message, encoder); + ByteBuffer buf = toByteBuffer(message); buf.flip(); out.write(buf); } @@ -64,10 +56,11 @@ public ProtocolDecoder getDecoder() throws Exception { return new ProtocolDecoder() { - public void decode(IoSession session, ByteBuffer in, ProtocolDecoderOutput out) throws Exception { - // convert to bytes to write, we can not pass in the byte buffer as it could be sent to - // multiple mina sessions so we must convert it to bytes - byte[] bytes = context.getTypeConverter().convertTo(byte[].class, in); + public void decode(IoSession session, ByteBuffer in, + ProtocolDecoderOutput out) throws Exception { + // convert to bytes to write, we can not pass in the byte buffer + // as it could be sent to multiple mina sessions so we must convert it to bytes + byte[] bytes = context.getTypeConverter().mandatoryConvertTo(byte[].class, in); out.write(bytes); } @@ -81,17 +74,15 @@ }; } - private ByteBuffer toByteBuffer(Object message, CharsetEncoder encoder) - throws CharacterCodingException, NoTypeConversionAvailableException { - String value = context.getTypeConverter().convertTo(String.class, message); + private ByteBuffer toByteBuffer(Object message) throws CharacterCodingException, NoTypeConversionAvailableException { + // try to convert it to a byte array + byte[] value = context.getTypeConverter().tryConvertTo(byte[].class, message); if (value != null) { - ByteBuffer answer = ByteBuffer.allocate(value.length()).setAutoExpand(false); - answer.putString(value, encoder); + ByteBuffer answer = ByteBuffer.allocate(value.length).setAutoExpand(false); + answer.put(value); return answer; } - - // failback to use a byte buffer converter + // fallback to use a byte buffer converter return context.getTypeConverter().mandatoryConvertTo(ByteBuffer.class, message); } - }
diff --git a/components/camel-mina/src/test/java/org/apache/camel/component/mina/MinaUdpUsingTemplateTest.java b/components/camel-mina/src/test/java/org/apache/camel/component/mina/MinaUdpUsingTemplateTest.java index cb6643b..83d40d0c 100644 --- a/components/camel-mina/src/test/java/org/apache/camel/component/mina/MinaUdpUsingTemplateTest.java +++ b/components/camel-mina/src/test/java/org/apache/camel/component/mina/MinaUdpUsingTemplateTest.java
@@ -24,7 +24,7 @@ import org.junit.Test; /** - * @version + * @version */ public class MinaUdpUsingTemplateTest extends BaseMinaTest { @@ -37,8 +37,6 @@ endpoint.expectedBodiesReceived("Hello Message: 0", "Hello Message: 1", "Hello Message: 2"); sendUdpMessages(); - // sleeping for while to let the mock endpoint get all the message - Thread.sleep(2000); assertMockEndpointsSatisfied(); } @@ -57,9 +55,6 @@ byte[] in = "Hello from bytes".getBytes(); template.sendBody("mina:udp://127.0.0.1:{{port}}?sync=false", in); - // sleeping for while to let the mock endpoint get all the message - Thread.sleep(2000); - assertMockEndpointsSatisfied(); List<Exchange> list = endpoint.getReceivedExchanges(); byte[] out = list.get(0).getIn().getBody(byte[].class); @@ -69,10 +64,49 @@ } } + @Test + public void testSendingRawByteMessage() throws Exception { + MockEndpoint endpoint = getMockEndpoint("mock:result"); + endpoint.expectedMessageCount(1); + + String toSend = "ef3e00559f5faf0262f5ff0962d9008daa91001cd46b0fa9330ef0f3030fff250e46f72444d1cc501678c351e04b8004c" + + "4000002080000fe850bbe011030000008031b031bfe9251305441593830354720020800050440ff"; + byte[] in = fromHexString(toSend); + template.sendBody("mina:udp://127.0.0.1:{{port}}?sync=false", in); + + assertMockEndpointsSatisfied(); + List<Exchange> list = endpoint.getReceivedExchanges(); + byte[] out = list.get(0).getIn().getBody(byte[].class); + + for (int i = 0; i < in.length; i++) { + assertEquals("The bytes should be the same", in[i], out[i]); + } + assertEquals("The strings should be the same", toSend, byteArrayToHex(out)); + } + + private String byteArrayToHex(byte[] bytes) { + StringBuilder sb = new StringBuilder(); + for (byte b : bytes) { + sb.append(String.format("%02x", b & 0xff)); + } + return sb.toString(); + } + + private byte[] fromHexString(String hexstr) { + byte data[] = new byte[hexstr.length() / 2]; + int i = 0; + for (int n = hexstr.length(); i < n; i += 2) { + data[i / 2] = (Integer.decode("0x" + hexstr.charAt(i) + + hexstr.charAt(i + 1))).byteValue(); + } + return data; + } + protected RouteBuilder createRouteBuilder() { return new RouteBuilder() { public void configure() { - from("mina:udp://127.0.0.1:{{port}}?sync=false&minaLogger=true").to("mock:result"); + from("mina:udp://127.0.0.1:{{port}}?sync=false&minaLogger=true") + .to("mock:result"); } }; }
diff --git a/components/camel-mina2/src/main/java/org/apache/camel/component/mina2/Mina2Consumer.java b/components/camel-mina2/src/main/java/org/apache/camel/component/mina2/Mina2Consumer.java index d175eb6..31267b2 100644 --- a/components/camel-mina2/src/main/java/org/apache/camel/component/mina2/Mina2Consumer.java +++ b/components/camel-mina2/src/main/java/org/apache/camel/component/mina2/Mina2Consumer.java
@@ -224,12 +224,10 @@ protected void configureDataGramCodecFactory(final String type, final IoService service, final Mina2Configuration configuration) { ProtocolCodecFactory codecFactory = configuration.getCodec(); if (codecFactory == null) { - final Charset charset = getEncodingParameter(type, configuration); - - codecFactory = new Mina2UdpProtocolCodecFactory(this.getEndpoint().getCamelContext(), charset); + codecFactory = new Mina2UdpProtocolCodecFactory(this.getEndpoint().getCamelContext()); if (LOG.isDebugEnabled()) { - LOG.debug("{}: Using CodecFactory: {} using encoding: {}", new Object[]{type, codecFactory, charset}); + LOG.debug("{}: Using CodecFactory: {}", new Object[]{type, codecFactory}); } }
diff --git a/components/camel-mina2/src/main/java/org/apache/camel/component/mina2/Mina2Producer.java b/components/camel-mina2/src/main/java/org/apache/camel/component/mina2/Mina2Producer.java index c13f824..139e3a8 100644 --- a/components/camel-mina2/src/main/java/org/apache/camel/component/mina2/Mina2Producer.java +++ b/components/camel-mina2/src/main/java/org/apache/camel/component/mina2/Mina2Producer.java
@@ -388,12 +388,10 @@ protected void configureDataGramCodecFactory(final String type, final IoService service, final Mina2Configuration configuration) { ProtocolCodecFactory codecFactory = configuration.getCodec(); if (codecFactory == null) { - final Charset charset = getEncodingParameter(type, configuration); - - codecFactory = new Mina2UdpProtocolCodecFactory(this.getEndpoint().getCamelContext(), charset); + codecFactory = new Mina2UdpProtocolCodecFactory(this.getEndpoint().getCamelContext()); if (LOG.isDebugEnabled()) { - LOG.debug("{}: Using CodecFactory: {} using encoding: {}", new Object[]{type, codecFactory, charset}); + LOG.debug("{}: Using CodecFactory: {}", new Object[]{type, codecFactory}); } }
diff --git a/components/camel-mina2/src/main/java/org/apache/camel/component/mina2/Mina2UdpProtocolCodecFactory.java b/components/camel-mina2/src/main/java/org/apache/camel/component/mina2/Mina2UdpProtocolCodecFactory.java index 2a5fde4..1b2a27d 100644 --- a/components/camel-mina2/src/main/java/org/apache/camel/component/mina2/Mina2UdpProtocolCodecFactory.java +++ b/components/camel-mina2/src/main/java/org/apache/camel/component/mina2/Mina2UdpProtocolCodecFactory.java
@@ -17,8 +17,6 @@ package org.apache.camel.component.mina2; import java.nio.charset.CharacterCodingException; -import java.nio.charset.Charset; -import java.nio.charset.CharsetEncoder; import org.apache.camel.CamelContext; import org.apache.camel.NoTypeConversionAvailableException; @@ -31,28 +29,21 @@ import org.apache.mina.filter.codec.ProtocolEncoderOutput; /** - * @version + * @version */ public class Mina2UdpProtocolCodecFactory implements ProtocolCodecFactory { - private final Charset charset; private final CamelContext context; - public Mina2UdpProtocolCodecFactory(CamelContext context, Charset charset) { + public Mina2UdpProtocolCodecFactory(CamelContext context) { this.context = context; - this.charset = charset; } public ProtocolEncoder getEncoder(IoSession session) throws Exception { return new ProtocolEncoder() { - private CharsetEncoder encoder; - public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception { - if (encoder == null) { - encoder = charset.newEncoder(); - } - IoBuffer buf = toIoBuffer(message, encoder); + IoBuffer buf = toIoBuffer(message); buf.flip(); out.write(buf); } @@ -83,16 +74,16 @@ }; } - private IoBuffer toIoBuffer(Object message, CharsetEncoder encoder) - throws CharacterCodingException, NoTypeConversionAvailableException { - String value = context.getTypeConverter().convertTo(String.class, message); + private IoBuffer toIoBuffer(Object message) throws CharacterCodingException, NoTypeConversionAvailableException { + //try to convert it to a byte array + byte[] value = context.getTypeConverter().tryConvertTo(byte[].class, message); if (value != null) { - IoBuffer answer = IoBuffer.allocate(value.length()).setAutoExpand(true); - answer.putString(value, encoder); + IoBuffer answer = IoBuffer.allocate(value.length).setAutoExpand(true); + answer.put(value); return answer; } - // failback to use a byte buffer converter + // fallback to use a byte buffer converter return context.getTypeConverter().mandatoryConvertTo(IoBuffer.class, message); } }
diff --git a/components/camel-mina2/src/test/java/org/apache/camel/component/mina2/Mina2UdpUsingTemplateTest.java b/components/camel-mina2/src/test/java/org/apache/camel/component/mina2/Mina2UdpUsingTemplateTest.java index 1d66b4b..e67b2c9 100644 --- a/components/camel-mina2/src/test/java/org/apache/camel/component/mina2/Mina2UdpUsingTemplateTest.java +++ b/components/camel-mina2/src/test/java/org/apache/camel/component/mina2/Mina2UdpUsingTemplateTest.java
@@ -24,7 +24,7 @@ import org.junit.Test; /** - * @version + * @version */ public class Mina2UdpUsingTemplateTest extends BaseMina2Test { @@ -37,8 +37,6 @@ endpoint.expectedBodiesReceived("Hello Message: 0", "Hello Message: 1", "Hello Message: 2"); sendUdpMessages(); - // sleeping for while to let the mock endpoint get all the message - Thread.sleep(2000); assertMockEndpointsSatisfied(); } @@ -57,9 +55,6 @@ byte[] in = "Hello from bytes".getBytes(); template.sendBody(String.format("mina2:udp://127.0.0.1:%1$s?sync=false", getPort()), in); - // sleeping for while to let the mock endpoint get all the message - Thread.sleep(2000); - assertMockEndpointsSatisfied(); List<Exchange> list = endpoint.getReceivedExchanges(); byte[] out = list.get(0).getIn().getBody(byte[].class); @@ -69,6 +64,44 @@ } } + @Test + public void testSendingRawByteMessage() throws Exception { + MockEndpoint endpoint = getMockEndpoint("mock:result"); + endpoint.expectedMessageCount(1); + + String toSend = "ef3e00559f5faf0262f5ff0962d9008daa91001cd46b0fa9330ef0f3030fff250e46f72444d1cc501678c351e04b8004c" + + "4000002080000fe850bbe011030000008031b031bfe9251305441593830354720020800050440ff"; + byte[] in = fromHexString(toSend); + template.sendBody(String.format("mina2:udp://127.0.0.1:%1$s?sync=false", getPort()), in); + + assertMockEndpointsSatisfied(); + List<Exchange> list = endpoint.getReceivedExchanges(); + byte[] out = list.get(0).getIn().getBody(byte[].class); + + for (int i = 0; i < in.length; i++) { + assertEquals("The bytes should be the same", in[i], out[i]); + } + assertEquals("The strings should be the same", toSend, byteArrayToHex(out)); + } + + private String byteArrayToHex(byte[] bytes) { + StringBuilder sb = new StringBuilder(); + for (byte b : bytes) { + sb.append(String.format("%02x", b & 0xff)); + } + return sb.toString(); + } + + private byte[] fromHexString(String hexstr) { + byte data[] = new byte[hexstr.length() / 2]; + int i = 0; + for (int n = hexstr.length(); i < n; i += 2) { + data[i / 2] = (Integer.decode("0x" + hexstr.charAt(i) + + hexstr.charAt(i + 1))).byteValue(); + } + return data; + } + protected RouteBuilder createRouteBuilder() { return new RouteBuilder() { public void configure() {