General Sonar clean-up
[ovsdb.git] / openstack / net-virt-providers / src / main / java / org / opendaylight / ovsdb / openstack / netvirt / providers / openflow13 / AbstractServiceInstance.java
index 0843f12fa4440909903c242c65c4723e9c3f4c03..64c0f4075557cfb4bc9c96f1e4cc2a82199c24e6 100644 (file)
@@ -9,24 +9,16 @@
  */
 package org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13;
 
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ExecutionException;
-
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
-import org.opendaylight.controller.sal.utils.HexEncode;
-import org.opendaylight.ovsdb.lib.notation.Row;
+import org.opendaylight.ovsdb.openstack.netvirt.api.Southbound;
 import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
-import org.opendaylight.ovsdb.compatibility.plugin.api.OvsdbConfigurationService;
-import org.opendaylight.ovsdb.compatibility.plugin.api.OvsdbConnectionService;
-import org.opendaylight.ovsdb.schema.openvswitch.Bridge;
+import org.opendaylight.ovsdb.openstack.netvirt.providers.NetvirtProvidersProvider;
 import org.opendaylight.ovsdb.utils.mdsal.openflow.InstructionUtils;
+import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
@@ -43,15 +35,20 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
 import com.google.common.collect.Lists;
 import com.google.common.util.concurrent.CheckedFuture;
 
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+
+import org.osgi.framework.ServiceReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 /**
  * Any ServiceInstance class that extends AbstractServiceInstance to be a part of the pipeline
  * have 2 basic requirements : <br>
@@ -62,51 +59,32 @@ import com.google.common.util.concurrent.CheckedFuture;
  */
 public abstract class AbstractServiceInstance {
     public static final String SERVICE_PROPERTY ="serviceProperty";
-    private static final Logger logger = LoggerFactory.getLogger(AbstractServiceInstance.class);
+    private static final Logger LOG = LoggerFactory.getLogger(AbstractServiceInstance.class);
     public static final String OPENFLOW = "openflow:";
+    private DataBroker dataBroker = null;
     // OSGi Services that we are dependent on.
-    private volatile MdsalConsumer mdsalConsumer;
     private volatile PipelineOrchestrator orchestrator;
-    private volatile OvsdbConfigurationService ovsdbConfigService;
-    private volatile OvsdbConnectionService connectionService;
+    private volatile Southbound southbound;
 
-    // Concrete Service that this AbstractServiceInstance represent
+    // Concrete Service that this AbstractServiceInstance represents
     private Service service;
 
     public AbstractServiceInstance (Service service) {
         this.service = service;
+        this.dataBroker = NetvirtProvidersProvider.getDataBroker();
     }
 
-    public boolean isBridgeInPipeline (String nodeId){
-        String bridgeName = getBridgeName(nodeId.split(":")[1]);
-        logger.debug("isBridgeInPipeline: nodeId {} bridgeName {}", nodeId, bridgeName);
-        if (bridgeName != null && Constants.INTEGRATION_BRIDGE.equalsIgnoreCase(bridgeName)) {
-            return true;
-        }
-        return false;
+    protected void setDependencies(final ServiceReference ref, AbstractServiceInstance serviceInstance) {
+        this.orchestrator =
+                (PipelineOrchestrator) ServiceHelper.getGlobalInstance(PipelineOrchestrator.class, serviceInstance);
+        orchestrator.registerService(ref, serviceInstance);
+        this.southbound =
+                (Southbound) ServiceHelper.getGlobalInstance(Southbound.class, serviceInstance);
     }
 
-    private String getBridgeName(String nodeId){
-        List<org.opendaylight.controller.sal.core.Node> ovsNodes = connectionService.getNodes();
-
-        for (org.opendaylight.controller.sal.core.Node ovsNode : ovsNodes) {
-            Map<String, Row> bridges = ovsdbConfigService.getRows(ovsNode, ovsdbConfigService.getTableName(ovsNode, Bridge.class));
-            if (bridges == null) continue;
-            for (String brUuid : bridges.keySet()) {
-                Bridge bridge = ovsdbConfigService.getTypedRow(ovsNode, Bridge.class, bridges.get(brUuid));
-
-                Set<String> dpids = bridge.getDatapathIdColumn().getData();
-                if (dpids == null || dpids.size() == 0) return null;
-                Long dpid = HexEncode.stringToLong((String) dpids.toArray()[0]);
-                logger.debug("getBridgeName: bridgeDpid {} ofNodeDpid {}", bridge.getDatapathIdColumn().getData().toArray()[0], nodeId);
-                if (dpid.equals(Long.parseLong(nodeId))){
-                    // Found the bridge
-                    logger.debug("getOvsNode: found ovsNode {} bridge {} for ofNode {}", ovsNode.getNodeIDString(), bridge.getName(), nodeId);
-                    return bridge.getName();
-                }
-            }
-        }
-        return null;
+    public boolean isBridgeInPipeline (Node node){
+        String bridgeName = southbound.getBridgeName(node);
+        return bridgeName != null && Constants.INTEGRATION_BRIDGE.equals(bridgeName);
     }
 
     public short getTable() {
@@ -128,8 +106,24 @@ public abstract class AbstractServiceInstance {
         return builder;
     }
 
+    private static InstanceIdentifier<Flow> createFlowPath(FlowBuilder flowBuilder, NodeBuilder nodeBuilder) {
+        return InstanceIdentifier.builder(Nodes.class)
+                .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node.class,
+                        nodeBuilder.getKey())
+                .augmentation(FlowCapableNode.class)
+                .child(Table.class, new TableKey(flowBuilder.getTableId()))
+                .child(Flow.class, flowBuilder.getKey()).build();
+    }
+
+    private static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node>
+    createNodePath(NodeBuilder nodeBuilder) {
+        return InstanceIdentifier.builder(Nodes.class)
+                .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node.class,
+                        nodeBuilder.getKey()).build();
+    }
+
     /**
-     * This method returns the required Pipeline Instructions to by used by any matching flows that needs
+     * This method returns the required Pipeline Instructions to by used by any matching flows that need
      * to be further processed by next service in the pipeline.
      *
      * Important to note that this is a convenience method which returns a mutable instructionBuilder which
@@ -146,118 +140,99 @@ public abstract class AbstractServiceInstance {
     }
 
     protected void writeFlow(FlowBuilder flowBuilder, NodeBuilder nodeBuilder) {
-        Preconditions.checkNotNull(mdsalConsumer);
-        if (mdsalConsumer == null) {
-            logger.error("ERROR finding MDSAL Service. Its possible that writeFlow is called too soon ?");
-            return;
-        }
-
-        DataBroker dataBroker = mdsalConsumer.getDataBroker();
-        if (dataBroker == null) {
-            logger.error("ERROR finding reference for DataBroker. Please check MD-SAL support on the Controller.");
-            return;
-        }
-
-        ReadWriteTransaction modification = dataBroker.newReadWriteTransaction();
-        InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node> nodePath = InstanceIdentifier.builder(Nodes.class)
-                .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node.class, nodeBuilder.getKey()).toInstance();
-
-        modification.put(LogicalDatastoreType.CONFIGURATION, nodePath, nodeBuilder.build(), true);
-        InstanceIdentifier<Flow> path1 = InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory
-                .rev130819.nodes.Node.class, nodeBuilder.getKey()).augmentation(FlowCapableNode.class).child(Table.class,
-                new TableKey(flowBuilder.getTableId())).child(Flow.class, flowBuilder.getKey()).build();
-
-        modification.put(LogicalDatastoreType.CONFIGURATION, path1, flowBuilder.build(), true /*createMissingParents*/);
+        LOG.debug("writeFlow: flowBuilder: {}, nodeBuilder: {}",
+                flowBuilder.build(), nodeBuilder.build());
+        WriteTransaction modification = dataBroker.newWriteOnlyTransaction();
+        modification.put(LogicalDatastoreType.CONFIGURATION, createNodePath(nodeBuilder),
+                nodeBuilder.build(), true /*createMissingParents*/);
+        modification.put(LogicalDatastoreType.CONFIGURATION, createFlowPath(flowBuilder, nodeBuilder),
+                flowBuilder.build(), true /*createMissingParents*/);
 
         CheckedFuture<Void, TransactionCommitFailedException> commitFuture = modification.submit();
         try {
             commitFuture.get();  // TODO: Make it async (See bug 1362)
-            logger.debug("Transaction success for write of Flow "+flowBuilder.getFlowName());
-            Thread.sleep(500);
+            LOG.debug("Transaction success for write of Flow {}", flowBuilder.getFlowName());
         } catch (Exception e) {
-            logger.error(e.getMessage(), e);
+            LOG.error(e.getMessage(), e);
             modification.cancel();
         }
     }
 
     protected void removeFlow(FlowBuilder flowBuilder, NodeBuilder nodeBuilder) {
-        Preconditions.checkNotNull(mdsalConsumer);
-        if (mdsalConsumer == null) {
-            logger.error("ERROR finding MDSAL Service.");
-            return;
-        }
-
-        DataBroker dataBroker = mdsalConsumer.getDataBroker();
-        if (dataBroker == null) {
-            logger.error("ERROR finding reference for DataBroker. Please check MD-SAL support on the Controller.");
-            return;
-        }
-
         WriteTransaction modification = dataBroker.newWriteOnlyTransaction();
-        InstanceIdentifier<Flow> path1 = InstanceIdentifier.builder(Nodes.class)
-                .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory
-                               .rev130819.nodes.Node.class, nodeBuilder.getKey())
-                .augmentation(FlowCapableNode.class).child(Table.class,
-                                                           new TableKey(flowBuilder.getTableId())).child(Flow.class, flowBuilder.getKey()).build();
-        //modification.delete(LogicalDatastoreType.OPERATIONAL, nodeBuilderToInstanceId(nodeBuilder));
-        //modification.delete(LogicalDatastoreType.OPERATIONAL, path1);
-        //modification.delete(LogicalDatastoreType.CONFIGURATION, nodeBuilderToInstanceId(nodeBuilder));
-        modification.delete(LogicalDatastoreType.CONFIGURATION, path1);
+        modification.delete(LogicalDatastoreType.CONFIGURATION, createFlowPath(flowBuilder, nodeBuilder));
 
         CheckedFuture<Void, TransactionCommitFailedException> commitFuture = modification.submit();
         try {
             commitFuture.get();  // TODO: Make it async (See bug 1362)
-            logger.debug("Transaction success for deletion of Flow "+flowBuilder.getFlowName());
+            LOG.debug("Transaction success for deletion of Flow {}", flowBuilder.getFlowName());
         } catch (Exception e) {
-            logger.error(e.getMessage(), e);
+            LOG.error(e.getMessage(), e);
             modification.cancel();
         }
     }
 
     public Flow getFlow(FlowBuilder flowBuilder, NodeBuilder nodeBuilder) {
-        Preconditions.checkNotNull(mdsalConsumer);
-        if (mdsalConsumer == null) {
-            logger.error("ERROR finding MDSAL Service. Its possible that writeFlow is called too soon ?");
-            return null;
+        ReadOnlyTransaction readTx = dataBroker.newReadOnlyTransaction();
+        try {
+            Optional<Flow> data =
+                    readTx.read(LogicalDatastoreType.CONFIGURATION, createFlowPath(flowBuilder, nodeBuilder)).get();
+            if (data.isPresent()) {
+                return data.get();
+            }
+        } catch (InterruptedException|ExecutionException e) {
+            LOG.error(e.getMessage(), e);
         }
 
-        DataBroker dataBroker = mdsalConsumer.getDataBroker();
-        if (dataBroker == null) {
-            logger.error("ERROR finding reference for DataBroker. Please check MD-SAL support on the Controller.");
-            return null;
-        }
+        LOG.debug("Cannot find data for Flow {}", flowBuilder.getFlowName());
+        return null;
+    }
 
-        InstanceIdentifier<Flow> path1 = InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory
-                .rev130819.nodes.Node.class, nodeBuilder.getKey()).augmentation(FlowCapableNode.class).child(Table.class,
-                new TableKey(flowBuilder.getTableId())).child(Flow.class, flowBuilder.getKey()).build();
+    public org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node
+    getOpenFlowNode(String nodeId) {
 
         ReadOnlyTransaction readTx = dataBroker.newReadOnlyTransaction();
         try {
-            Optional<Flow> data = readTx.read(LogicalDatastoreType.CONFIGURATION, path1).get();
+            Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node> data =
+                    readTx.read(LogicalDatastoreType.OPERATIONAL, createNodePath(createNodeBuilder(nodeId))).get();
             if (data.isPresent()) {
                 return data.get();
             }
         } catch (InterruptedException|ExecutionException e) {
-            logger.error(e.getMessage(), e);
+            LOG.error(e.getMessage(), e);
         }
 
-        logger.debug("Cannot find data for Flow " + flowBuilder.getFlowName());
+        LOG.debug("Cannot find data for Node {}", nodeId);
         return null;
     }
 
+    private long getDpid(Node node) {
+        long dpid = southbound.getDataPathId(node);
+        if (dpid == 0) {
+            LOG.warn("getDpid: dpid not found: {}", node);
+        }
+        return dpid;
+    }
+
     /**
      * Program Default Pipeline Flow.
      *
-     * @param nodeId Node on which the default pipeline flow is programmed.
+     * @param node on which the default pipeline flow is programmed.
      */
-    protected void programDefaultPipelineRule(String nodeId) {
-        if (!isBridgeInPipeline(nodeId)) {
-            logger.debug("Bridge {} is not in pipeline", nodeId);
+    protected void programDefaultPipelineRule(Node node) {
+        if (!isBridgeInPipeline(node)) {
+            //LOG.trace("Bridge is not in pipeline {} ", node);
             return;
         }
         MatchBuilder matchBuilder = new MatchBuilder();
         FlowBuilder flowBuilder = new FlowBuilder();
-        NodeBuilder nodeBuilder = createNodeBuilder(nodeId);
+        long dpid = getDpid(node);
+        if (dpid == 0L) {
+            LOG.info("could not find dpid: {}", node.getNodeId());
+            return;
+        }
+        String nodeName = OPENFLOW + getDpid(node);
+        NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
 
         // Create the OF Actions and Instructions
         InstructionsBuilder isb = new InstructionsBuilder();