Luis (from the integration project) identified the SAL Connection service interaction issues
during OVSDB Passive connection to the controller.
Also introduced the disconnect handling, including cleaning up the tableCache for that node.
Change-Id: Ieb7ed88e164574c3f27413d8ccae38222e82d89f
Signed-off-by: Madhu Venugopal <mavenugo@gmail.com>
import org.opendaylight.controller.sal.core.Node;
import org.opendaylight.controller.sal.core.NodeConnector;
import org.opendaylight.controller.sal.inventory.IPluginInInventoryService;
+import org.opendaylight.controller.sal.inventory.IPluginOutInventoryService;
import org.opendaylight.controller.sal.utils.GlobalConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
c.setInterface(
new String[] {IPluginInInventoryService.class.getName(),
InventoryServiceInternal.class.getName()}, props);
+ c.add(createServiceDependency()
+ .setService(IPluginOutInventoryService.class, "(scope=Global)")
+ .setCallbacks("setPluginOutInventoryServices",
+ "unsetPluginOutInventoryServices")
+ .setRequired(true));
}
if (imp.equals(NodeFactory.class)) {
--- /dev/null
+package org.opendaylight.ovsdb.plugin;
+
+import org.opendaylight.controller.sal.core.Node;
+
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelFutureListener;
+
+public class ChannelConnectionHandler implements ChannelFutureListener {
+ Node node;
+ ConnectionService connectionService;
+ public Node getNode() {
+ return node;
+ }
+ public void setNode(Node node) {
+ this.node = node;
+ }
+ public ConnectionService getConnectionService() {
+ return connectionService;
+ }
+ public void setConnectionService(ConnectionService connectionService) {
+ this.connectionService = connectionService;
+ }
+ @Override
+ public void operationComplete(ChannelFuture arg0) throws Exception {
+ connectionService.channelClosed(node);
+ }
+}
import org.opendaylight.controller.sal.connection.ConnectionConstants;
import org.opendaylight.controller.sal.connection.IPluginInConnectionService;
import org.opendaylight.controller.sal.core.Node;
+import org.opendaylight.controller.sal.core.Property;
import org.opendaylight.controller.sal.utils.Status;
import org.opendaylight.controller.sal.utils.StatusCode;
import org.opendaylight.ovsdb.lib.database.DatabaseSchema;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.Arrays;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutionException;
ovsdb.registerCallback(instance);
ovsdbConnections.put(identifier, connection);
+ ChannelConnectionHandler handler = new ChannelConnectionHandler();
+ handler.setNode(node);
+ handler.setConnectionService(this);
+ ChannelFuture closeFuture = channel.closeFuture();
+ closeFuture.addListener(handler);
// Keeping the Initial inventory update(s) on its own thread.
new Thread() {
Connection connection;
return node;
}
+ public void channelClosed(Node node) throws Exception {
+ logger.error("Connection to Node : {} closed", node);
+ inventoryServiceInternal.removeNode(node);
+ }
+
private void initializeInventoryForNewNode (Connection connection) throws InterruptedException, ExecutionException {
Channel channel = connection.getChannel();
InetAddress address = ((InetSocketAddress)channel.remoteAddress()).getAddress();
int port = ((InetSocketAddress)channel.remoteAddress()).getPort();
IPAddressProperty addressProp = new IPAddressProperty(address);
L4PortProperty l4Port = new L4PortProperty(port);
- inventoryServiceInternal.addNodeProperty(connection.getNode(), addressProp);
- inventoryServiceInternal.addNodeProperty(connection.getNode(), l4Port);
+ Set<Property> props = new HashSet<Property>();
+ props.add(addressProp);
+ props.add(l4Port);
+ inventoryServiceInternal.addNode(connection.getNode(), props);
List<String> dbNames = Arrays.asList(Open_vSwitch.NAME.getName());
ListenableFuture<DatabaseSchema> dbSchemaF = connection.getRpc().get_schema(dbNames);
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.CopyOnWriteArraySet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.opendaylight.controller.sal.core.Node;
import org.opendaylight.controller.sal.core.NodeConnector;
import org.opendaylight.controller.sal.core.Property;
+import org.opendaylight.controller.sal.core.UpdateType;
import org.opendaylight.controller.sal.inventory.IPluginInInventoryService;
+import org.opendaylight.controller.sal.inventory.IPluginOutInventoryService;
import org.opendaylight.ovsdb.lib.database.DatabaseSchema;
import org.opendaylight.ovsdb.lib.message.TableUpdate;
import org.opendaylight.ovsdb.lib.message.TableUpdate.Row;
public class InventoryService implements IPluginInInventoryService, InventoryServiceInternal {
private static final Logger logger = LoggerFactory
.getLogger(InventoryService.class);
-
+ private final Set<IPluginOutInventoryService> pluginOutInventoryServices =
+ new CopyOnWriteArraySet<IPluginOutInventoryService>();
private ConcurrentMap<Node, Map<String, Property>> nodeProps;
private ConcurrentMap<NodeConnector, Map<String, Property>> nodeConnectorProps;
private Map<Node, NodeDB> dbCache = Maps.newHashMap();
public void stop() {
}
+ public void setPluginOutInventoryServices(IPluginOutInventoryService service) {
+ if (this.pluginOutInventoryServices != null) {
+ this.pluginOutInventoryServices.add(service);
+ }
+ }
+
+ public void unsetPluginOutInventoryServices(
+ IPluginOutInventoryService service) {
+ if (this.pluginOutInventoryServices != null) {
+ this.pluginOutInventoryServices.remove(service);
+ }
+ }
+
/**
* Retrieve nodes from openflow
*/
}
@Override
- public void addNodeProperty(Node n, Property prop) {
- Map<String, Property> nProp = nodeProps.get(n);
+ public void addNode(Node node, Set<Property> props) {
+ addNodeProperty(node, UpdateType.ADDED, props);
+ }
+
+ @Override
+ public void addNodeProperty(Node node, UpdateType type, Set<Property> props) {
+ Map<String, Property> nProp = nodeProps.get(node);
if (nProp == null) nProp = new HashMap<String, Property>();
- nProp.put(prop.getName(), prop);
- nodeProps.put(n, nProp);
+ for (Property prop : props) {
+ nProp.put(prop.getName(), prop);
+ }
+ nodeProps.put(node, nProp);
+ for (IPluginOutInventoryService service : pluginOutInventoryServices) {
+ service.updateNode(node, type, props);
+ }
}
@Override
}
db.setSchema(schema);
}
+
+ @Override
+ public void removeNode(Node node) {
+ for (IPluginOutInventoryService service : pluginOutInventoryServices) {
+ service.updateNode(node, UpdateType.REMOVED, null);
+ }
+ nodeProps.remove(node);
+ dbCache.remove(node);
+ }
}
package org.opendaylight.ovsdb.plugin;
import java.util.Map;
+import java.util.Set;
import org.opendaylight.controller.sal.core.Node;
import org.opendaylight.controller.sal.core.Property;
+import org.opendaylight.controller.sal.core.UpdateType;
import org.opendaylight.ovsdb.lib.database.DatabaseSchema;
import org.opendaylight.ovsdb.lib.message.TableUpdates;
import org.opendaylight.ovsdb.lib.table.internal.Table;
public void removeRow(Node n, String tableName, String uuid);
public void processTableUpdates(Node n, TableUpdates tableUpdates);
public void updateDatabaseSchema(Node n, DatabaseSchema schema);
- public DatabaseSchema getDatabaseSchema(Node n);
+ public DatabaseSchema getDatabaseSchema(Node n);
public void printCache(Node n);
- public void addNodeProperty(Node n, Property prop);
+ public void addNode(Node n, Set<Property> props);
+ public void removeNode(Node n);
+ public void addNodeProperty(Node node, UpdateType type, Set<Property> props);
}
\ No newline at end of file