Merge "Fix channelInactive event handling in the netty pipeline for netconf."
authorTony Tkacik <ttkacik@cisco.com>
Mon, 8 Dec 2014 09:07:36 +0000 (09:07 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Mon, 8 Dec 2014 09:07:37 +0000 (09:07 +0000)
features/mdsal/pom.xml
opendaylight/md-sal/sal-distributed-datastore/pom.xml
opendaylight/netconf/netconf-monitoring/src/test/java/org/opendaylight/controller/netconf/monitoring/osgi/NetconfMonitoringActivatorTest.java
opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/ChunkedFramingMechanismEncoder.java
opendaylight/netconf/netconf-netty-util/src/test/java/org/opendaylight/controller/netconf/nettyutil/handler/ChunkedFramingMechanismEncoderTest.java
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/messages/NetconfMessageConstants.java

index 6f43768..6159922 100644 (file)
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal-core-api</artifactId>
     </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>sal-core-api</artifactId>
-    </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal-core-spi</artifactId>
index bd42a9c..cbaf278 100644 (file)
       <artifactId>yang-common</artifactId>
     </dependency>
 
-    <dependency>
-      <groupId>org.opendaylight.yangtools</groupId>
-      <artifactId>yang-data-api</artifactId>
-    </dependency>
-
     <dependency>
       <groupId>org.osgi</groupId>
       <artifactId>org.osgi.core</artifactId>
index 6664f3e..792a591 100644 (file)
@@ -40,6 +40,7 @@ public class NetconfMonitoringActivatorTest {
         ServiceReference<?>[] refs = new ServiceReference[2];
         doReturn(Arrays.asList(refs)).when(context).getServiceReferences(any(Class.class), anyString());
         doReturn(refs).when(context).getServiceReferences(anyString(), anyString());
+        doNothing().when(context).removeServiceListener(any(ServiceListener.class));
     }
 
     @Test
index c4cddb8..2287a58 100644 (file)
@@ -8,13 +8,12 @@
 
 package org.opendaylight.controller.netconf.nettyutil.handler;
 
+import com.google.common.base.Charsets;
 import com.google.common.base.Preconditions;
 import io.netty.buffer.ByteBuf;
-import io.netty.buffer.Unpooled;
 import io.netty.channel.ChannelHandlerContext;
 import io.netty.handler.codec.MessageToByteEncoder;
 import org.opendaylight.controller.netconf.util.messages.NetconfMessageConstants;
-import org.opendaylight.controller.netconf.util.messages.NetconfMessageHeader;
 
 public class ChunkedFramingMechanismEncoder extends MessageToByteEncoder<ByteBuf> {
     public static final int DEFAULT_CHUNK_SIZE = 8192;
@@ -27,9 +26,8 @@ public class ChunkedFramingMechanismEncoder extends MessageToByteEncoder<ByteBuf
         this(DEFAULT_CHUNK_SIZE);
     }
 
-    public ChunkedFramingMechanismEncoder(int chunkSize) {
-        Preconditions.checkArgument(chunkSize > MIN_CHUNK_SIZE);
-        Preconditions.checkArgument(chunkSize < MAX_CHUNK_SIZE);
+    public ChunkedFramingMechanismEncoder(final int chunkSize) {
+        Preconditions.checkArgument(chunkSize >= MIN_CHUNK_SIZE && chunkSize <= MAX_CHUNK_SIZE, "Unsupported chunk size %s", chunkSize);
         this.chunkSize = chunkSize;
     }
 
@@ -38,19 +36,17 @@ public class ChunkedFramingMechanismEncoder extends MessageToByteEncoder<ByteBuf
     }
 
     @Override
-    protected void encode(ChannelHandlerContext ctx, ByteBuf msg, ByteBuf out)  {
-        while (msg.readableBytes() > chunkSize) {
-            ByteBuf chunk = Unpooled.buffer(chunkSize);
-            chunk.writeBytes(createChunkHeader(chunkSize));
-            chunk.writeBytes(msg.readBytes(chunkSize));
-            ctx.write(chunk);
-        }
-        out.writeBytes(createChunkHeader(msg.readableBytes()));
-        out.writeBytes(msg.readBytes(msg.readableBytes()));
-        out.writeBytes(NetconfMessageConstants.END_OF_CHUNK);
-    }
+    protected void encode(final ChannelHandlerContext ctx, final ByteBuf msg, final ByteBuf out)  {
+        do {
+            final int xfer = Math.min(chunkSize, msg.readableBytes());
+
+            out.writeBytes(NetconfMessageConstants.START_OF_CHUNK);
+            out.writeBytes(String.valueOf(xfer).getBytes(Charsets.US_ASCII));
+            out.writeByte('\n');
 
-    private ByteBuf createChunkHeader(int chunkSize) {
-        return Unpooled.wrappedBuffer(NetconfMessageHeader.toBytes(chunkSize));
+            out.writeBytes(msg, xfer);
+        } while (msg.isReadable());
+
+        out.writeBytes(NetconfMessageConstants.END_OF_CHUNK);
     }
 }
index 556bece..4488c5e 100644 (file)
@@ -9,20 +9,16 @@
 package org.opendaylight.controller.netconf.nettyutil.handler;
 
 import static org.junit.Assert.assertEquals;
-import static org.mockito.Matchers.anyObject;
-import static org.mockito.Mockito.doAnswer;
-import com.google.common.collect.Lists;
+import static org.junit.Assert.assertTrue;
+import com.google.common.base.Charsets;
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
 import io.netty.channel.ChannelHandlerContext;
-import java.util.List;
+import java.nio.ByteBuffer;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-import org.opendaylight.controller.netconf.util.messages.NetconfMessageConstants;
 
 public class ChunkedFramingMechanismEncoderTest {
 
@@ -48,30 +44,20 @@ public class ChunkedFramingMechanismEncoderTest {
 
     @Test
     public void testEncode() throws Exception {
-        final List<ByteBuf> chunks = Lists.newArrayList();
-        doAnswer(new Answer<Object>() {
-            @Override
-            public Object answer(final InvocationOnMock invocation) throws Throwable {
-                chunks.add((ByteBuf) invocation.getArguments()[0]);
-                return null;
-            }
-        }).when(ctx).write(anyObject());
-
         final ChunkedFramingMechanismEncoder encoder = new ChunkedFramingMechanismEncoder(chunkSize);
         final int lastChunkSize = 20;
         final ByteBuf src = Unpooled.wrappedBuffer(getByteArray(chunkSize * 4 + lastChunkSize));
         final ByteBuf destination = Unpooled.buffer();
         encoder.encode(ctx, src, destination);
-        assertEquals(4, chunks.size());
 
-        final int framingSize = "#256\n".getBytes().length + 1/* new line at end */;
+        assertEquals(1077, destination.readableBytes());
 
-        for (final ByteBuf chunk : chunks) {
-            assertEquals(chunkSize + framingSize, chunk.readableBytes());
-        }
+        byte[] buf = new byte[destination.readableBytes()];
+        destination.readBytes(buf);
+        String s = Charsets.US_ASCII.decode(ByteBuffer.wrap(buf)).toString();
 
-        final int lastFramingSize = "#20\n".length() + NetconfMessageConstants.END_OF_CHUNK.length + 1/* new line at end */;
-        assertEquals(lastChunkSize + lastFramingSize, destination.readableBytes());
+        assertTrue(s.startsWith("\n#256\na"));
+        assertTrue(s.endsWith("\n#20\naaaaaaaaaaaaaaaaaaaa\n##\n"));
     }
 
     private byte[] getByteArray(final int size) {
index 5c2770a..89285d1 100644 (file)
@@ -27,6 +27,7 @@ public final class NetconfMessageConstants {
 
     public static final int MAX_HEADER_LENGTH = 13;
 
+    public static final byte[] START_OF_CHUNK = "\n#".getBytes(Charsets.UTF_8);
     public static final byte[] END_OF_CHUNK = "\n##\n".getBytes(Charsets.UTF_8);
 
 }

©2013 OpenDaylight, A Linux Foundation Collaborative Project. All Rights Reserved.
OpenDaylight is a registered trademark of The OpenDaylight Project, Inc.
Linux Foundation and OpenDaylight are registered trademarks of the Linux Foundation.
Linux is a registered trademark of Linus Torvalds.