Author: davsclaus Date: Tue Jul 6 05:49:47 2010 New Revision: 960792 URL: http://svn.apache.org/viewvc?rev=960792&view=rev Log: CAMEL-2908: Added textline delimiter configuration and auto append missing delimiter options.
Added: camel/trunk/components/camel-netty/src/main/java/org/apache/camel/component/netty/TextLineDelimiter.java (with props) camel/trunk/components/camel-netty/src/test/java/org/apache/camel/component/netty/NettyTextlineInOnlyNullDelimiterTest.java - copied, changed from r960773, camel/trunk/components/camel-netty/src/test/java/org/apache/camel/component/netty/NettyTextlineInOnlyTest.java Modified: camel/trunk/components/camel-mina/src/main/java/org/apache/camel/component/mina/TextLineDelimiter.java camel/trunk/components/camel-netty/src/main/java/org/apache/camel/component/netty/NettyConfiguration.java camel/trunk/components/camel-netty/src/main/java/org/apache/camel/component/netty/NettyHelper.java camel/trunk/components/camel-netty/src/main/java/org/apache/camel/component/netty/NettyProducer.java camel/trunk/components/camel-netty/src/main/java/org/apache/camel/component/netty/handlers/ServerChannelHandler.java camel/trunk/components/camel-netty/src/test/java/org/apache/camel/component/netty/NettyTcpWithInOutUsingPlainSocketTest.java camel/trunk/components/camel-netty/src/test/java/org/apache/camel/component/netty/NettyTextlineInOnlyTest.java camel/trunk/components/camel-netty/src/test/java/org/apache/camel/component/netty/NettyUdpWithInOutUsingPlainSocketTest.java Modified: camel/trunk/components/camel-mina/src/main/java/org/apache/camel/component/mina/TextLineDelimiter.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-mina/src/main/java/org/apache/camel/component/mina/TextLineDelimiter.java?rev=960792&r1=960791&r2=960792&view=diff ============================================================================== --- camel/trunk/components/camel-mina/src/main/java/org/apache/camel/component/mina/TextLineDelimiter.java (original) +++ camel/trunk/components/camel-mina/src/main/java/org/apache/camel/component/mina/TextLineDelimiter.java Tue Jul 6 05:49:47 2010 @@ -17,7 +17,7 @@ package org.apache.camel.component.mina; /** - * Possible text line delmiters to be used with the textline codec. + * Possible text line delimiters to be used with the textline codec. */ public enum TextLineDelimiter { DEFAULT, AUTO, UNIX, WINDOWS, MAC Modified: camel/trunk/components/camel-netty/src/main/java/org/apache/camel/component/netty/NettyConfiguration.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-netty/src/main/java/org/apache/camel/component/netty/NettyConfiguration.java?rev=960792&r1=960791&r2=960792&view=diff ============================================================================== --- camel/trunk/components/camel-netty/src/main/java/org/apache/camel/component/netty/NettyConfiguration.java (original) +++ camel/trunk/components/camel-netty/src/main/java/org/apache/camel/component/netty/NettyConfiguration.java Tue Jul 6 05:49:47 2010 @@ -30,6 +30,8 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.jboss.netty.channel.ChannelDownstreamHandler; import org.jboss.netty.channel.ChannelUpstreamHandler; +import org.jboss.netty.handler.codec.frame.DelimiterBasedFrameDecoder; +import org.jboss.netty.handler.codec.frame.Delimiters; import org.jboss.netty.handler.codec.serialization.ObjectDecoder; import org.jboss.netty.handler.codec.serialization.ObjectEncoder; import org.jboss.netty.handler.codec.string.StringDecoder; @@ -52,6 +54,9 @@ public class NettyConfiguration implemen private boolean reuseAddress = true; private boolean sync = true; private boolean textline; + private TextLineDelimiter delimiter = TextLineDelimiter.LINE; + private boolean autoAppendDelimiter = true; + private int decorderMaxLineLength = 1024; private String encoding; private String passphrase; private File keyStoreFile; @@ -123,10 +128,12 @@ public class NettyConfiguration implemen if (isTextline()) { Charset charset = getEncoding() != null ? Charset.forName(getEncoding()) : CharsetUtil.UTF_8; encoders.add(new StringEncoder(charset)); + decoders.add(new DelimiterBasedFrameDecoder(decorderMaxLineLength, true, delimiter == TextLineDelimiter.LINE ? Delimiters.lineDelimiter() : Delimiters.nulDelimiter())); decoders.add(new StringDecoder(charset)); if (LOG.isDebugEnabled()) { - LOG.debug("Using textline encoders and decoders with charset: " + charset); + LOG.debug("Using textline encoders and decoders with charset: " + charset + ", delimiter: " + + delimiter + " and decoderMaxLineLength: " + decorderMaxLineLength); } } else { // object serializable is then used @@ -158,7 +165,7 @@ public class NettyConfiguration implemen return Charset.forName(encoding).name(); } - protected boolean isTcp() { + public boolean isTcp() { return protocol.equalsIgnoreCase("tcp"); } @@ -242,6 +249,30 @@ public class NettyConfiguration implemen this.textline = textline; } + public int getDecorderMaxLineLength() { + return decorderMaxLineLength; + } + + public void setDecorderMaxLineLength(int decorderMaxLineLength) { + this.decorderMaxLineLength = decorderMaxLineLength; + } + + public TextLineDelimiter getDelimiter() { + return delimiter; + } + + public void setDelimiter(TextLineDelimiter delimiter) { + this.delimiter = delimiter; + } + + public boolean isAutoAppendDelimiter() { + return autoAppendDelimiter; + } + + public void setAutoAppendDelimiter(boolean autoAppendDelimiter) { + this.autoAppendDelimiter = autoAppendDelimiter; + } + public String getEncoding() { return encoding; } Modified: camel/trunk/components/camel-netty/src/main/java/org/apache/camel/component/netty/NettyHelper.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-netty/src/main/java/org/apache/camel/component/netty/NettyHelper.java?rev=960792&r1=960791&r2=960792&view=diff ============================================================================== --- camel/trunk/components/camel-netty/src/main/java/org/apache/camel/component/netty/NettyHelper.java (original) +++ camel/trunk/components/camel-netty/src/main/java/org/apache/camel/component/netty/NettyHelper.java Tue Jul 6 05:49:47 2010 @@ -20,6 +20,7 @@ import java.net.SocketAddress; import org.apache.camel.CamelExchangeException; import org.apache.camel.Exchange; +import org.apache.camel.NoTypeConversionAvailableException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.jboss.netty.channel.Channel; @@ -39,11 +40,49 @@ public final class NettyHelper { } /** + * Gets the string body to be used when sending with the textline codec. + * + * @param body the current body + * @param exchange the exchange + * @param delimiter the textline delimiter + * @param autoAppendDelimiter whether absent delimiter should be auto appended + * @return the string body to send + * @throws NoTypeConversionAvailableException is thrown if the current body could not be converted to a String type + */ + public static String getTextlineBody(Object body, Exchange exchange, TextLineDelimiter delimiter, boolean autoAppendDelimiter) throws NoTypeConversionAvailableException { + String s = exchange.getContext().getTypeConverter().mandatoryConvertTo(String.class, exchange, body); + + // auto append delimiter if missing? + if (autoAppendDelimiter) { + if (TextLineDelimiter.LINE.equals(delimiter)) { + // line delimiter so ensure it ends with newline + if (!s.endsWith("\n")) { + if (LOG.isTraceEnabled()) { + LOG.trace("Auto appending missing newline delimiter to body"); + } + s = s + "\n"; + } + } else { + // null delimiter so ensure it ends with null + if (!s.endsWith("\u0000")) { + if (LOG.isTraceEnabled()) { + LOG.trace("Auto appending missing null delimiter to body"); + } + s = s + "\u0000"; + } + } + } + + return s; + } + + /** * Writes the given body to Netty channel. Will wait until the body has been written. * - * @param channel the Netty channel - * @param body the body to write (send) - * @param exchange the exchange + * @param channel the Netty channel + * @param remoteAddress the remote address when using UDP + * @param body the body to write (send) + * @param exchange the exchange * @throws CamelExchangeException is thrown if the body could not be written for some reasons * (eg remote connection is closed etc.) */ @@ -69,6 +108,11 @@ public final class NettyHelper { } } + /** + * Closes the given channel + * + * @param channel the channel to close + */ public static void close(Channel channel) { if (channel != null) { if (LOG.isTraceEnabled()) { Modified: camel/trunk/components/camel-netty/src/main/java/org/apache/camel/component/netty/NettyProducer.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-netty/src/main/java/org/apache/camel/component/netty/NettyProducer.java?rev=960792&r1=960791&r2=960792&view=diff ============================================================================== --- camel/trunk/components/camel-netty/src/main/java/org/apache/camel/component/netty/NettyProducer.java (original) +++ camel/trunk/components/camel-netty/src/main/java/org/apache/camel/component/netty/NettyProducer.java Tue Jul 6 05:49:47 2010 @@ -129,10 +129,11 @@ public class NettyProducer extends Defau callback.done(true); return true; } + // if textline enabled then covert to a String which must be used for textline if (getConfiguration().isTextline()) { try { - body = context.getTypeConverter().mandatoryConvertTo(String.class, exchange, body); + body = NettyHelper.getTextlineBody(body, exchange, getConfiguration().getDelimiter(), getConfiguration().isAutoAppendDelimiter()); } catch (NoTypeConversionAvailableException e) { exchange.setException(e); callback.done(true); Added: camel/trunk/components/camel-netty/src/main/java/org/apache/camel/component/netty/TextLineDelimiter.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-netty/src/main/java/org/apache/camel/component/netty/TextLineDelimiter.java?rev=960792&view=auto ============================================================================== --- camel/trunk/components/camel-netty/src/main/java/org/apache/camel/component/netty/TextLineDelimiter.java (added) +++ camel/trunk/components/camel-netty/src/main/java/org/apache/camel/component/netty/TextLineDelimiter.java Tue Jul 6 05:49:47 2010 @@ -0,0 +1,10 @@ +package org.apache.camel.component.netty; + +/** + * Possible text line delimiters to be used with the textline codec. + * + * @version $Revision$ + */ +public enum TextLineDelimiter { + LINE, NULL; +} Propchange: camel/trunk/components/camel-netty/src/main/java/org/apache/camel/component/netty/TextLineDelimiter.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: camel/trunk/components/camel-netty/src/main/java/org/apache/camel/component/netty/TextLineDelimiter.java ------------------------------------------------------------------------------ svn:keywords = Rev Date Modified: camel/trunk/components/camel-netty/src/main/java/org/apache/camel/component/netty/handlers/ServerChannelHandler.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-netty/src/main/java/org/apache/camel/component/netty/handlers/ServerChannelHandler.java?rev=960792&r1=960791&r2=960792&view=diff ============================================================================== --- camel/trunk/components/camel-netty/src/main/java/org/apache/camel/component/netty/handlers/ServerChannelHandler.java (original) +++ camel/trunk/components/camel-netty/src/main/java/org/apache/camel/component/netty/handlers/ServerChannelHandler.java Tue Jul 6 05:49:47 2010 @@ -135,17 +135,17 @@ public class ServerChannelHandler extend } else { // if textline enabled then covert to a String which must be used for textline if (consumer.getConfiguration().isTextline()) { - body = consumer.getContext().getTypeConverter().mandatoryConvertTo(String.class, exchange, body); + body = NettyHelper.getTextlineBody(body, exchange, consumer.getConfiguration().getDelimiter(), consumer.getConfiguration().isAutoAppendDelimiter()); } // we got a body to write if (LOG.isDebugEnabled()) { LOG.debug("Writing body: " + body); } - if (consumer.getConfiguration().getProtocol().equalsIgnoreCase("udp")) { - NettyHelper.writeBodySync(messageEvent.getChannel(), messageEvent.getRemoteAddress(), body, exchange); - } else { + if (consumer.getConfiguration().isTcp()) { NettyHelper.writeBodySync(messageEvent.getChannel(), null, body, exchange); + } else { + NettyHelper.writeBodySync(messageEvent.getChannel(), messageEvent.getRemoteAddress(), body, exchange); } } Modified: camel/trunk/components/camel-netty/src/test/java/org/apache/camel/component/netty/NettyTcpWithInOutUsingPlainSocketTest.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-netty/src/test/java/org/apache/camel/component/netty/NettyTcpWithInOutUsingPlainSocketTest.java?rev=960792&r1=960791&r2=960792&view=diff ============================================================================== --- camel/trunk/components/camel-netty/src/test/java/org/apache/camel/component/netty/NettyTcpWithInOutUsingPlainSocketTest.java (original) +++ camel/trunk/components/camel-netty/src/test/java/org/apache/camel/component/netty/NettyTcpWithInOutUsingPlainSocketTest.java Tue Jul 6 05:49:47 2010 @@ -89,7 +89,8 @@ public class NettyTcpWithInOutUsingPlain InputStream is = null; try { os = soc.getOutputStream(); - os.write(input.getBytes()); + // must append the line delimiter + os.write((input + "\n").getBytes()); is = soc.getInputStream(); int len = is.read(buf); Copied: camel/trunk/components/camel-netty/src/test/java/org/apache/camel/component/netty/NettyTextlineInOnlyNullDelimiterTest.java (from r960773, camel/trunk/components/camel-netty/src/test/java/org/apache/camel/component/netty/NettyTextlineInOnlyTest.java) URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-netty/src/test/java/org/apache/camel/component/netty/NettyTextlineInOnlyNullDelimiterTest.java?p2=camel/trunk/components/camel-netty/src/test/java/org/apache/camel/component/netty/NettyTextlineInOnlyNullDelimiterTest.java&p1=camel/trunk/components/camel-netty/src/test/java/org/apache/camel/component/netty/NettyTextlineInOnlyTest.java&r1=960773&r2=960792&rev=960792&view=diff ============================================================================== --- camel/trunk/components/camel-netty/src/test/java/org/apache/camel/component/netty/NettyTextlineInOnlyTest.java (original) +++ camel/trunk/components/camel-netty/src/test/java/org/apache/camel/component/netty/NettyTextlineInOnlyNullDelimiterTest.java Tue Jul 6 05:49:47 2010 @@ -23,13 +23,13 @@ import org.junit.Test; /** * @version $Revision$ */ -public class NettyTextlineInOnlyTest extends CamelTestSupport { +public class NettyTextlineInOnlyNullDelimiterTest extends CamelTestSupport { @Test - public void testTextlineInOnly() throws Exception { - getMockEndpoint("mock:result").expectedBodiesReceived("Hello World\nHow are you?"); - - template.sendBody("netty:tcp://localhost:5149?textline=true&sync=false", "Hello World\nHow are you?"); + public void testTextlineInOnlyNull() throws Exception { + getMockEndpoint("mock:result").expectedBodiesReceived("Hello World"); + + template.sendBody("netty:tcp://localhost:5149?textline=true&delimiter=NULL&sync=false", "Hello World\u0000"); assertMockEndpointsSatisfied(); } @@ -39,11 +39,11 @@ public class NettyTextlineInOnlyTest ext return new RouteBuilder() { @Override public void configure() throws Exception { - from("netty:tcp://localhost:5149?textline=true&sync=false") + from("netty:tcp://localhost:5149?textline=true&delimiter=NULL&sync=false") // body should be a String when using textline codec .validate(body().isInstanceOf(String.class)) .to("mock:result"); } }; } -} +} \ No newline at end of file Modified: camel/trunk/components/camel-netty/src/test/java/org/apache/camel/component/netty/NettyTextlineInOnlyTest.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-netty/src/test/java/org/apache/camel/component/netty/NettyTextlineInOnlyTest.java?rev=960792&r1=960791&r2=960792&view=diff ============================================================================== --- camel/trunk/components/camel-netty/src/test/java/org/apache/camel/component/netty/NettyTextlineInOnlyTest.java (original) +++ camel/trunk/components/camel-netty/src/test/java/org/apache/camel/component/netty/NettyTextlineInOnlyTest.java Tue Jul 6 05:49:47 2010 @@ -26,10 +26,28 @@ import org.junit.Test; public class NettyTextlineInOnlyTest extends CamelTestSupport { @Test + public void testTextlineInOnlyDual() throws Exception { + getMockEndpoint("mock:result").expectedBodiesReceived("Hello World", "how are you?"); + + template.sendBody("netty:tcp://localhost:5149?textline=true&sync=false", "Hello World\nhow are you?\n"); + + assertMockEndpointsSatisfied(); + } + + @Test + public void testTextlineInOnlyAutoAppend() throws Exception { + getMockEndpoint("mock:result").expectedBodiesReceived("Hello World"); + + template.sendBody("netty:tcp://localhost:5149?textline=true&sync=false", "Hello World"); + + assertMockEndpointsSatisfied(); + } + + @Test public void testTextlineInOnly() throws Exception { - getMockEndpoint("mock:result").expectedBodiesReceived("Hello World\nHow are you?"); - - template.sendBody("netty:tcp://localhost:5149?textline=true&sync=false", "Hello World\nHow are you?"); + getMockEndpoint("mock:result").expectedBodiesReceived("Hello World"); + + template.sendBody("netty:tcp://localhost:5149?textline=true&sync=false", "Hello World\n"); assertMockEndpointsSatisfied(); } Modified: camel/trunk/components/camel-netty/src/test/java/org/apache/camel/component/netty/NettyUdpWithInOutUsingPlainSocketTest.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-netty/src/test/java/org/apache/camel/component/netty/NettyUdpWithInOutUsingPlainSocketTest.java?rev=960792&r1=960791&r2=960792&view=diff ============================================================================== --- camel/trunk/components/camel-netty/src/test/java/org/apache/camel/component/netty/NettyUdpWithInOutUsingPlainSocketTest.java (original) +++ camel/trunk/components/camel-netty/src/test/java/org/apache/camel/component/netty/NettyUdpWithInOutUsingPlainSocketTest.java Tue Jul 6 05:49:47 2010 @@ -39,14 +39,15 @@ public class NettyUdpWithInOutUsingPlain public void testSendAndReceiveOnce() throws Exception { String out = sendAndReceiveUdpMessages("World"); assertNotNull("should receive data", out); - assertEquals("Hello World", out); + assertEquals("Hello World\n", out); } private String sendAndReceiveUdpMessages(String input) throws Exception { DatagramSocket socket = new DatagramSocket(); InetAddress address = InetAddress.getByName("127.0.0.1"); - byte[] data = input.getBytes(); + // must append delimiter + byte[] data = (input + "\n").getBytes(); DatagramPacket packet = new DatagramPacket(data, data.length, address, PORT); LOG.debug("+++ Sending data +++");