Of Tunnel creation Oper Implementation 26/90926/20
authorApurba Mukherjee <apurba.mukherjee@ericsson.com>
Mon, 6 Jul 2020 10:18:19 +0000 (15:48 +0530)
committerApurba Mukherjee <apurba.mukherjee@ericsson.com>
Mon, 17 Aug 2020 08:08:37 +0000 (13:38 +0530)
Change-Id: I535021fbe9b1cc69c8da173ab60b304245c1d4bc
Signed-off-by: Apurba Mukherjee <apurba.mukherjee@ericsson.com>
itm/itm-api/src/main/java/org/opendaylight/genius/itm/globals/ITMConstants.java
itm/itm-impl/src/main/java/org/opendaylight/genius/itm/cache/OfDpnTepConfigCache.java
itm/itm-impl/src/main/java/org/opendaylight/genius/itm/cache/OfTepStateCache.java
itm/itm-impl/src/main/java/org/opendaylight/genius/itm/cache/UnprocessedOFNodeConnectorCache.java [new file with mode: 0644]
itm/itm-impl/src/main/java/org/opendaylight/genius/itm/impl/ItmUtils.java
itm/itm-impl/src/main/java/org/opendaylight/genius/itm/itmdirecttunnels/listeners/TunnelInventoryStateListener.java
itm/itm-impl/src/main/java/org/opendaylight/genius/itm/itmdirecttunnels/listeners/TunnelListenerCreator.java
itm/itm-impl/src/main/java/org/opendaylight/genius/itm/itmdirecttunnels/workers/OfPortStateAddWorker.java [new file with mode: 0644]
itm/itm-impl/src/main/java/org/opendaylight/genius/itm/itmdirecttunnels/workers/OfPortStateAddWorkerForNodeConnector.java [new file with mode: 0644]
itm/itm-impl/src/main/java/org/opendaylight/genius/itm/servicebinding/BindServiceUtils.java [new file with mode: 0644]
itm/itm-impl/src/test/java/org/opendaylight/genius/itm/impl/ItmManagerRpcServiceTest.java

index 0dcc66d4b75409d2afe2e5cab3400e3464ef03d1..0a6741d714d8304bb1731032f66d38426cd9dad0 100644 (file)
@@ -74,4 +74,5 @@ public interface ITMConstants {
     int INVALID_PORT_NO = -1;
     int DEFAULT_FLOW_PRIORITY = 5;
     String OF_URI_SEPARATOR = ":";
+    int INVALID_ID = 0;
 }
index 81bb64c8da80f4fbfe9073eddb8ba1ecf9699cef..ef5fa3539a11f383e8a902acdd365fee5f8396e5 100644 (file)
@@ -11,25 +11,72 @@ package org.opendaylight.genius.itm.cache;
 import java.math.BigInteger;
 import javax.inject.Inject;
 import javax.inject.Singleton;
+import org.opendaylight.genius.itm.globals.ITMConstants;
+import org.opendaylight.genius.itm.itmdirecttunnels.renderer.ovs.utilities.DirectTunnelUtils;
+import org.opendaylight.genius.itm.itmdirecttunnels.workers.OfPortStateAddWorker;
+import org.opendaylight.genius.itm.itmdirecttunnels.workers.OfPortStateAddWorkerForNodeConnector;
+import org.opendaylight.genius.itm.utils.NodeConnectorInfo;
 import org.opendaylight.genius.mdsalutil.cache.DataObjectCache;
 import org.opendaylight.infrautils.caches.CacheProvider;
+import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
+import org.opendaylight.infrautils.utils.concurrent.NamedSimpleReentrantLock.Acquired;
 import org.opendaylight.mdsal.binding.api.DataBroker;
+import org.opendaylight.mdsal.binding.util.ManagedNewTransactionRunner;
+import org.opendaylight.mdsal.binding.util.ManagedNewTransactionRunnerImpl;
 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnTepConfig;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.tep.config.OfDpnTep;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.tep.config.OfDpnTepKey;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.common.Uint64;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 @Singleton
 public class OfDpnTepConfigCache extends DataObjectCache<BigInteger, OfDpnTep> {
 
+    private static final Logger LOG = LoggerFactory.getLogger(OfDpnTepConfigCache.class);
+    private static final Logger EVENT_LOGGER = LoggerFactory.getLogger("GeniusEventLogger");
+    private final DirectTunnelUtils directTunnelUtils;
+    private final UnprocessedOFNodeConnectorCache unprocessedOFNCCache;
+    private final ManagedNewTransactionRunner txRunner;
+    private final JobCoordinator coordinator;
+
     @Inject
-    public OfDpnTepConfigCache(DataBroker dataBroker, CacheProvider cacheProvider) {
+    public OfDpnTepConfigCache(DataBroker dataBroker, JobCoordinator coordinator,
+                               CacheProvider cacheProvider,
+                               DirectTunnelUtils directTunnelUtils,
+                               UnprocessedOFNodeConnectorCache unprocessedOFNCCache) {
         super(OfDpnTep.class, dataBroker, LogicalDatastoreType.CONFIGURATION,
             InstanceIdentifier.builder(DpnTepConfig.class).child(OfDpnTep.class).build(), cacheProvider,
             (iid, dpnsTeps) -> dpnsTeps.getSourceDpnId().toJava(),
             sourceDpnId -> InstanceIdentifier.builder(DpnTepConfig.class)
                     .child(OfDpnTep.class, new OfDpnTepKey(Uint64.valueOf(sourceDpnId))).build());
+        this.directTunnelUtils = directTunnelUtils;
+        this.unprocessedOFNCCache = unprocessedOFNCCache;
+        this.coordinator = coordinator;
+        this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
+    }
+
+    @Override
+    protected void added(InstanceIdentifier<OfDpnTep> path, OfDpnTep ofDpnTep) {
+        NodeConnectorInfo nodeConnectorInfo = null;
+        try (Acquired lock = directTunnelUtils.lockTunnel(ofDpnTep.getOfPortName())) {
+            if (unprocessedOFNCCache.get(ofDpnTep.getOfPortName()) != null) {
+                nodeConnectorInfo = unprocessedOFNCCache.remove(ofDpnTep.getOfPortName());
+            }
+        }
+
+        if (nodeConnectorInfo != null && directTunnelUtils.isEntityOwner()) {
+
+            OfPortStateAddWorkerForNodeConnector ifOfStateAddWorker =
+                    new OfPortStateAddWorkerForNodeConnector(new OfPortStateAddWorker(directTunnelUtils,
+                            ofDpnTep, txRunner), nodeConnectorInfo);
+            LOG.debug("ITM-Of-tepInventoryState Entity Owner,ADD {} {}",
+                    ofDpnTep.getSourceDpnId(), ofDpnTep.getOfPortName());
+            EVENT_LOGGER.debug("ITM-Of-tepInventoryState Entity Owner,ADD {} {}",
+                    ofDpnTep.getSourceDpnId(), ofDpnTep.getOfPortName());
+            coordinator.enqueueJob(ofDpnTep.getOfPortName(), ifOfStateAddWorker, ITMConstants.JOB_MAX_RETRIES);
+        }
     }
 }
index 0bb7da5fd5d99da4458ebd5e7a8c0e88aaad93c4..e89e94d6584e9317d1481ba49a75bee93c186798 100644 (file)
@@ -7,8 +7,14 @@
  */
 package org.opendaylight.genius.itm.cache;
 
+import com.google.common.util.concurrent.ListenableFuture;
+import java.util.ArrayList;
+import java.util.List;
 import javax.inject.Inject;
 import javax.inject.Singleton;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
+import org.opendaylight.genius.itm.servicebinding.BindServiceUtils;
 import org.opendaylight.genius.mdsalutil.cache.DataObjectCache;
 import org.opendaylight.infrautils.caches.CacheProvider;
 import org.opendaylight.mdsal.binding.api.DataBroker;
@@ -24,6 +30,8 @@ import org.slf4j.LoggerFactory;
 @Singleton
 public class OfTepStateCache extends DataObjectCache<String, OfTep> {
 
+    private final ManagedNewTransactionRunner txRunner;
+    List<ListenableFuture<Void>> futures = new ArrayList<>();
     private static final Logger LOG = LoggerFactory.getLogger(OfTepStateCache.class);
 
     @Inject
@@ -32,5 +40,13 @@ public class OfTepStateCache extends DataObjectCache<String, OfTep> {
             InstanceIdentifier.builder(OfTepsState.class).child(OfTep.class).build(), cacheProvider,
             (iid, ofTepList) -> ofTepList.getOfPortName(), ofPortName -> InstanceIdentifier.builder(OfTepsState.class)
                     .child(OfTep.class, new OfTepKey(ofPortName)).build());
+        this.txRunner =  new ManagedNewTransactionRunnerImpl(dataBroker);
+    }
+
+    protected void added(InstanceIdentifier<OfTep> path, OfTep ofTep) {
+        LOG.info("Binding default egress dispatcher service for{}", ofTep.getOfPortName());
+        BindServiceUtils.bindDefaultEgressDispatcherService(txRunner, futures, "VXLAN_TRUNK_INTERFACE",
+                String.valueOf(ofTep.getPortNumber()), ofTep.getOfPortName(),
+                ofTep.getIfIndex());
     }
 }
diff --git a/itm/itm-impl/src/main/java/org/opendaylight/genius/itm/cache/UnprocessedOFNodeConnectorCache.java b/itm/itm-impl/src/main/java/org/opendaylight/genius/itm/cache/UnprocessedOFNodeConnectorCache.java
new file mode 100644 (file)
index 0000000..6e9ea6e
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2020 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.genius.itm.cache;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import javax.inject.Singleton;
+import org.opendaylight.genius.itm.utils.NodeConnectorInfo;
+
+@Singleton
+public class UnprocessedOFNodeConnectorCache {
+
+    private final ConcurrentMap<String, NodeConnectorInfo> unprocessedOFNodeConnectorMap = new ConcurrentHashMap<>();
+
+    public void add(String ofPortName, NodeConnectorInfo nodeConnectorInfo) {
+        unprocessedOFNodeConnectorMap.put(ofPortName, nodeConnectorInfo);
+    }
+
+    public NodeConnectorInfo get(String ofPortName) {
+        return unprocessedOFNodeConnectorMap.get(ofPortName);
+    }
+
+    public NodeConnectorInfo remove(String ofPortName) {
+        return unprocessedOFNodeConnectorMap.remove(ofPortName);
+    }
+
+    public ConcurrentMap<String, NodeConnectorInfo> getAllPresent() {
+        return unprocessedOFNodeConnectorMap;
+    }
+}
index 292f26deb264e6a3d0ee853f3b5e4234c354ef45..0dea8af64d9aea07ad7bd64973ec8638ea4af0ca 100644 (file)
@@ -84,6 +84,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.ItmConfig;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnEndpoints;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.ExternalTunnelList;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.OfTepsState;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TepTypeBase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TepTypeExternal;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TepTypeHwvtep;
@@ -106,6 +107,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.external.tunnel.list.ExternalTunnel;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.external.tunnel.list.ExternalTunnelBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.external.tunnel.list.ExternalTunnelKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.of.teps.state.OfTep;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.of.teps.state.OfTepKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnel.list.InternalTunnel;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnel.list.InternalTunnelBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnel.list.InternalTunnelKey;
@@ -932,6 +935,11 @@ public final class ItmUtils {
         return InstanceIdentifier.builder(TunnelsState.class).child(StateTunnelList.class, tlKey).build();
     }
 
+    public static InstanceIdentifier<OfTep> buildStateOfTepListId(OfTepKey ofTepKey) {
+        return InstanceIdentifier.builder(OfTepsState.class)
+                .child(OfTep.class, ofTepKey).build();
+    }
+
     @NonNull
     public static Optional<InternalTunnel> getInternalTunnelFromDS(Uint64 srcDpn, Uint64 destDpn,
                                                                    Class<? extends TunnelTypeBase> type,
index f6d5f0001beab3ec496089537d3e1c5cc6538a2c..1c08ebf025e1eecadfea974cfe2ecfdf1c55eb44 100644 (file)
@@ -16,18 +16,24 @@ import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
+import java.util.Optional;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
 import org.opendaylight.genius.itm.cache.DPNTEPsInfoCache;
 import org.opendaylight.genius.itm.cache.DpnTepStateCache;
+import org.opendaylight.genius.itm.cache.OfDpnTepConfigCache;
 import org.opendaylight.genius.itm.cache.TunnelStateCache;
 import org.opendaylight.genius.itm.cache.UnprocessedNodeConnectorCache;
 import org.opendaylight.genius.itm.cache.UnprocessedNodeConnectorEndPointCache;
+import org.opendaylight.genius.itm.cache.UnprocessedOFNodeConnectorCache;
 import org.opendaylight.genius.itm.globals.ITMConstants;
 import org.opendaylight.genius.itm.impl.ItmUtils;
 import org.opendaylight.genius.itm.itmdirecttunnels.renderer.ovs.utilities.DirectTunnelUtils;
+import org.opendaylight.genius.itm.itmdirecttunnels.workers.OfPortStateAddWorker;
+import org.opendaylight.genius.itm.itmdirecttunnels.workers.OfPortStateAddWorkerForNodeConnector;
 import org.opendaylight.genius.itm.itmdirecttunnels.workers.TunnelStateAddWorker;
 import org.opendaylight.genius.itm.itmdirecttunnels.workers.TunnelStateAddWorkerForNodeConnector;
 import org.opendaylight.genius.itm.utils.DpnTepInterfaceInfo;
@@ -50,6 +56,7 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortReason;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.tep.config.OfDpnTep;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelList;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelListBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelListKey;
@@ -81,6 +88,9 @@ public class TunnelInventoryStateListener extends
     private final UnprocessedNodeConnectorEndPointCache unprocessedNodeConnectorEndPointCache;
     private final DirectTunnelUtils directTunnelUtils;
     private final ConcurrentMap<String, NodeConnectorInfo> meshedMap = new ConcurrentHashMap<>();
+    private final UnprocessedOFNodeConnectorCache unprocessedOFNCCache;
+    private final OfDpnTepConfigCache ofDpnTepConfigCache;
+    private final IInterfaceManager interfaceManager;
 
     public TunnelInventoryStateListener(final DataBroker dataBroker,
                                         final JobCoordinator coordinator,
@@ -90,7 +100,10 @@ public class TunnelInventoryStateListener extends
                                         final UnprocessedNodeConnectorCache unprocessedNCCache,
                                         final UnprocessedNodeConnectorEndPointCache
                                             unprocessedNodeConnectorEndPointCache,
-                                        final DirectTunnelUtils directTunnelUtils) {
+                                        final DirectTunnelUtils directTunnelUtils,
+                                        UnprocessedOFNodeConnectorCache unprocessedOFNCCache,
+                                        final OfDpnTepConfigCache ofDpnTepConfigCache,
+                                        final IInterfaceManager interfaceManager) {
         super(dataBroker, LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.create(Nodes.class).child(Node.class)
             .child(NodeConnector.class).augmentation(FlowCapableNodeConnector.class));
         this.coordinator = coordinator;
@@ -101,6 +114,9 @@ public class TunnelInventoryStateListener extends
         this.unprocessedNCCache = unprocessedNCCache;
         this.unprocessedNodeConnectorEndPointCache = unprocessedNodeConnectorEndPointCache;
         this.directTunnelUtils = directTunnelUtils;
+        this.unprocessedOFNCCache = unprocessedOFNCCache;
+        this.ofDpnTepConfigCache = ofDpnTepConfigCache;
+        this.interfaceManager = interfaceManager;
         super.register();
     }
 
@@ -152,7 +168,7 @@ public class TunnelInventoryStateListener extends
                        @NonNull FlowCapableNodeConnector fcNodeConnectorNew) {
         EVENT_LOGGER.debug("ITM-TunnelInventoryState,UPDATE DTCN received for {}", fcNodeConnectorOld.getName());
         String portName = fcNodeConnectorNew.getName();
-        if (!DirectTunnelUtils.TUNNEL_PORT_PREDICATE.test(portName)) {
+        if (!DirectTunnelUtils.TUNNEL_PORT_PREDICATE.test(portName) && !portName.startsWith("of")) {
             LOG.debug("Node Connector Update - {} Interface is not a tunnel I/f, so no-op", portName);
             return;
         } else if (!dpnTepStateCache.isInternal(portName)) {
@@ -190,40 +206,41 @@ public class TunnelInventoryStateListener extends
             return;
         }
 
+        //Optional<OfDpnTep> dpnTepOptional = Optional.ofNullable(null);
         NodeConnectorInfo nodeConnectorInfo =
                 new NodeConnectorInfoBuilder().setNodeConnectorId(key).setNodeConnector(fcNodeConnectorNew).build();
 
-        if (portName.startsWith("of")) {
+        if (portName.startsWith("of") && interfaceManager.isItmOfTunnelsEnabled()) {
             NodeConnectorId nodeConnectorId = InstanceIdentifier.keyOf(key.firstIdentifierOf(NodeConnector.class))
                     .getId();
-            String srcDpn = DirectTunnelUtils.getDpnFromNodeConnectorId(nodeConnectorId).toString();
-
-            if (meshedMap.isEmpty()) {
-                meshedMap.put(srcDpn, nodeConnectorInfo);
-                return;
-            } else {
-                for (Map.Entry<String, NodeConnectorInfo> entry : meshedMap.entrySet()) {
-                    DpnTepInterfaceInfo infInfoForward = dpnTepStateCache.getDpnTepInterface(Uint64.valueOf(srcDpn),
-                        Uint64.valueOf(entry.getKey()));
-                    if (infInfoForward == null) {
-                        unprocessedNCCache.add(srcDpn + ":" + entry.getKey(),
-                                new TunnelStateInfoBuilder().setNodeConnectorInfo(nodeConnectorInfo).build());
+            Uint64 srcDpn = DirectTunnelUtils.getDpnFromNodeConnectorId(nodeConnectorId);
+
+            OfDpnTep dpntep = null;
+            try (Acquired lock = directTunnelUtils.lockTunnel(portName)) {
+                try {
+                    Optional<OfDpnTep> dpnTepOptional = ofDpnTepConfigCache.get(srcDpn.toJava());
+                    if (!dpnTepOptional.isPresent()) {
+                        // Park the notification
+                        LOG.debug("Unable to process the NodeConnector ADD event for {} as Config not available."
+                                + "Hence parking it", portName);
+                        unprocessedOFNCCache.add(portName, nodeConnectorInfo);
+                        return;
                     } else {
-                        addTunnelState(nodeConnectorInfo, infInfoForward.getTunnelName());
-                    }
-
-                    DpnTepInterfaceInfo infInfoReverse = dpnTepStateCache.getDpnTepInterface(
-                        Uint64.valueOf(entry.getKey()), Uint64.valueOf(srcDpn));
-
-                    if (infInfoReverse == null) {
-                        unprocessedNCCache.add(entry.getKey() + ":" + srcDpn,
-                                new TunnelStateInfoBuilder().setNodeConnectorInfo(entry.getValue()).build());
-                    } else {
-                        addTunnelState(entry.getValue(), infInfoReverse.getTunnelName());
+                        dpntep = dpnTepOptional.get();
                     }
+                } catch (ReadFailedException e) {
+                    LOG.error("unable to get ofDpnTepConfigCache");
                 }
             }
-            meshedMap.put(srcDpn, nodeConnectorInfo);
+
+            if (dpntep != null) {
+                OfPortStateAddWorkerForNodeConnector ifOfStateAddWorker =
+                        new OfPortStateAddWorkerForNodeConnector(new OfPortStateAddWorker(directTunnelUtils,
+                                dpntep, txRunner), nodeConnectorInfo);
+                EVENT_LOGGER.debug("ITM-Of-tepInventoryState Entity Owner,ADD {} {}",
+                        nodeConnectorId.getValue(), portName);
+                coordinator.enqueueJob(portName, ifOfStateAddWorker, ITMConstants.JOB_MAX_RETRIES);
+            }
         } else {
             addTunnelState(nodeConnectorInfo, portName);
         }
@@ -289,7 +306,7 @@ public class TunnelInventoryStateListener extends
         }
 
         if (tunnelEndPtInfo != null && tunnelStateInfo.getSrcDpnTepsInfo() != null
-            && tunnelStateInfo.getDstDpnTepsInfo() != null && directTunnelUtils.isEntityOwner()) {
+            && tunnelStateInfo.getDstDpnTepsInfo() != null) {
             EVENT_LOGGER.debug("ITM-TunnelInventoryState Entity Owner,ADD {}", portName);
             coordinator.enqueueJob(portName,
                 new TunnelStateAddWorkerForNodeConnector(new TunnelStateAddWorker(directTunnelUtils, txRunner),
index d2ac45553f9779d42fd8569937c5e6795753c89a..d2dccb0dfb10aa1dc8f58afd6ab3041a6ff7da6a 100644 (file)
@@ -13,10 +13,12 @@ import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
 import org.opendaylight.genius.itm.cache.BfdStateCache;
 import org.opendaylight.genius.itm.cache.DPNTEPsInfoCache;
 import org.opendaylight.genius.itm.cache.DpnTepStateCache;
+import org.opendaylight.genius.itm.cache.OfDpnTepConfigCache;
 import org.opendaylight.genius.itm.cache.OvsBridgeEntryCache;
 import org.opendaylight.genius.itm.cache.TunnelStateCache;
 import org.opendaylight.genius.itm.cache.UnprocessedNodeConnectorCache;
 import org.opendaylight.genius.itm.cache.UnprocessedNodeConnectorEndPointCache;
+import org.opendaylight.genius.itm.cache.UnprocessedOFNodeConnectorCache;
 import org.opendaylight.genius.itm.itmdirecttunnels.renderer.ovs.utilities.DirectTunnelUtils;
 import org.opendaylight.genius.itm.listeners.RemoteDpnListener;
 import org.opendaylight.genius.utils.clustering.EntityOwnershipUtils;
@@ -50,14 +52,17 @@ public class TunnelListenerCreator implements AutoCloseable {
                                  final TunnelStateCache tunnelStateCache,
                                  final UnprocessedNodeConnectorCache unprocessedNodeConnectorCache,
                                  final UnprocessedNodeConnectorEndPointCache
-                                    unprocessedNodeConnectorEndPointCache) {
+                                    unprocessedNodeConnectorEndPointCache,
+                                 final UnprocessedOFNodeConnectorCache unprocessedOFNodeConnectorCache,
+                                 final OfDpnTepConfigCache ofDpnTepConfigCache) {
         if (interfaceManager.isItmDirectTunnelsEnabled()) {
             LOG.debug("ITM Direct Tunnels is enabled. Initializing the listeners");
             this.tunnelTopologyStateListener = new TunnelTopologyStateListener(dataBroker, coordinator,
                 directTunnelUtils, dpnTepStateCache, ovsBridgeEntryCache);
             this.tunnelInventoryStateListener = new TunnelInventoryStateListener(dataBroker, coordinator,
                 tunnelStateCache, dpnTepStateCache, dpntePsInfoCache, unprocessedNodeConnectorCache,
-                unprocessedNodeConnectorEndPointCache, directTunnelUtils);
+                unprocessedNodeConnectorEndPointCache, directTunnelUtils, unprocessedOFNodeConnectorCache,
+                    ofDpnTepConfigCache, interfaceManager);
             this.terminationPointStateListener = new TerminationPointStateListener(dataBroker, entityOwnershipUtils,
                 coordinator, bfdStateCache, dpnTepStateCache,tunnelStateCache);
             this.interfaceConfigListener = new InterfaceConfigListener(dataBroker, coordinator);
diff --git a/itm/itm-impl/src/main/java/org/opendaylight/genius/itm/itmdirecttunnels/workers/OfPortStateAddWorker.java b/itm/itm-impl/src/main/java/org/opendaylight/genius/itm/itmdirecttunnels/workers/OfPortStateAddWorker.java
new file mode 100644 (file)
index 0000000..f0bbb2b
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2020 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.genius.itm.itmdirecttunnels.workers;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import org.opendaylight.genius.interfacemanager.globals.IfmConstants;
+import org.opendaylight.genius.itm.globals.ITMConstants;
+import org.opendaylight.genius.itm.impl.ITMBatchingUtils;
+import org.opendaylight.genius.itm.impl.ItmUtils;
+import org.opendaylight.genius.itm.itmdirecttunnels.renderer.ovs.utilities.DirectTunnelUtils;
+import org.opendaylight.genius.itm.utils.NodeConnectorInfo;
+import org.opendaylight.mdsal.binding.util.Datastore;
+import org.opendaylight.mdsal.binding.util.ManagedNewTransactionRunner;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.meta.rev171210.IfIndexesTunnelMap;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.meta.rev171210._if.indexes.tunnel.map.IfIndexTunnel;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.meta.rev171210._if.indexes.tunnel.map.IfIndexTunnelBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.meta.rev171210._if.indexes.tunnel.map.IfIndexTunnelKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TunnelOperStatus;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.tep.config.OfDpnTep;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.of.teps.state.OfTep;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.of.teps.state.OfTepBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.of.teps.state.OfTepKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.OperationFailedException;
+import org.opendaylight.yangtools.yang.common.Uint16;
+import org.opendaylight.yangtools.yang.common.Uint64;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public final class OfPortStateAddWorker {
+
+    private static final Logger LOG = LoggerFactory.getLogger(OfPortStateAddWorker.class);
+    private static final Logger EVENT_LOGGER = LoggerFactory.getLogger("GeniusEventLogger");
+
+    private final DirectTunnelUtils directTunnelUtils;
+    private final OfDpnTep dpnTep;
+    private final ManagedNewTransactionRunner txRunner;
+
+    public OfPortStateAddWorker(final DirectTunnelUtils directTunnelUtils, final OfDpnTep dpnTep,
+                                final ManagedNewTransactionRunner txRunner) {
+        this.directTunnelUtils = directTunnelUtils;
+        this.dpnTep = dpnTep;
+        this.txRunner = txRunner;
+    }
+
+    public List<? extends ListenableFuture<?>> addState(NodeConnectorInfo nodeConnectorInfo)
+            throws ExecutionException, InterruptedException, OperationFailedException {
+        // When this method is invoked, all parameters necessary should be available
+        // Retrieve Port No from nodeConnectorId
+        NodeConnectorId nodeConnectorId = InstanceIdentifier.keyOf(
+                nodeConnectorInfo.getNodeConnectorId().firstIdentifierOf(NodeConnector.class)).getId();
+        String ofPortName = nodeConnectorInfo.getNodeConnector().getName();
+        long portNo = DirectTunnelUtils.getPortNumberFromNodeConnectorId(nodeConnectorId);
+        EVENT_LOGGER.debug("ITM-Of Port State, ADD to oper DS {}", ofPortName);
+        if (portNo == ITMConstants.INVALID_PORT_NO) {
+            LOG.error("Cannot derive port number, not proceeding with of-port State "
+                    + "addition for of-port: {}", ofPortName);
+            return null;
+        }
+
+        LOG.info("adding of-port state to Oper DS for interface: {}", ofPortName);
+        OfTep ofTep = addStateEntry(ofPortName, portNo);
+
+        // If this interface is a of-port interface, create the of-port ingress flow
+        if (ofTep != null) {
+            return Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(Datastore.CONFIGURATION,
+                tx -> {
+                    Uint64 dpId = DirectTunnelUtils.getDpnFromNodeConnectorId(nodeConnectorId);
+                    directTunnelUtils.addTunnelIngressFlow(tx, dpId, portNo, ofPortName,
+                            ofTep.getIfIndex().toJava(),
+                            ofTep.getTepIp().getIpv4Address());
+                }));
+        }
+        EVENT_LOGGER.debug("ITM-of-port,ADD Table 0 flow for {} completed", ofPortName);
+        return Collections.emptyList();
+    }
+
+    private OfTep addStateEntry(String ofPortName, long portNo)
+            throws ExecutionException, InterruptedException, OperationFailedException {
+        final int ifIndex = directTunnelUtils.allocateId(IfmConstants.IFM_IDPOOL_NAME, ofPortName);
+        if (ifIndex == ITMConstants.INVALID_ID) {
+            LOG.trace("aborting addStateEntry for {}, due to invalid Id", ofPortName);
+            return null;
+        }
+        createLportTagInterfaceMap(ofPortName, ifIndex);
+        final OfTepBuilder ofTepBuilder = new OfTepBuilder();
+
+        Interface.OperStatus operStatus = Interface.OperStatus.Up;
+
+        TunnelOperStatus tunnelOperStatus = DirectTunnelUtils.convertInterfaceToTunnelOperState(operStatus);
+
+        OfTepKey ofTepKey = new OfTepKey(ofPortName);
+        ofTepBuilder.withKey(ofTepKey).setTunnelType(dpnTep.getTunnelType()).setOfPortName(ofPortName)
+                .setTepIp(dpnTep.getTepIp()).setPortNumber(String.valueOf(portNo))
+                .setIfIndex(Uint16.valueOf(ifIndex)).setOfTepState(tunnelOperStatus)
+                .setSourceDpnId(dpnTep.getSourceDpnId());
+
+        InstanceIdentifier<OfTep> ofTepsListId = ItmUtils.buildStateOfTepListId(ofTepKey);
+        LOG.trace("Batching the Creation of tunnel_state: {} for Id: {}", ofTepBuilder.build(), ofTepsListId);
+        ITMBatchingUtils.write(ofTepsListId, ofTepBuilder.build(), ITMBatchingUtils.EntityType.DEFAULT_OPERATIONAL);
+        return ofTepBuilder.build();
+    }
+
+    private void createLportTagInterfaceMap(String infName, Integer ifIndex) {
+        LOG.debug("creating lport tag to interface map for {}", infName);
+        InstanceIdentifier<IfIndexTunnel> id = InstanceIdentifier.builder(IfIndexesTunnelMap.class)
+                .child(IfIndexTunnel.class, new IfIndexTunnelKey(ifIndex)).build();
+        IfIndexTunnel ifIndexInterface = new IfIndexTunnelBuilder().setIfIndex(ifIndex)
+                .withKey(new IfIndexTunnelKey(ifIndex)).setInterfaceName(infName).build();
+        ITMBatchingUtils.write(id, ifIndexInterface, ITMBatchingUtils.EntityType.DEFAULT_OPERATIONAL);
+    }
+}
diff --git a/itm/itm-impl/src/main/java/org/opendaylight/genius/itm/itmdirecttunnels/workers/OfPortStateAddWorkerForNodeConnector.java b/itm/itm-impl/src/main/java/org/opendaylight/genius/itm/itmdirecttunnels/workers/OfPortStateAddWorkerForNodeConnector.java
new file mode 100644 (file)
index 0000000..1f400f7
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2020 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.genius.itm.itmdirecttunnels.workers;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import org.opendaylight.genius.itm.utils.NodeConnectorInfo;
+
+public class OfPortStateAddWorkerForNodeConnector implements Callable<List<? extends ListenableFuture<?>>> {
+    private final OfPortStateAddWorker ofPortStateAddWorker;
+    private final NodeConnectorInfo nodeConnectorInfo;
+    private final ConcurrentMap<String, NodeConnectorInfo> ofPortStateInfo = new ConcurrentHashMap<>();
+
+    public OfPortStateAddWorkerForNodeConnector(OfPortStateAddWorker ofPortStateAddWorker,
+                                                NodeConnectorInfo nodeConnectorInfo) {
+        this.ofPortStateAddWorker = ofPortStateAddWorker;
+        this.nodeConnectorInfo = nodeConnectorInfo;
+    }
+
+    @Override
+    public List<? extends ListenableFuture<?>> call() throws Exception {
+        // If another renderer(for eg : OVS) needs to be supported, check can be performed here
+        // to call the respective helpers.
+        return ofPortStateAddWorker.addState(nodeConnectorInfo);
+    }
+
+    @Override
+    public String toString() {
+        return "OfPortStateAddWorkerForNodeConnector{"
+                + "ofStateInfo=" + ofPortStateInfo
+                + '}';
+    }
+}
diff --git a/itm/itm-impl/src/main/java/org/opendaylight/genius/itm/servicebinding/BindServiceUtils.java b/itm/itm-impl/src/main/java/org/opendaylight/genius/itm/servicebinding/BindServiceUtils.java
new file mode 100644 (file)
index 0000000..01a33ba
--- /dev/null
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 2020 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.genius.itm.servicebinding;
+
+import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.opendaylight.genius.infra.Datastore;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
+import org.opendaylight.genius.infra.TypedWriteTransaction;
+import org.opendaylight.genius.itm.globals.ITMConstants;
+import org.opendaylight.genius.mdsalutil.ActionInfo;
+import org.opendaylight.genius.mdsalutil.MDSALUtil;
+import org.opendaylight.genius.mdsalutil.MetaDataUtil;
+import org.opendaylight.genius.mdsalutil.NwConstants;
+import org.opendaylight.genius.mdsalutil.actions.ActionGroup;
+import org.opendaylight.genius.mdsalutil.actions.ActionNxResubmit;
+import org.opendaylight.genius.mdsalutil.actions.ActionOutput;
+import org.opendaylight.genius.mdsalutil.actions.ActionRegLoad;
+import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldTunnelId;
+import org.opendaylight.genius.utils.ServiceIndex;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceBindings;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceModeBase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceModeEgress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceTypeFlowBased;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.StypeOpenflowBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.ServicesInfo;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.ServicesInfoKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServices;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServicesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServicesKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.Uint16;
+import org.opendaylight.yangtools.yang.common.Uint64;
+import org.opendaylight.yangtools.yang.common.Uint8;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public final class BindServiceUtils {
+
+    private static final Logger LOG = LoggerFactory.getLogger(BindServiceUtils.class);
+
+    private BindServiceUtils() {
+        throw new IllegalStateException("Utility class");
+    }
+
+    public static void bindDefaultEgressDispatcherService(ManagedNewTransactionRunner txRunner,
+                                                          List<ListenableFuture<Void>> futures, String tunType,
+                                                          String portNo, String interfaceName, Uint16 ifIndex) {
+        Map<InstructionKey, Instruction> instructions =
+                getEgressInstructionsForInterface(tunType, portNo, null, true, ifIndex, 0);
+        bindDefaultEgressDispatcherService(txRunner, futures, interfaceName, instructions);
+    }
+
+    public static void bindDefaultEgressDispatcherService(ManagedNewTransactionRunner txRunner,
+                                                          List<ListenableFuture<Void>> futures,
+                                                          String interfaceName,
+                                                          Map<InstructionKey, Instruction> instructions) {
+        futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> {
+            int priority = ServiceIndex.getIndex(NwConstants.DEFAULT_EGRESS_SERVICE_NAME,
+                    NwConstants.DEFAULT_EGRESS_SERVICE_INDEX);
+            BoundServices serviceInfo =
+                    getBoundServices(String.format("%s.%s", "default", interfaceName),
+                            ServiceIndex.getIndex(NwConstants.DEFAULT_EGRESS_SERVICE_NAME,
+                                    NwConstants.DEFAULT_EGRESS_SERVICE_INDEX),
+                            priority, NwConstants.EGRESS_DISPATCHER_TABLE_COOKIE, instructions);
+            bindService(tx, interfaceName, serviceInfo, ServiceModeEgress.class);
+        }));
+    }
+
+    public static Map<InstructionKey, Instruction> getEgressInstructionsForInterface(String tunType,String portNo,
+                                                                                     Long tunnelKey,
+                                                                                     boolean isDefaultEgress,
+                                                                                     Uint16 ifIndex, long groupId) {
+        Map<InstructionKey, Instruction> instructions = new HashMap<>();
+        List<Action> actionList = MDSALUtil.buildActions(
+                getEgressActionInfosForInterface(tunType, portNo, tunnelKey, 0,
+                        isDefaultEgress, ifIndex, groupId));
+        Instruction inst = MDSALUtil.buildApplyActionsInstruction(actionList);
+        instructions.put(inst.key(), inst);
+        return instructions;
+    }
+
+    public static List<ActionInfo> getEgressActionInfosForInterface(String tunType, String portNo,
+                                                                    Long tunnelKey,
+                                                                    int actionKeyStart, boolean isDefaultEgress,
+                                                                    Uint16 ifIndex, long groupId) {
+        List<ActionInfo> result = new ArrayList<>();
+        switch (tunType) {
+            case "MPLS_OVER_GRE":
+                // fall through
+            case "GRE_TRUNK_INTERFACE":
+                if (!isDefaultEgress) {
+                    // TODO tunnel_id to encode GRE key, once it is supported
+                    // Until then, tunnel_id should be "cleaned", otherwise it
+                    // stores the value coming from a VXLAN tunnel
+                    if (tunnelKey == null) {
+                        tunnelKey = 0L;
+                    }
+                    result.add(new ActionSetFieldTunnelId(actionKeyStart++, Uint64.valueOf(tunnelKey)));
+                    addEgressActionInfosForInterface(ifIndex, actionKeyStart, result);
+                } else {
+                    result.add(new ActionOutput(actionKeyStart++, new Uri(portNo)));
+                }
+                break;
+                // fall through
+            case "VXLAN_TRUNK_INTERFACE":
+                if (!isDefaultEgress) {
+                    if (tunnelKey != null) {
+                        result.add(new ActionSetFieldTunnelId(actionKeyStart++, Uint64.valueOf(tunnelKey)));
+                    }
+                    addEgressActionInfosForInterface(ifIndex, actionKeyStart, result);
+                } else {
+                    result.add(new ActionOutput(actionKeyStart++, new Uri(portNo)));
+                }
+                break;
+            case "VLAN_INTERFACE":
+                LOG.error("VLAN swicth case");
+                if (isDefaultEgress) {
+                    result.add(new ActionOutput(actionKeyStart++, new Uri(portNo)));
+                } else {
+                    addEgressActionInfosForInterface(ifIndex, actionKeyStart, result);
+                }
+                break;
+            case "LOGICAL_GROUP_INTERFACE":
+                if (isDefaultEgress) {
+                    result.add(new ActionGroup(groupId));
+                } else {
+                    addEgressActionInfosForInterface(ifIndex, actionKeyStart, result);
+                }
+                break;
+
+            default:
+                LOG.warn("Interface Type {} not handled yet", tunType);
+                break;
+        }
+        return result;
+    }
+
+    public static void addEgressActionInfosForInterface(Uint16 ifIndex, int actionKeyStart, List<ActionInfo> result) {
+        long regValue = MetaDataUtil.getReg6ValueForLPortDispatcher(ifIndex.intValue(),
+                NwConstants.DEFAULT_SERVICE_INDEX);
+        result.add(new ActionRegLoad(actionKeyStart++, NxmNxReg6.class, ITMConstants.REG6_START_INDEX,
+                ITMConstants.REG6_END_INDEX, regValue));
+        result.add(new ActionNxResubmit(actionKeyStart, NwConstants.EGRESS_LPORT_DISPATCHER_TABLE));
+    }
+
+    public static BoundServices getBoundServices(String serviceName, short servicePriority, int flowPriority,
+                                                 Uint64 cookie, Map<InstructionKey, Instruction> instructions) {
+        StypeOpenflowBuilder augBuilder = new StypeOpenflowBuilder().setFlowCookie(cookie)
+                .setFlowPriority(Uint16.valueOf(flowPriority))
+                .setInstruction(instructions);
+        return new BoundServicesBuilder()
+                .withKey(new BoundServicesKey(Uint8.valueOf(servicePriority)))
+                .setServiceName(serviceName)
+                .setServicePriority(Uint8.valueOf(servicePriority))
+                .setServiceType(ServiceTypeFlowBased.class)
+                .addAugmentation(augBuilder.build()).build();
+    }
+
+    public static void bindService(TypedWriteTransaction<Datastore.Configuration> tx, String interfaceName,
+                                   BoundServices serviceInfo,
+                                   Class<? extends ServiceModeBase> serviceMode) {
+        LOG.info("Binding Service {} for : {}", serviceInfo.getServiceName(), interfaceName);
+        InstanceIdentifier<BoundServices> boundServicesInstanceIdentifier = buildBoundServicesIId(
+                serviceInfo.getServicePriority(), interfaceName, serviceMode);
+        tx.mergeParentStructurePut(boundServicesInstanceIdentifier, serviceInfo);
+    }
+
+    public static InstanceIdentifier<BoundServices> buildBoundServicesIId(Uint8 servicePriority, String interfaceName,
+                                                                      Class<? extends ServiceModeBase> serviceMode) {
+        return InstanceIdentifier.builder(ServiceBindings.class)
+                .child(ServicesInfo.class, new ServicesInfoKey(interfaceName, serviceMode))
+                .child(BoundServices.class, new BoundServicesKey(servicePriority)).build();
+    }
+}
index 4d69bc929c0093ca80c60081814f1008f687e741..c275fb2581dfd4715ee9a44c75212a128627f0a7 100644 (file)
@@ -32,6 +32,7 @@ import org.opendaylight.genius.itm.cache.OvsBridgeRefEntryCache;
 import org.opendaylight.genius.itm.cache.TunnelStateCache;
 import org.opendaylight.genius.itm.cache.UnprocessedNodeConnectorCache;
 import org.opendaylight.genius.itm.cache.UnprocessedNodeConnectorEndPointCache;
+import org.opendaylight.genius.itm.cache.UnprocessedOFNodeConnectorCache;
 import org.opendaylight.genius.itm.globals.ITMConstants;
 import org.opendaylight.genius.itm.itmdirecttunnels.renderer.ovs.utilities.DirectTunnelUtils;
 import org.opendaylight.genius.itm.rpc.ItmManagerRpcService;
@@ -193,6 +194,7 @@ public class ItmManagerRpcServiceTest {
     DirectTunnelUtils directTunnelUtils;
     UnprocessedNodeConnectorCache unprocessedNodeConnectorCache;
     UnprocessedNodeConnectorEndPointCache unprocessedNodeConnectorEndPointCache;
+    UnprocessedOFNodeConnectorCache unprocessedOFNCCache;
 
     Optional<ExternalTunnel> externalTunnelOptional ;
     Optional<InternalTunnel> internalTunnelOptional;
@@ -231,8 +233,8 @@ public class ItmManagerRpcServiceTest {
                 new TunnelStateCache(dataBroker, new GuavaCacheProvider(new CacheManagersRegistryImpl()));
         OvsBridgeRefEntryCache ovsBridgeRefEntryCache =
             new OvsBridgeRefEntryCache(dataBroker, new GuavaCacheProvider(new CacheManagersRegistryImpl()));
-        OfDpnTepConfigCache ofDpnTepConfigCache = new OfDpnTepConfigCache(dataBroker, new GuavaCacheProvider(
-                new CacheManagersRegistryImpl()));
+        OfDpnTepConfigCache ofDpnTepConfigCache = new OfDpnTepConfigCache(dataBroker, jobCoordinator,
+                new GuavaCacheProvider(new CacheManagersRegistryImpl()), directTunnelUtils, unprocessedOFNCCache);
 
         OfTepStateCache ofTepStateCache = new OfTepStateCache(dataBroker, new GuavaCacheProvider(
                 new CacheManagersRegistryImpl()));