From c4d0bf06488e8ae51519e4ebc7ad5c75c7c4ae50 Mon Sep 17 00:00:00 2001 From: Michal Polkorab Date: Thu, 10 Oct 2013 14:12:40 +0200 Subject: [PATCH] Integration test with hadshake First augment DelegatingInboundHandler creates new Thread per message received Publishing ChannelInitializer now asks plugin for accepting new connection Updated SimpleClient Signed-off-by: Michal Polkorab Change-Id: Ic11f28fc18b08d8e0afd5f318a8945f93d3dba00 --- .../src/main/yang/openflow-augments.yang | 10 +-- .../connection/ConnectionAdapterImpl.java | 53 ++++++++++----- .../impl/connection/RpcResponseKey.java | 16 ++--- .../impl/core/DelegatingInboundHandler.java | 13 +++- .../protocol/impl/core/OF13Encoder.java | 2 + .../core/PublishingChannelInitializer.java | 11 ++- .../protocol/impl/core/TcpHandler.java | 16 ----- .../impl/serialization/MessageTypeKey.java | 5 ++ .../protocol/impl/clients/SimpleClient.java | 31 +-------- .../impl/clients/SimpleClientHandler.java | 63 ++++++++++++------ .../impl/clients/SimpleClientInitializer.java | 14 ++-- .../impl/integration/IntegrationTest.java | 26 ++++++-- .../protocol/impl/integration/MockPlugin.java | 62 ++++++++++++++++- .../impl/integration/OFBinaryMessageInput.txt | Bin 24 -> 8 bytes 14 files changed, 211 insertions(+), 111 deletions(-) diff --git a/openflow-protocol-api/src/main/yang/openflow-augments.yang b/openflow-protocol-api/src/main/yang/openflow-augments.yang index 67297e7a..13f8b00a 100644 --- a/openflow-protocol-api/src/main/yang/openflow-augments.yang +++ b/openflow-protocol-api/src/main/yang/openflow-augments.yang @@ -9,9 +9,9 @@ module openflow-augments { description "Initial model"; } - //augment "/ofproto:hello-message/ofproto:hello" { - // leaf uid { - // type uint16; - // } - //} + augment "/ofproto:hello-message/ofproto:elements" { + leaf uid { + type uint16; + } + } } \ No newline at end of file diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/connection/ConnectionAdapterImpl.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/connection/ConnectionAdapterImpl.java index 7cacb221..7ee35ae4 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/connection/ConnectionAdapterImpl.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/connection/ConnectionAdapterImpl.java @@ -7,6 +7,8 @@ import io.netty.channel.ChannelFuture; import io.netty.util.concurrent.GenericFutureListener; import java.util.Collection; +import java.util.Collections; +import java.util.List; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; @@ -100,7 +102,10 @@ public class ConnectionAdapterImpl implements ConnectionFacade { public void onRemoval( RemovalNotification> notification) { LOG.warn("rpc response discarded: "+notification.getKey()); - notification.getValue().cancel(true); + SettableFuture future = notification.getValue(); + if (!future.isDone()) { + future.cancel(true); + } } }).build(); LOG.info("ConnectionAdapter created"); @@ -237,6 +242,7 @@ public class ConnectionAdapterImpl implements ConnectionFacade { @Override public void consume(DataObject message) { + LOG.debug("Consume msg"); if (disconnectOccured ) { return; } @@ -272,10 +278,13 @@ public class ConnectionAdapterImpl implements ConnectionFacade { } } else { if (message instanceof OfHeader) { + LOG.debug("OFheader msg received"); RpcResponseKey key = createRpcResponseKey((OfHeader) message); SettableFuture> rpcFuture = findRpcResponse(key); if (rpcFuture != null) { - rpcFuture.set(Rpcs.getRpcResult(true, message, null)); + LOG.debug("corresponding rpcFuture found"); + List errors = Collections.emptyList(); + rpcFuture.set(Rpcs.getRpcResult(true, message, errors)); responseCache.invalidate(key); } else { LOG.warn("received unexpected rpc response: "+key); @@ -298,7 +307,9 @@ public class ConnectionAdapterImpl implements ConnectionFacade { */ private SettableFuture> sendToSwitchFuture( DataObject input, final String failureInfo) { + LOG.debug("going to flush"); ChannelFuture resultFuture = channel.writeAndFlush(input); + LOG.debug("flushed"); ErrorSeverity errorSeverity = ErrorSeverity.ERROR; String errorMessage = "check switch connection"; @@ -322,12 +333,18 @@ public class ConnectionAdapterImpl implements ConnectionFacade { */ private SettableFuture> sendToSwitchExpectRpcResultFuture( IN input, Class responseClazz, final String failureInfo) { + LOG.debug("going to flush"); + SettableFuture> rpcResult = SettableFuture.create(); + RpcResponseKey key = new RpcResponseKey(input.getXid(), responseClazz); + responseCache.put(key, rpcResult); ChannelFuture resultFuture = channel.writeAndFlush(input); + LOG.debug("flushed"); ErrorSeverity errorSeverity = ErrorSeverity.ERROR; String errorMessage = "check switch connection"; + return handleRpcChannelFutureWithResponse(resultFuture, failureInfo, errorSeverity, - errorMessage, input, responseClazz); + errorMessage, input, responseClazz, rpcResult, key); } /** @@ -340,16 +357,18 @@ public class ConnectionAdapterImpl implements ConnectionFacade { final ErrorSeverity errorSeverity, final String errorMessage) { final SettableFuture> rpcResult = SettableFuture.create(); - + LOG.debug("handlerpcchannelfuture"); resultFuture.addListener(new GenericFutureListener>() { @Override public void operationComplete( io.netty.util.concurrent.Future future) throws Exception { - Collection errors = null; + LOG.debug("operation complete"); + Collection errors = Collections.emptyList(); if (future.cause() != null) { + LOG.debug("future.cause != null"); RpcError rpcError = buildRpcError(failureInfo, errorSeverity, errorMessage, future.cause()); errors = Lists.newArrayList(rpcError); @@ -366,19 +385,21 @@ public class ConnectionAdapterImpl implements ConnectionFacade { } /** - * @param input - * @param responseClazz * @param resultFuture * @param failureInfo * @param errorSeverity * @param errorMessage + * @param input + * @param responseClazz + * @param key TODO + * @param future TODO * @return */ private SettableFuture> handleRpcChannelFutureWithResponse( ChannelFuture resultFuture, final String failureInfo, final ErrorSeverity errorSeverity, final String errorMessage, - final IN input, Class responseClazz) { - final SettableFuture> rpcResult = SettableFuture.create(); + final IN input, Class responseClazz, final SettableFuture> rpcResult, final RpcResponseKey key) { + LOG.debug("handleRpcchanfuture with response"); resultFuture.addListener(new GenericFutureListener>() { @@ -387,8 +408,10 @@ public class ConnectionAdapterImpl implements ConnectionFacade { io.netty.util.concurrent.Future future) throws Exception { + LOG.debug("operation complete"); + Collection errors = Collections.emptyList(); if (future.cause() != null) { - Collection errors = null; + LOG.debug("ChannelFuture.cause != null"); RpcError rpcError = buildRpcError(failureInfo, errorSeverity, errorMessage, future.cause()); errors = Lists.newArrayList(rpcError); @@ -397,12 +420,12 @@ public class ConnectionAdapterImpl implements ConnectionFacade { (OUT) null, errors) ); + responseCache.invalidate(key); } else { - RpcResponseKey key = new RpcResponseKey(input.getXid(), input.getClass().toString()); - if (responseCache.getIfPresent(key) != null) { - responseCache.invalidate(key); + LOG.debug("ChannelFuture.cause == null"); + if (responseCache.getIfPresent(key) == null) { + LOG.debug("responcache: key wasn't present"); } - responseCache.put(key, rpcResult); } } }); @@ -462,7 +485,7 @@ public class ConnectionAdapterImpl implements ConnectionFacade { * @return */ private static RpcResponseKey createRpcResponseKey(OfHeader message) { - return new RpcResponseKey(message.getXid(), message.getClass().toString()); + return new RpcResponseKey(message.getXid(), message.getClass()); } /** diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/connection/RpcResponseKey.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/connection/RpcResponseKey.java index d4cd3976..8a7bb5ef 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/connection/RpcResponseKey.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/connection/RpcResponseKey.java @@ -2,6 +2,8 @@ package org.opendaylight.openflowjava.protocol.impl.connection; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; + /** * @author mirehak @@ -10,12 +12,12 @@ package org.opendaylight.openflowjava.protocol.impl.connection; public class RpcResponseKey { private final long xid; - private final String outputClazz; + private final Class outputClazz; /** * @param xid * @param outputClazz */ - public RpcResponseKey(long xid, String outputClazz) { + public RpcResponseKey(long xid, Class outputClazz) { super(); this.xid = xid; this.outputClazz = outputClazz; @@ -31,16 +33,14 @@ public class RpcResponseKey { /** * @return the outputClazz */ - public String getOutputClazz() { + public Class getOutputClazz() { return outputClazz; } - + @Override public int hashCode() { final int prime = 31; int result = 1; - result = prime * result - + ((outputClazz == null) ? 0 : outputClazz.hashCode()); result = prime * result + (int) (xid ^ (xid >>> 32)); return result; } @@ -57,8 +57,8 @@ public class RpcResponseKey { if (outputClazz == null) { if (other.outputClazz != null) return false; - } else if (!outputClazz.equals(other.outputClazz)) - return false; + } else if (!other.outputClazz.isAssignableFrom(outputClazz)) + return false; if (xid != other.xid) return false; return true; diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/DelegatingInboundHandler.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/DelegatingInboundHandler.java index cef6b03b..44366ee3 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/DelegatingInboundHandler.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/DelegatingInboundHandler.java @@ -18,7 +18,7 @@ public class DelegatingInboundHandler extends ChannelInboundHandlerAdapter { private static final Logger LOGGER = LoggerFactory.getLogger(DelegatingInboundHandler.class); - private MessageConsumer consumer; + protected MessageConsumer consumer; private boolean inactiveMessageSent = false; /** @@ -31,8 +31,15 @@ public class DelegatingInboundHandler extends ChannelInboundHandlerAdapter { } @Override - public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { - consumer.consume((DataObject) msg); + public void channelRead(ChannelHandlerContext ctx, final Object msg) + throws Exception { + LOGGER.debug("Reading"); + new Thread(new Runnable() { + @Override + public void run() { + consumer.consume((DataObject) msg); + } + }).start(); } @Override diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OF13Encoder.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OF13Encoder.java index dde78e7d..3a7ad0cc 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OF13Encoder.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OF13Encoder.java @@ -26,8 +26,10 @@ public class OF13Encoder extends MessageToByteEncoder { @Override protected void encode(ChannelHandlerContext ctx, OfHeader msg, ByteBuf out) throws Exception { + LOGGER.debug("Encoding"); SerializationFactory.messageToBuffer(msg.getVersion(), out, msg); if (out.readableBytes() > 0) { + out.retain(); ctx.writeAndFlush(out); } else { LOGGER.warn("Translated buffer is empty"); diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/PublishingChannelInitializer.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/PublishingChannelInitializer.java index fdd2d1da..5866ebf2 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/PublishingChannelInitializer.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/PublishingChannelInitializer.java @@ -5,6 +5,7 @@ import io.netty.channel.ChannelInitializer; import io.netty.channel.group.DefaultChannelGroup; import io.netty.channel.socket.SocketChannel; +import java.net.InetAddress; import java.util.Iterator; import org.opendaylight.openflowjava.protocol.api.connection.SwitchConnectionHandler; @@ -34,8 +35,14 @@ public class PublishingChannelInitializer extends ChannelInitializer 0) { - port = Integer.parseInt(args[0]); - } else { - port = 6633; - } - new Thread(new TcpHandler(port)).start(); - } - @Override public ListenableFuture getIsOnlineFuture() { return isOnlineFuture; diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/MessageTypeKey.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/MessageTypeKey.java index 128c83ed..b6f22f76 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/MessageTypeKey.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/MessageTypeKey.java @@ -37,6 +37,11 @@ public class MessageTypeKey { return msgType; } + @Override + public String toString() { + return "msgVersion: " + msgVersion + " msgType: " + msgType.getName(); + } + @Override public int hashCode() { final int prime = 31; diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/clients/SimpleClient.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/clients/SimpleClient.java index 6c8e0299..91eb25f6 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/clients/SimpleClient.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/clients/SimpleClient.java @@ -39,8 +39,6 @@ public class SimpleClient extends Thread { private EventLoopGroup group; private SettableFuture isOnlineFuture; private SettableFuture automatedPartDone; - private SettableFuture dataReceived; - private int dataLimit; /** * Constructor of class @@ -77,7 +75,6 @@ public class SimpleClient extends Thread { private void init() { isOnlineFuture = SettableFuture.create(); automatedPartDone = SettableFuture.create(); - dataReceived = SettableFuture.create(); } /** @@ -88,17 +85,9 @@ public class SimpleClient extends Thread { group = new NioEventLoopGroup(); try { Bootstrap b = new Bootstrap(); - if (securedClient) { - b.group(group) - .channel(NioSocketChannel.class) - .handler(new SimpleClientInitializer(isOnlineFuture)); - } else { - SimpleClientHandler plainHandler = new SimpleClientHandler(isOnlineFuture); - plainHandler.setDataReceivedFuture(dataReceived , dataLimit); - b.group(group) - .channel(NioSocketChannel.class) - .handler(plainHandler); - } + b.group(group) + .channel(NioSocketChannel.class) + .handler(new SimpleClientInitializer(isOnlineFuture, securedClient)); Channel ch = b.connect(host, port).sync().channel(); @@ -201,24 +190,10 @@ public class SimpleClient extends Thread { return isOnlineFuture; } - /** - * @return the dataReceived - */ - public SettableFuture getDataReceived() { - return dataReceived; - } - /** * @return the automatedPartDone */ public SettableFuture getAutomatedPartDone() { return automatedPartDone; } - - /** - * @param dataLimit the dataLimit to set - */ - public void setDataLimit(int dataLimit) { - this.dataLimit = dataLimit; - } } \ No newline at end of file diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/clients/SimpleClientHandler.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/clients/SimpleClientHandler.java index c6f14253..67188f38 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/clients/SimpleClientHandler.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/clients/SimpleClientHandler.java @@ -3,9 +3,11 @@ package org.opendaylight.openflowjava.protocol.impl.clients; import io.netty.buffer.ByteBuf; +import io.netty.buffer.UnpooledByteBufAllocator; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; +import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper; import org.opendaylight.openflowjava.protocol.impl.util.ByteBufUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -20,9 +22,7 @@ public class SimpleClientHandler extends ChannelInboundHandlerAdapter { private static final Logger LOGGER = LoggerFactory.getLogger(SimpleClientHandler.class); private SettableFuture isOnlineFuture; - private SettableFuture dataReceived; - private int dataLimit; - private int dataCounter = 0; + private int messagesReceived; /** * @param isOnlineFuture future notifier of connected channel @@ -35,38 +35,57 @@ public class SimpleClientHandler extends ChannelInboundHandlerAdapter { public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { LOGGER.info("SimpleClientHandler - start of read"); ByteBuf bb = (ByteBuf) msg; - dataCounter += bb.readableBytes(); if (LOGGER.isDebugEnabled()) { LOGGER.debug(ByteBufUtils.byteBufToHexString(bb)); } - LOGGER.info(msg.toString()); - LOGGER.info("SimpleClientHandler - end of read"); - if (dataCounter >= dataLimit) { - LOGGER.debug("data obtained"); - dataReceived.set(null); + messagesReceived += readHeaders(bb); + LOGGER.debug("Messages received: " + messagesReceived); + switch (messagesReceived) { + case 2: + LOGGER.debug("FeaturesReply case"); + ByteBuf featuresReply = createFeaturesReplyBytebuf(); + ctx.write(featuresReply); + LOGGER.debug("FeaturesReply sent"); + break; + default: + LOGGER.debug("Default case"); + break; } + + ctx.flush(); + LOGGER.info("end of read"); + } + + private static ByteBuf createFeaturesReplyBytebuf() { + ByteBuf featuresReply = UnpooledByteBufAllocator.DEFAULT.buffer(); + featuresReply.writeByte(4); + featuresReply.writeByte(6); + featuresReply.writeShort(32); + ByteBuf featuresReplyBody = BufferHelper + .buildBuffer("00 01 02 03 04 05 06 07 00 01 02 03 01 01 00 00 00" + + " 01 02 03 00 01 02 03"); + featuresReply.writeBytes(featuresReplyBody); + return featuresReply; } -/* (non-Javadoc) - * @see io.netty.channel.ChannelInboundHandlerAdapter#channelActive(io.netty.channel.ChannelHandlerContext) - */ @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { - System.out.println("CLIENT IS ACTIVE"); + System.out.println("Client is active"); if (isOnlineFuture != null) { isOnlineFuture.set(true); isOnlineFuture = null; } } - /** - * @param dataReceived - * @param dataLimit - */ - public void setDataReceivedFuture(SettableFuture dataReceived, int dataLimit) { - this.dataReceived = dataReceived; - this.dataLimit = dataLimit; + private static int readHeaders(ByteBuf bb) { + int messages = 0; + int length = 0; + while (bb.readableBytes() > 0) { + length = bb.getShort(2); + bb.skipBytes(length); + messages++; + } + return messages; } - - + } diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/clients/SimpleClientInitializer.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/clients/SimpleClientInitializer.java index cf6f01dd..67135c7b 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/clients/SimpleClientInitializer.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/clients/SimpleClientInitializer.java @@ -20,21 +20,25 @@ import com.google.common.util.concurrent.SettableFuture; public class SimpleClientInitializer extends ChannelInitializer { private SettableFuture sf; + private boolean secured; /** * @param sf future notifier of connected channel */ - public SimpleClientInitializer(SettableFuture sf) { + public SimpleClientInitializer(SettableFuture sf, boolean secured) { this.sf = sf; + this.secured = secured; } @Override public void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); - SSLEngine engine = - SslContextFactory.getClientContext().createSSLEngine(); - engine.setUseClientMode(true); - pipeline.addLast("ssl", new SslHandler(engine)); + if (secured) { + SSLEngine engine = SslContextFactory.getClientContext() + .createSSLEngine(); + engine.setUseClientMode(true); + pipeline.addLast("ssl", new SslHandler(engine)); + } pipeline.addLast("handler", new SimpleClientHandler(sf)); sf = null; } diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/integration/IntegrationTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/integration/IntegrationTest.java index 5416a2a0..51848fe3 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/integration/IntegrationTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/integration/IntegrationTest.java @@ -57,13 +57,28 @@ public class IntegrationTest { configs.add(new TestingConnConfigImpl(startupAddress, DEFAULT_PORT, DEFAULT_TLS_SUPPORT)); scpimpl.configure(configs); scpimpl.startup().get(CONNECTION_TIMEOUT, TimeUnit.MILLISECONDS); - + int amountOfCLients = 1; - List clients = createAndStartClient(amountOfCLients, 24); + List clients = createAndStartClient(amountOfCLients); SimpleClient firstClient = clients.get(0); firstClient.getAutomatedPartDone().get(); - firstClient.getDataReceived().get(); - disconnectClients(clients); + mockPlugin.getFinishedFuture().get(); + } + + /** + * Library integration and communication test (with virtual machine) + * @throws Exception + */ + //@Test + public void testCommunicationWithVM() throws Exception { + mockPlugin = new MockPlugin(); + SwitchConnectionProviderImpl scpimpl = new SwitchConnectionProviderImpl(); + scpimpl.setSwitchConnectionHandler(mockPlugin); + List configs = new ArrayList<>(); + configs.add(new TestingConnConfigImpl(startupAddress, DEFAULT_PORT, DEFAULT_TLS_SUPPORT)); + scpimpl.configure(configs); + scpimpl.startup().get(CONNECTION_TIMEOUT, TimeUnit.MILLISECONDS); + mockPlugin.getFinishedFuture().get(); } /** @@ -73,7 +88,7 @@ public class IntegrationTest { * @throws InterruptedException * @throws ExecutionException */ - private List createAndStartClient(int amountOfCLients, int dataLimit) + private List createAndStartClient(int amountOfCLients) throws InterruptedException, ExecutionException { List clientsHorde = new ArrayList<>(); for (int i = 0; i < amountOfCLients; i++) { @@ -82,7 +97,6 @@ public class IntegrationTest { getClass().getResourceAsStream(OF_BINARY_MESSAGE_INPUT_TXT)); sc.setSecuredClient(false); clientsHorde.add(sc); - sc.setDataLimit(dataLimit); sc.start(); } for (SimpleClient sc : clientsHorde) { diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/integration/MockPlugin.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/integration/MockPlugin.java index 3ee507ea..5603a473 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/integration/MockPlugin.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/integration/MockPlugin.java @@ -1,15 +1,25 @@ /* Copyright (C)2013 Pantheon Technologies, s.r.o. All rights reserved. */ package org.opendaylight.openflowjava.protocol.impl.integration; +import java.lang.reflect.InvocationTargetException; import java.net.InetAddress; +import java.util.Arrays; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; import org.opendaylight.openflowjava.protocol.api.connection.ConnectionAdapter; import org.opendaylight.openflowjava.protocol.api.connection.SwitchConnectionHandler; import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoReplyInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoReplyInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoRequestMessage; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessage; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterMessage; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemovedMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloMessage; @@ -20,9 +30,13 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessage; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.system.rev130927.DisconnectEvent; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.system.rev130927.SystemNotificationsListener; +import org.opendaylight.yangtools.yang.common.RpcError; +import org.opendaylight.yangtools.yang.common.RpcResult; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.google.common.util.concurrent.SettableFuture; + /** * @author michal.polkorab * @@ -31,7 +45,11 @@ public class MockPlugin implements OpenflowProtocolListener, SwitchConnectionHan private static final Logger LOGGER = LoggerFactory.getLogger(MockPlugin.class); private ConnectionAdapter adapter; + private SettableFuture finishedFuture; + public MockPlugin() { + finishedFuture = SettableFuture.create(); + } @Override public void onSwitchConnected(ConnectionAdapter connection) { @@ -50,7 +68,21 @@ public class MockPlugin implements OpenflowProtocolListener, SwitchConnectionHan @Override public void onEchoRequestMessage(EchoRequestMessage notification) { LOGGER.debug("EchoRequest message received"); - + LOGGER.debug("Building EchoReplyInput"); + EchoReplyInputBuilder replyBuilder = new EchoReplyInputBuilder(); + try { + BufferHelper.setupHeader(replyBuilder); + } catch (NoSuchMethodException | SecurityException + | IllegalAccessException | IllegalArgumentException + | InvocationTargetException e) { + LOGGER.error(e.getMessage(), e); + } + replyBuilder.setXid(notification.getXid()); + EchoReplyInput echoReplyInput = replyBuilder.build(); + LOGGER.debug("EchoReplyInput built"); + LOGGER.debug("Going to send EchoReplyInput"); + adapter.echoReply(echoReplyInput); + LOGGER.debug("EchoReplyInput sent"); } @Override @@ -75,13 +107,36 @@ public class MockPlugin implements OpenflowProtocolListener, SwitchConnectionHan public void onHelloMessage(HelloMessage notification) { LOGGER.debug("Hello message received"); HelloInputBuilder hib = new HelloInputBuilder(); + GetFeaturesInputBuilder featuresBuilder = new GetFeaturesInputBuilder(); try { BufferHelper.setupHeader(hib); + BufferHelper.setupHeader(featuresBuilder); } catch (Exception e) { LOGGER.error(e.getMessage(), e); } HelloInput hi = hib.build(); adapter.hello(hi); + LOGGER.debug("hello msg sent"); + GetFeaturesInput featuresInput = featuresBuilder.build(); + try { + LOGGER.debug("Going to send featuresRequest"); + RpcResult rpcResult = adapter.getFeatures( + featuresInput).get(2500, TimeUnit.MILLISECONDS); + if (rpcResult.isSuccessful()) { + byte[] byteArray = rpcResult.getResult().getDatapathId() + .toByteArray(); + LOGGER.debug("DatapathId: " + Arrays.toString(byteArray)); + } else { + RpcError rpcError = rpcResult.getErrors().iterator().next(); + LOGGER.warn("rpcResult failed: " + + rpcError.getCause().getMessage(), rpcError.getCause()); + } + } catch (InterruptedException | ExecutionException | TimeoutException e) { + LOGGER.error(e.getMessage(), e); + } + LOGGER.info("After FeaturesReply message - disconnecting"); + adapter.disconnect(); + finishedFuture.set(null); } @Override @@ -113,4 +168,9 @@ public class MockPlugin implements OpenflowProtocolListener, SwitchConnectionHan LOGGER.debug("disconnection ocured: "+notification.getInfo()); } + public SettableFuture getFinishedFuture() { + return finishedFuture; + } + + } diff --git a/openflow-protocol-impl/src/test/resources/org/opendaylight/openflowjava/protocol/impl/integration/OFBinaryMessageInput.txt b/openflow-protocol-impl/src/test/resources/org/opendaylight/openflowjava/protocol/impl/integration/OFBinaryMessageInput.txt index 1914e08cd9378954c8c5f8424880e29e400c0f0e..1c9aa226e8d84385c5ecf718e564e01a25058148 100644 GIT binary patch literal 8 PcmZQ!VBlb2U|<9Q08s!A literal 24 VcmZQ!VBlb2U|?i{&`eO882|z{04o3h -- 2.36.6