From 6a07d2d622eaa06953f3353e39c080984076e8de Mon Sep 17 00:00:00 2001 From: Ashlee Young Date: Fri, 9 Oct 2015 18:32:44 -0700 Subject: Updated master to commit id 6ee8aa3e67ce89908a8c93aa9445c6f71a18f986 Change-Id: I94b055ee2f298daf71e2ec794fd0f2495bd8081f --- .../ovsdb/controller/impl/Controller.java | 98 ++++++++++++++++++++++ .../ovsdb/controller/impl/OvsdbControllerImpl.java | 63 +++++++------- .../ovsdb/controller/impl/OvsdbJsonRpcHandler.java | 2 +- 3 files changed, 133 insertions(+), 30 deletions(-) (limited to 'framework/src/onos/ovsdb/ctl') diff --git a/framework/src/onos/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/Controller.java b/framework/src/onos/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/Controller.java index 07582327..2e84a16a 100644 --- a/framework/src/onos/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/Controller.java +++ b/framework/src/onos/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/Controller.java @@ -15,25 +15,38 @@ */ package org.onosproject.ovsdb.controller.impl; +import io.netty.bootstrap.Bootstrap; import io.netty.bootstrap.ServerBootstrap; import io.netty.buffer.PooledByteBufAllocator; import io.netty.channel.Channel; +import io.netty.channel.ChannelDuplexHandler; import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelFutureListener; +import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelOption; +import io.netty.channel.ChannelPipeline; +import io.netty.channel.EventLoop; import io.netty.channel.EventLoopGroup; import io.netty.channel.ServerChannel; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; +import io.netty.channel.socket.nio.NioSocketChannel; import io.netty.handler.codec.string.StringEncoder; +import io.netty.handler.timeout.IdleState; +import io.netty.handler.timeout.IdleStateEvent; +import io.netty.handler.timeout.IdleStateHandler; import io.netty.util.CharsetUtil; import java.net.InetSocketAddress; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; import org.onlab.packet.IpAddress; +import org.onlab.packet.TpPort; import org.onosproject.ovsdb.controller.OvsdbConstant; import org.onosproject.ovsdb.controller.OvsdbNodeId; import org.onosproject.ovsdb.controller.driver.DefaultOvsdbClient; @@ -63,6 +76,9 @@ public class Controller { private EventLoopGroup workerGroup; private Class serverChannelClass; + private static final int MAX_RETRY = 5; + private static final int IDLE_TIMEOUT_SEC = 10; + /** * Initialization. */ @@ -198,4 +214,86 @@ public class Controller { workerGroup.shutdownGracefully(); bossGroup.shutdownGracefully(); } + + /** + * Connect to the ovsdb server with given ip address and port number. + * + * @param ip ip address + * @param port port number + */ + public void connect(IpAddress ip, TpPort port) { + ChannelFutureListener listener = new ConnectionListener(this, ip, port); + connectRetry(ip, port, listener); + } + + private void connectRetry(IpAddress ip, TpPort port, ChannelFutureListener listener) { + try { + Bootstrap b = new Bootstrap(); + b.group(workerGroup) + .channel(NioSocketChannel.class) + .option(ChannelOption.TCP_NODELAY, true) + .handler(new ChannelInitializer() { + + @Override + protected void initChannel(SocketChannel channel) throws Exception { + ChannelPipeline p = channel.pipeline(); + p.addLast(new MessageDecoder(), + new StringEncoder(CharsetUtil.UTF_8), + new IdleStateHandler(IDLE_TIMEOUT_SEC, 0, 0), + new ConnectionHandler()); + } + }); + b.remoteAddress(ip.toString(), port.toInt()); + b.connect().addListener(listener); + } catch (Exception e) { + log.warn("Connection to the ovsdb server {}:{} failed", ip.toString(), port.toString()); + } + } + + private class ConnectionListener implements ChannelFutureListener { + private Controller controller; + private IpAddress ip; + private TpPort port; + private AtomicInteger count = new AtomicInteger(); + + public ConnectionListener(Controller controller, + IpAddress ip, + TpPort port) { + this.controller = controller; + this.ip = ip; + this.port = port; + } + + @Override + public void operationComplete(ChannelFuture channelFuture) throws Exception { + if (!channelFuture.isSuccess()) { + channelFuture.channel().close(); + + if (count.incrementAndGet() < MAX_RETRY) { + final EventLoop loop = channelFuture.channel().eventLoop(); + + loop.schedule(() -> { + controller.connectRetry(this.ip, this.port, this); + }, 1L, TimeUnit.SECONDS); + } else { + log.info("Connection to the ovsdb {}:{} failed", + this.ip.toString(), this.port.toString()); + } + } else { + handleNewNodeConnection(channelFuture.channel()); + } + } + } + + private class ConnectionHandler extends ChannelDuplexHandler { + + @Override + public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { + IdleStateEvent e = (IdleStateEvent) evt; + + if (e.state() == IdleState.READER_IDLE) { + ctx.close(); + } + } + } } diff --git a/framework/src/onos/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/OvsdbControllerImpl.java b/framework/src/onos/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/OvsdbControllerImpl.java index 9b482968..c2cbbf8b 100644 --- a/framework/src/onos/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/OvsdbControllerImpl.java +++ b/framework/src/onos/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/OvsdbControllerImpl.java @@ -15,24 +15,15 @@ */ package org.onosproject.ovsdb.controller.impl; -import static com.google.common.base.Preconditions.checkNotNull; - -import java.math.BigInteger; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.CopyOnWriteArraySet; -import java.util.concurrent.ExecutionException; - +import com.fasterxml.jackson.databind.JsonNode; +import com.google.common.collect.ImmutableList; import org.apache.felix.scr.annotations.Activate; import org.apache.felix.scr.annotations.Component; import org.apache.felix.scr.annotations.Deactivate; import org.apache.felix.scr.annotations.Service; import org.onlab.packet.IpAddress; import org.onlab.packet.MacAddress; +import org.onlab.packet.TpPort; import org.onosproject.ovsdb.controller.DefaultEventSubject; import org.onosproject.ovsdb.controller.EventSubject; import org.onosproject.ovsdb.controller.OvsdbClientService; @@ -67,7 +58,17 @@ import org.osgi.service.component.ComponentContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.fasterxml.jackson.databind.JsonNode; +import java.math.BigInteger; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArraySet; +import java.util.concurrent.ExecutionException; + +import static com.google.common.base.Preconditions.checkNotNull; /** * The implementation of OvsdbController. @@ -133,8 +134,7 @@ public class OvsdbControllerImpl implements OvsdbController { @Override public List getNodeIds() { - // TODO Auto-generated method stub - return null; + return ImmutableList.copyOf(ovsdbClients.keySet()); } @Override @@ -142,6 +142,11 @@ public class OvsdbControllerImpl implements OvsdbController { return ovsdbClients.get(nodeId); } + @Override + public void connect(IpAddress ip, TpPort port) { + controller.connect(ip, port); + } + /** * Implementation of an Ovsdb Agent which is responsible for keeping track * of connected node and the state in which they are. @@ -204,8 +209,8 @@ public class OvsdbControllerImpl implements OvsdbController { * Processes table updates. * * @param clientService OvsdbClientService instance - * @param updates TableUpdates instance - * @param dbName ovsdb database name + * @param updates TableUpdates instance + * @param dbName ovsdb database name */ private void processTableUpdates(OvsdbClientService clientService, TableUpdates updates, String dbName) @@ -236,8 +241,8 @@ public class OvsdbControllerImpl implements OvsdbController { Row row = clientService.getRow(OvsdbConstant.DATABASENAME, tableName, uuid.value()); dispatchInterfaceEvent(clientService, row, - OvsdbEvent.Type.PORT_REMOVED, - dbSchema); + OvsdbEvent.Type.PORT_REMOVED, + dbSchema); } clientService.removeRow(dbName, tableName, uuid.value()); } @@ -249,10 +254,10 @@ public class OvsdbControllerImpl implements OvsdbController { * Dispatches event to the north. * * @param clientService OvsdbClientService instance - * @param newRow a new row - * @param oldRow an old row - * @param eventType type of event - * @param dbSchema ovsdb database schema + * @param newRow a new row + * @param oldRow an old row + * @param eventType type of event + * @param dbSchema ovsdb database schema */ private void dispatchInterfaceEvent(OvsdbClientService clientService, Row row, @@ -277,13 +282,13 @@ public class OvsdbControllerImpl implements OvsdbController { } EventSubject eventSubject = new DefaultEventSubject(MacAddress.valueOf( - macAndIfaceId[0]), + macAndIfaceId[0]), new HashSet(), new OvsdbPortName(intf - .getName()), + .getName()), new OvsdbPortNumber(localPort), new OvsdbDatapathId(Long - .toString(dpid)), + .toString(dpid)), new OvsdbPortType(portType), new OvsdbIfaceId(macAndIfaceId[1])); for (OvsdbEventListener listener : ovsdbEventListener) { @@ -309,7 +314,7 @@ public class OvsdbControllerImpl implements OvsdbController { String attachedMac = externalIds.get(OvsdbConstant.EXTERNAL_ID_VM_MAC); if (attachedMac == null) { - log.warn("The attachedMac is null"); + log.debug("The attachedMac is null"); //FIXME why always null? return null; } String ifaceid = externalIds @@ -318,7 +323,7 @@ public class OvsdbControllerImpl implements OvsdbController { log.warn("The ifaceid is null"); return null; } - return new String[] {attachedMac, ifaceid}; + return new String[]{attachedMac, ifaceid}; } /** @@ -343,7 +348,7 @@ public class OvsdbControllerImpl implements OvsdbController { * Gets datapathid from table bridge. * * @param clientService OvsdbClientService instance - * @param dbSchema ovsdb database schema + * @param dbSchema ovsdb database schema * @return datapathid the bridge datapathid */ private long getDataPathid(OvsdbClientService clientService, diff --git a/framework/src/onos/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/OvsdbJsonRpcHandler.java b/framework/src/onos/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/OvsdbJsonRpcHandler.java index 37942c24..1956a1eb 100644 --- a/framework/src/onos/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/OvsdbJsonRpcHandler.java +++ b/framework/src/onos/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/OvsdbJsonRpcHandler.java @@ -89,7 +89,7 @@ public final class OvsdbJsonRpcHandler extends ChannelInboundHandlerAdapter { */ private void processOvsdbMessage(JsonNode jsonNode) { - log.info("Handle ovsdb message"); + log.debug("Handle ovsdb message"); if (jsonNode.has("result")) { -- cgit 1.2.3-korg