Create UcastMacs by Listening DS Changes 55/30855/3
authorPeng Zhang <pzhang@ctbri.com.cn>
Fri, 4 Dec 2015 14:41:30 +0000 (22:41 +0800)
committerPeng Zhang <pzhang@ctbri.com.cn>
Mon, 7 Dec 2015 08:36:55 +0000 (16:36 +0800)
PathSet 1:
1. create UcastMacsLocal/Remote command
2. add UcastMacs restconf api to postman collection
3. delete physical locator update/remove command

PatchSet 2:
1. change according review comments

PathSet 3:
1. change according review comments

Change-Id: If926651a84d4ae4bac496eb9ca76b36f67b0a3f3
Signed-off-by: Peng Zhang <pzhang@ctbri.com.cn>
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/HwvtepOperationalState.java
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/PhysicalLocatorRemoveCommand.java [deleted file]
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/PhysicalLocatorUpdateCommand.java [deleted file]
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/TransactCommandAggregator.java
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/TransactUtils.java
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/UcastMacsLocalUpdateCommand.java
hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/UcastMacsRemoteUpdateCommand.java
resources/commons/Ovsdb-HwvtepSouthbound-Collection.json.postman_collection

index b09a5d9a076320bc32c151ad873a0d20bfa5357e..e3ad78a438dad10132c38e7746b80cdf25272adf 100644 (file)
@@ -25,8 +25,16 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hw
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalLocatorAugmentation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalPortAugmentation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.PhysicalSwitchAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LocalMcastMacs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LocalMcastMacsKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LocalUcastMacs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LocalUcastMacsKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitches;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitchesKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteMcastMacs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteMcastMacsKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteUcastMacs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteUcastMacsKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.Switches;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
@@ -36,15 +44,17 @@ import org.slf4j.LoggerFactory;
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 
+//TODO: need to be optimized, get entry by iid not name
 public class HwvtepOperationalState {
     private static final Logger LOG = LoggerFactory.getLogger(HwvtepOperationalState.class);
     private Map<InstanceIdentifier<Node>, Node> operationalNodes = new HashMap<>();
+    ReadWriteTransaction transaction;
 
     public HwvtepOperationalState(DataBroker db, Collection<DataTreeModification<Node>> changes) {
         Map<InstanceIdentifier<Node>, Node> nodeCreateOrUpdate =
             TransactUtils.extractCreatedOrUpdatedOrRemoved(changes, Node.class);
         if (nodeCreateOrUpdate != null) {
-            final ReadWriteTransaction transaction = db.newReadWriteTransaction();
+            transaction = db.newReadWriteTransaction();
             for (Entry<InstanceIdentifier<Node>, Node> entry: nodeCreateOrUpdate.entrySet()) {
                 Optional<Node> readNode = HwvtepSouthboundUtil.readNode(transaction, entry.getKey());
                 //add related globalNode or physicalSwitchNode to operationalNodes map
@@ -161,4 +171,96 @@ public class HwvtepOperationalState {
         }
         return Optional.absent();
     }
+
+    public Optional<LocalMcastMacs> getLocalMcastMacs(InstanceIdentifier<?> iid, LocalMcastMacsKey key) {
+        Preconditions.checkNotNull(iid);
+        Optional<HwvtepGlobalAugmentation> nodeOptional = getHwvtepGlobalAugmentation(iid);
+        if (nodeOptional.isPresent()) {
+            HwvtepGlobalAugmentation hgAugmentation = nodeOptional.get();
+            List<LocalMcastMacs> macList = null;
+            if (hgAugmentation != null) {
+                macList = hgAugmentation.getLocalMcastMacs();
+            }
+            if (macList != null) {
+                for (LocalMcastMacs mac: macList) {
+                    if (mac.getKey().equals(key)) {
+                        return Optional.fromNullable(mac);
+                    }
+                }
+            }
+        }
+        return Optional.absent();
+    }
+
+    public Optional<RemoteMcastMacs> getRemoteMcastMacs(InstanceIdentifier<?> iid, RemoteMcastMacsKey key) {
+        Preconditions.checkNotNull(iid);
+        Optional<HwvtepGlobalAugmentation> nodeOptional = getHwvtepGlobalAugmentation(iid);
+        if (nodeOptional.isPresent()) {
+            HwvtepGlobalAugmentation hgAugmentation = nodeOptional.get();
+            List<RemoteMcastMacs> macList = null;
+            if (hgAugmentation != null) {
+                macList = hgAugmentation.getRemoteMcastMacs();
+            }
+            if (macList != null) {
+                for (RemoteMcastMacs mac: macList) {
+                    if (mac.getKey().equals(key)) {
+                        return Optional.fromNullable(mac);
+                    }
+                }
+            }
+        }
+        return Optional.absent();
+    }
+
+    public Optional<LocalUcastMacs> getLocalUcastMacs(InstanceIdentifier<?> iid, LocalUcastMacsKey key) {
+        Preconditions.checkNotNull(iid);
+        Optional<HwvtepGlobalAugmentation> nodeOptional = getHwvtepGlobalAugmentation(iid);
+        if (nodeOptional.isPresent()) {
+            HwvtepGlobalAugmentation hgAugmentation = nodeOptional.get();
+            List<LocalUcastMacs> macList = null;
+            if (hgAugmentation != null) {
+                macList = hgAugmentation.getLocalUcastMacs();
+            }
+            if (macList != null) {
+                for (LocalUcastMacs mac: macList) {
+                    if (mac.getKey().equals(key)) {
+                        return Optional.fromNullable(mac);
+                    }
+                }
+            }
+        }
+        return Optional.absent();
+    }
+
+    public Optional<RemoteUcastMacs> getRemoteUcastMacs(InstanceIdentifier<?> iid, RemoteUcastMacsKey key) {
+        Preconditions.checkNotNull(iid);
+        Optional<HwvtepGlobalAugmentation> nodeOptional = getHwvtepGlobalAugmentation(iid);
+        if (nodeOptional.isPresent()) {
+            HwvtepGlobalAugmentation hgAugmentation = nodeOptional.get();
+            List<RemoteUcastMacs> macList = null;
+            if (hgAugmentation != null) {
+                macList = hgAugmentation.getRemoteUcastMacs();
+            }
+            if (macList != null) {
+                for (RemoteUcastMacs mac: macList) {
+                    if (mac.getKey().equals(key)) {
+                        return Optional.fromNullable(mac);
+                    }
+                }
+            }
+        }
+        return Optional.absent();
+    }
+
+    public Optional<HwvtepPhysicalLocatorAugmentation> getPhysicalLocatorAugmentation(InstanceIdentifier<TerminationPoint> iid) {
+        Optional<TerminationPoint> tp = HwvtepSouthboundUtil.readNode(transaction, iid);
+        if (tp.isPresent()) {
+            return Optional.fromNullable(tp.get().getAugmentation(HwvtepPhysicalLocatorAugmentation.class));
+        }
+        return Optional.absent();
+    }
+    
+    public ReadWriteTransaction getReadWriteTransaction() {
+        return transaction;
+    }
 }
diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/PhysicalLocatorRemoveCommand.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/PhysicalLocatorRemoveCommand.java
deleted file mode 100644 (file)
index 8206b4c..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2015 China Telecom Beijing Research Institute 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.ovsdb.hwvtepsouthbound.transact;
-
-import java.util.Collection;
-
-import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
-import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class PhysicalLocatorRemoveCommand extends AbstractTransactCommand {
-    private static final Logger LOG = LoggerFactory.getLogger(PhysicalLocatorRemoveCommand.class);
-
-    public PhysicalLocatorRemoveCommand(HwvtepOperationalState state,
-            Collection<DataTreeModification<Node>> changes) {
-        super(state, changes);
-    }
-
-    @Override
-    public void execute(TransactionBuilder transaction) {
-        //TODO
-    }
-}
diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/PhysicalLocatorUpdateCommand.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/PhysicalLocatorUpdateCommand.java
deleted file mode 100644 (file)
index 113d78b..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 2015 China Telecom Beijing Research Institute 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.ovsdb.hwvtepsouthbound.transact;
-
-import java.util.Collection;
-
-import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
-import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class PhysicalLocatorUpdateCommand extends AbstractTransactCommand {
-    private static final Logger LOG = LoggerFactory.getLogger(PhysicalLocatorUpdateCommand.class);
-
-    public PhysicalLocatorUpdateCommand(HwvtepOperationalState state,
-            Collection<DataTreeModification<Node>> changes) {
-        super(state, changes);
-    }
-
-    @Override
-    public void execute(TransactionBuilder transaction) {
-        //TODO
-    }
-
-}
index 0055cf32689062ad7f39670aad0b3cd756aefc46..cd1c79c864e464134dcd67452eb4496bd52eeb93 100644 (file)
@@ -27,8 +27,6 @@ public class TransactCommandAggregator implements TransactCommand {
         commands.add(new LogicalSwitchRemoveCommand(state,changes));
         commands.add(new PhysicalPortUpdateCommand(state,changes));
         commands.add(new PhysicalPortRemoveCommand(state,changes));
-        commands.add(new PhysicalLocatorUpdateCommand(state,changes));
-        commands.add(new PhysicalLocatorRemoveCommand(state,changes));
         commands.add(new McastMacsRemoteUpdateCommand(state,changes));
         commands.add(new McastMacsRemoteRemoveCommand(state,changes));
         commands.add(new McastMacsLocalUpdateCommand(state,changes));
index a62175069274cc6478431d8b692e65753d61a3e4..43e5617ecc946d8087dbc583b430a6efb5e6b0e7 100644 (file)
@@ -7,18 +7,33 @@
  */
 package org.opendaylight.ovsdb.hwvtepsouthbound.transact;
 
+import static org.opendaylight.ovsdb.lib.operations.Operations.op;
+
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.Map;
 
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification.ModificationType;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundConstants;
+import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundMapper;
+import org.opendaylight.ovsdb.lib.notation.UUID;
+import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
+import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
+import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalLocator;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalLocatorAugmentation;
 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;
+
 public class TransactUtils {
     private static final Logger LOG = LoggerFactory.getLogger(TransactUtils.class);
 
@@ -123,4 +138,37 @@ public class TransactUtils {
     }
     */
 
+    public static <D extends org.opendaylight.yangtools.yang.binding.DataObject> Optional<D> readNodeFromConfig(
+            ReadWriteTransaction transaction, final InstanceIdentifier<D> connectionIid) {
+        Optional<D> node = Optional.absent();
+        try {
+            node = transaction.read(LogicalDatastoreType.CONFIGURATION, connectionIid).checkedGet();
+        } catch (final ReadFailedException e) {
+            LOG.warn("Read Configration/DS for Node failed! {}", connectionIid, e);
+        }
+        return node;
+    }
+
+    public static UUID createPhysicalLocator(TransactionBuilder transaction, HwvtepPhysicalLocatorAugmentation inputLocator) {
+        LOG.debug("Creating a physical locator: {}", inputLocator.getDstIp());
+        PhysicalLocator physicalLocator = TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(), PhysicalLocator.class);
+        setEncapsulationType(physicalLocator, inputLocator);
+        setDstIp(physicalLocator, inputLocator);
+        String locatorUuid = "PhysicalLocator_" + HwvtepSouthboundMapper.getRandomUUID();
+        transaction.add(op.insert(physicalLocator).withId(locatorUuid));
+        return new UUID(locatorUuid);
+    }
+
+    private static final void setEncapsulationType(PhysicalLocator physicalLocator, HwvtepPhysicalLocatorAugmentation inputLocator) {
+        if (inputLocator.getEncapsulationType() != null) {
+            String encapType = HwvtepSouthboundConstants.ENCAPS_TYPE_MAP.get(HwvtepSouthboundMapper.createEncapsulationType(""));
+            physicalLocator.setEncapsulationType(encapType);
+        }
+    }
+
+    private static final void setDstIp(PhysicalLocator physicalLocator, HwvtepPhysicalLocatorAugmentation inputLocator) {
+        if (inputLocator.getDstIp() != null) {
+            physicalLocator.setDstIp(inputLocator.getDstIp().getIpv4Address().getValue());
+        }
+    }
 }
index 183bd7e3405f182a77fc6e95199d13839ada4f58..ee1106b333af80b19ccfefc9cecb02160888c8a5 100644 (file)
@@ -8,14 +8,35 @@
 
 package org.opendaylight.ovsdb.hwvtepsouthbound.transact;
 
+import static org.opendaylight.ovsdb.lib.operations.Operations.op;
+
 import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
 
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.ovsdb.lib.notation.UUID;
 import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
+import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
+import org.opendaylight.ovsdb.schema.hardwarevtep.UcastMacsLocal;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepNodeName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalLocatorAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LocalUcastMacs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitches;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitchesKey;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.base.Optional;
+
 public class UcastMacsLocalUpdateCommand extends AbstractTransactCommand {
     private static final Logger LOG = LoggerFactory.getLogger(PhysicalPortRemoveCommand.class);
 
@@ -26,6 +47,166 @@ public class UcastMacsLocalUpdateCommand extends AbstractTransactCommand {
 
     @Override
     public void execute(TransactionBuilder transaction) {
-        //TODO
+        Map<InstanceIdentifier<Node>, List<LocalUcastMacs>> createds =
+                extractCreated(getChanges(),LocalUcastMacs.class);
+        if (!createds.isEmpty()) {
+            for (Entry<InstanceIdentifier<Node>, List<LocalUcastMacs>> created:
+                createds.entrySet()) {
+                updateUcastMacsLocal(transaction,  created.getKey(), created.getValue());
+            }
+        }
+        Map<InstanceIdentifier<Node>, List<LocalUcastMacs>> updateds =
+                extractUpdated(getChanges(),LocalUcastMacs.class);
+        if (!updateds.isEmpty()) {
+            for (Entry<InstanceIdentifier<Node>, List<LocalUcastMacs>> updated:
+                updateds.entrySet()) {
+                updateUcastMacsLocal(transaction,  updated.getKey(), updated.getValue());
+            }
+        }
+    }
+
+    private void updateUcastMacsLocal(TransactionBuilder transaction,
+            InstanceIdentifier<Node> instanceIdentifier, List<LocalUcastMacs> localUcastMacs) {
+        for (LocalUcastMacs localUcastMac: localUcastMacs) {
+            LOG.debug("Creating localUcastMacs, mac address: {}", localUcastMac.getMacEntryKey().getValue());
+            Optional<LocalUcastMacs> operationalMacOptional =
+                    getOperationalState().getLocalUcastMacs(instanceIdentifier, localUcastMac.getKey());
+            UcastMacsLocal ucastMacsLocal = TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(), UcastMacsLocal.class);
+            setIpAddress(ucastMacsLocal, localUcastMac);
+            setLocator(transaction, ucastMacsLocal, localUcastMac);
+            setLogicalSwitch(instanceIdentifier, ucastMacsLocal, localUcastMac);
+            if (!operationalMacOptional.isPresent()) {
+                setMac(ucastMacsLocal, localUcastMac, operationalMacOptional);
+                transaction.add(op.insert(ucastMacsLocal));
+            } else {
+                LocalUcastMacs updatedMac = operationalMacOptional.get();
+                String existingMac = updatedMac.getMacEntryKey().getValue();
+                UcastMacsLocal extraMac = TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(), UcastMacsLocal.class);
+                extraMac.setMac("");;
+                transaction.add(op.update(ucastMacsLocal)
+                        .where(extraMac.getMacColumn().getSchema().opEqual(existingMac))
+                        .build());
+            }
+        }
+    }
+
+    private void setLogicalSwitch(InstanceIdentifier<Node> iid, UcastMacsLocal ucastMacsLocal, LocalUcastMacs inputMac) {
+        if (inputMac.getLogicalSwitchRef() != null) {
+            HwvtepNodeName lswitchName = new HwvtepNodeName(inputMac.getLogicalSwitchRef().getValue());
+            Optional<LogicalSwitches> operationalSwitchOptional =
+                    getOperationalState().getLogicalSwitches(iid, new LogicalSwitchesKey(lswitchName));
+            if (operationalSwitchOptional.isPresent()) {
+                Uuid logicalSwitchUuid = operationalSwitchOptional.get().getLogicalSwitchUuid();
+                UUID logicalSwitchUUID = new UUID(logicalSwitchUuid.getValue());
+                ucastMacsLocal.setLogicalSwitch(logicalSwitchUUID);
+            } else {
+                LOG.warn("Create or update localUcastMacs: No logical switch named {} found in operational datastore!",
+                        lswitchName);
+            }
+        }
+    }
+
+    private void setLocator(TransactionBuilder transaction, UcastMacsLocal ucastMacsLocal, LocalUcastMacs inputMac) {
+        //get UUID by locatorRef
+        if (inputMac.getLocatorRef() != null) {
+            UUID locatorUuid = null;
+            @SuppressWarnings("unchecked")
+            InstanceIdentifier<TerminationPoint> iid = (InstanceIdentifier<TerminationPoint>) inputMac.getLocatorRef().getValue();
+            //try to find locator in operational DS
+            Optional<HwvtepPhysicalLocatorAugmentation> operationalLocatorOptional =
+                    getOperationalState().getPhysicalLocatorAugmentation(iid);
+            if (operationalLocatorOptional.isPresent()) {
+                //if exist, get uuid
+                HwvtepPhysicalLocatorAugmentation locatorAugmentation = operationalLocatorOptional.get();
+                locatorUuid = new UUID(locatorAugmentation.getPhysicalLocatorUuid().getValue());
+            } else {
+                //if no, get it from config DS and create id
+                Optional<TerminationPoint> configLocatorOptional =
+                        TransactUtils.readNodeFromConfig(getOperationalState().getReadWriteTransaction(), iid);
+                if (configLocatorOptional.isPresent()) {
+                    HwvtepPhysicalLocatorAugmentation locatorAugmentation =
+                            configLocatorOptional.get().getAugmentation(HwvtepPhysicalLocatorAugmentation.class);
+                    locatorUuid = TransactUtils.createPhysicalLocator(transaction, locatorAugmentation);
+                } else {
+                    LOG.warn("Create or update localUcastMac: No physical locator found in operational datastore!"
+                            + "Its indentifier is {}", inputMac.getLocatorRef().getValue());
+                }
+            }
+            if (locatorUuid != null) {
+                ucastMacsLocal.setLocator(locatorUuid);
+            }
+        }
+    }
+
+    private void setIpAddress(UcastMacsLocal ucastMacsLocal, LocalUcastMacs inputMac) {
+        if (inputMac.getIpaddr() != null) {
+            ucastMacsLocal.setIpAddress(inputMac.getIpaddr().getIpv4Address().getValue());
+        }
+    }
+
+    private void setMac(UcastMacsLocal ucastMacsLocal, LocalUcastMacs inputMac,
+            Optional<LocalUcastMacs> inputSwitchOptional) {
+        if (inputMac.getMacEntryKey() != null) {
+            ucastMacsLocal.setMac(inputMac.getMacEntryKey().getValue());
+        } else if (inputSwitchOptional.isPresent() && inputSwitchOptional.get().getMacEntryKey() != null) {
+            ucastMacsLocal.setMac(inputSwitchOptional.get().getMacEntryKey().getValue());
+        }
+    }
+
+    private Map<InstanceIdentifier<Node>, List<LocalUcastMacs>> extractCreated(
+            Collection<DataTreeModification<Node>> changes, Class<LocalUcastMacs> class1) {
+        Map<InstanceIdentifier<Node>, List<LocalUcastMacs>> result
+            = new HashMap<InstanceIdentifier<Node>, List<LocalUcastMacs>>();
+        if (changes != null && !changes.isEmpty()) {
+            for (DataTreeModification<Node> change : changes) {
+                final InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
+                final DataObjectModification<Node> mod = change.getRootNode();
+                Node created = TransactUtils.getCreated(mod);
+                if (created != null) {
+                    List<LocalUcastMacs> macListUpdated = null;
+                    HwvtepGlobalAugmentation hgAugmentation = created.getAugmentation(HwvtepGlobalAugmentation.class);
+                    if (hgAugmentation != null) {
+                        macListUpdated = hgAugmentation.getLocalUcastMacs();
+                    }
+                    if (macListUpdated != null) {
+                        result.put(key, macListUpdated);
+                    }
+                }
+            }
+        }
+        return result;
+    }
+
+    private Map<InstanceIdentifier<Node>, List<LocalUcastMacs>> extractUpdated(
+            Collection<DataTreeModification<Node>> changes, Class<LocalUcastMacs> class1) {
+        Map<InstanceIdentifier<Node>, List<LocalUcastMacs>> result
+            = new HashMap<InstanceIdentifier<Node>, List<LocalUcastMacs>>();
+        if (changes != null && !changes.isEmpty()) {
+            for (DataTreeModification<Node> change : changes) {
+                final InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
+                final DataObjectModification<Node> mod = change.getRootNode();
+                Node updated = TransactUtils.getUpdated(mod);
+                Node before = mod.getDataBefore();
+                if (updated != null && before != null) {
+                    List<LocalUcastMacs> macListUpdated = null;
+                    List<LocalUcastMacs> macListBefore = null;
+                    HwvtepGlobalAugmentation hgUpdated = updated.getAugmentation(HwvtepGlobalAugmentation.class);
+                    if (hgUpdated != null) {
+                        macListUpdated = hgUpdated.getLocalUcastMacs();
+                    }
+                    HwvtepGlobalAugmentation hgBefore = before.getAugmentation(HwvtepGlobalAugmentation.class);
+                    if (hgBefore != null) {
+                        macListBefore = hgBefore.getLocalUcastMacs();
+                    }
+                    if (macListUpdated != null) {
+                        if (macListBefore != null) {
+                            macListUpdated.removeAll(macListBefore);
+                        }
+                        result.put(key, macListUpdated);
+                    }
+                }
+            }
+        }
+        return result;
     }
-}
\ No newline at end of file
+}
index 0363fd679b597b0c8c185928e93d59f06f3a0361..2de4177ea64e82387634ec95ef3c5eb2b6ebb573 100644 (file)
@@ -8,14 +8,35 @@
 
 package org.opendaylight.ovsdb.hwvtepsouthbound.transact;
 
+import static org.opendaylight.ovsdb.lib.operations.Operations.op;
+
 import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
 
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.ovsdb.lib.notation.UUID;
 import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
+import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
+import org.opendaylight.ovsdb.schema.hardwarevtep.UcastMacsRemote;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepNodeName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalLocatorAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitches;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitchesKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteUcastMacs;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
 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;
+
 public class UcastMacsRemoteUpdateCommand extends AbstractTransactCommand {
     private static final Logger LOG = LoggerFactory.getLogger(PhysicalPortRemoveCommand.class);
 
@@ -26,6 +47,167 @@ public class UcastMacsRemoteUpdateCommand extends AbstractTransactCommand {
 
     @Override
     public void execute(TransactionBuilder transaction) {
-        //TODO
+        Map<InstanceIdentifier<Node>, List<RemoteUcastMacs>> createds =
+                extractCreated(getChanges(),RemoteUcastMacs.class);
+        if (!createds.isEmpty()) {
+            for (Entry<InstanceIdentifier<Node>, List<RemoteUcastMacs>> created:
+                createds.entrySet()) {
+                updateUcastMacsRemote(transaction,  created.getKey(), created.getValue());
+            }
+        }
+        Map<InstanceIdentifier<Node>, List<RemoteUcastMacs>> updateds =
+                extractUpdated(getChanges(),RemoteUcastMacs.class);
+        if (!updateds.isEmpty()) {
+            for (Entry<InstanceIdentifier<Node>, List<RemoteUcastMacs>> updated:
+                updateds.entrySet()) {
+                updateUcastMacsRemote(transaction,  updated.getKey(), updated.getValue());
+            }
+        }
+    }
+
+    private void updateUcastMacsRemote(TransactionBuilder transaction,
+            InstanceIdentifier<Node> instanceIdentifier, List<RemoteUcastMacs> remoteUcastMacs) {
+        for (RemoteUcastMacs remoteUcastMac: remoteUcastMacs) {
+            LOG.debug("Creating remoteUcastMacs, mac address: {}", remoteUcastMac.getMacEntryKey().getValue());
+            Optional<RemoteUcastMacs> operationalMacOptional =
+                    getOperationalState().getRemoteUcastMacs(instanceIdentifier, remoteUcastMac.getKey());
+            UcastMacsRemote ucastMacsRemote = TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(), UcastMacsRemote.class);
+            setIpAddress(ucastMacsRemote, remoteUcastMac);
+            setLocator(transaction, ucastMacsRemote, remoteUcastMac);
+            setLogicalSwitch(instanceIdentifier, ucastMacsRemote, remoteUcastMac);
+            if (!operationalMacOptional.isPresent()) {
+                setMac(ucastMacsRemote, remoteUcastMac, operationalMacOptional);
+                transaction.add(op.insert(ucastMacsRemote));
+            } else {
+                RemoteUcastMacs updatedMac = operationalMacOptional.get();
+                String existingMac = updatedMac.getMacEntryKey().getValue();
+                UcastMacsRemote extraMac = TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(), UcastMacsRemote.class);
+                extraMac.setMac("");;
+                transaction.add(op.update(ucastMacsRemote)
+                        .where(extraMac.getMacColumn().getSchema().opEqual(existingMac))
+                        .build());
+            }
+        }
+    }
+
+    private void setLogicalSwitch(InstanceIdentifier<Node> iid, UcastMacsRemote ucastMacsRemote, RemoteUcastMacs inputMac) {
+        if (inputMac.getLogicalSwitchRef() != null) {
+            HwvtepNodeName lswitchName = new HwvtepNodeName(inputMac.getLogicalSwitchRef().getValue());
+            Optional<LogicalSwitches> operationalSwitchOptional =
+                    getOperationalState().getLogicalSwitches(iid, new LogicalSwitchesKey(lswitchName));
+            if (operationalSwitchOptional.isPresent()) {
+                Uuid logicalSwitchUuid = operationalSwitchOptional.get().getLogicalSwitchUuid();
+                UUID logicalSwitchUUID = new UUID(logicalSwitchUuid.getValue());
+                ucastMacsRemote.setLogicalSwitch(logicalSwitchUUID);
+            } else {
+                LOG.warn("Create or update remoteUcastMac: No logical switch named {} found in operational datastore!",
+                        lswitchName);
+            }
+        }
+    }
+
+    private void setLocator(TransactionBuilder transaction, UcastMacsRemote ucastMacsRemote, RemoteUcastMacs inputMac) {
+        //get UUID by locatorRef
+        if (inputMac.getLocatorRef() != null) {
+            UUID locatorUuid = null;
+            @SuppressWarnings("unchecked")
+            InstanceIdentifier<TerminationPoint> iid = (InstanceIdentifier<TerminationPoint>) inputMac.getLocatorRef().getValue();
+            //try to find locator in operational DS
+            Optional<HwvtepPhysicalLocatorAugmentation> operationalLocatorOptional =
+                    getOperationalState().getPhysicalLocatorAugmentation(iid);
+            if (operationalLocatorOptional.isPresent()) {
+                //if exist, get uuid
+                HwvtepPhysicalLocatorAugmentation locatorAugmentation = operationalLocatorOptional.get();
+                locatorUuid = new UUID(locatorAugmentation.getPhysicalLocatorUuid().getValue());
+            } else {
+                //TODO: need to optimize by eliminating reading Configuration datastore
+                //if no, get it from config DS and create id
+                Optional<TerminationPoint> configLocatorOptional =
+                        TransactUtils.readNodeFromConfig(getOperationalState().getReadWriteTransaction(), iid);
+                if (configLocatorOptional.isPresent()) {
+                    HwvtepPhysicalLocatorAugmentation locatorAugmentation =
+                            configLocatorOptional.get().getAugmentation(HwvtepPhysicalLocatorAugmentation.class);
+                    locatorUuid = TransactUtils.createPhysicalLocator(transaction, locatorAugmentation);
+                } else {
+                    LOG.warn("Create or update remoteUcastMac: No physical locator found in operational datastore!"
+                            + "Its indentifier is {}", inputMac.getLocatorRef().getValue());
+                }
+            }
+            if (locatorUuid != null) {
+                ucastMacsRemote.setLocator(locatorUuid);
+            }
+        }
+    }
+
+    private void setIpAddress(UcastMacsRemote ucastMacsRemote, RemoteUcastMacs inputMac) {
+        if (inputMac.getIpaddr() != null) {
+            ucastMacsRemote.setIpAddress(inputMac.getIpaddr().getIpv4Address().getValue());
+        }
+    }
+
+    private void setMac(UcastMacsRemote ucastMacsRemote, RemoteUcastMacs inputMac,
+            Optional<RemoteUcastMacs> inputSwitchOptional) {
+        if (inputMac.getMacEntryKey() != null) {
+            ucastMacsRemote.setMac(inputMac.getMacEntryKey().getValue());
+        } else if (inputSwitchOptional.isPresent() && inputSwitchOptional.get().getMacEntryKey() != null) {
+            ucastMacsRemote.setMac(inputSwitchOptional.get().getMacEntryKey().getValue());
+        }
+    }
+
+    private Map<InstanceIdentifier<Node>, List<RemoteUcastMacs>> extractCreated(
+            Collection<DataTreeModification<Node>> changes, Class<RemoteUcastMacs> class1) {
+        Map<InstanceIdentifier<Node>, List<RemoteUcastMacs>> result
+            = new HashMap<InstanceIdentifier<Node>, List<RemoteUcastMacs>>();
+        if (changes != null && !changes.isEmpty()) {
+            for (DataTreeModification<Node> change : changes) {
+                final InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
+                final DataObjectModification<Node> mod = change.getRootNode();
+                Node created = TransactUtils.getCreated(mod);
+                if (created != null) {
+                    List<RemoteUcastMacs> macListUpdated = null;
+                    HwvtepGlobalAugmentation hgAugmentation = created.getAugmentation(HwvtepGlobalAugmentation.class);
+                    if (hgAugmentation != null) {
+                        macListUpdated = hgAugmentation.getRemoteUcastMacs();
+                    }
+                    if (macListUpdated != null) {
+                        result.put(key, macListUpdated);
+                    }
+                }
+            }
+        }
+        return result;
+    }
+
+    private Map<InstanceIdentifier<Node>, List<RemoteUcastMacs>> extractUpdated(
+            Collection<DataTreeModification<Node>> changes, Class<RemoteUcastMacs> class1) {
+        Map<InstanceIdentifier<Node>, List<RemoteUcastMacs>> result
+            = new HashMap<InstanceIdentifier<Node>, List<RemoteUcastMacs>>();
+        if (changes != null && !changes.isEmpty()) {
+            for (DataTreeModification<Node> change : changes) {
+                final InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
+                final DataObjectModification<Node> mod = change.getRootNode();
+                Node updated = TransactUtils.getUpdated(mod);
+                Node before = mod.getDataBefore();
+                if (updated != null && before != null) {
+                    List<RemoteUcastMacs> macListUpdated = null;
+                    List<RemoteUcastMacs> macListBefore = null;
+                    HwvtepGlobalAugmentation hgUpdated = updated.getAugmentation(HwvtepGlobalAugmentation.class);
+                    if (hgUpdated != null) {
+                        macListUpdated = hgUpdated.getRemoteUcastMacs();
+                    }
+                    HwvtepGlobalAugmentation hgBefore = before.getAugmentation(HwvtepGlobalAugmentation.class);
+                    if (hgBefore != null) {
+                        macListBefore = hgBefore.getRemoteUcastMacs();
+                    }
+                    if (macListUpdated != null) {
+                        if (macListBefore != null) {
+                            macListUpdated.removeAll(macListBefore);
+                        }
+                        result.put(key, macListUpdated);
+                    }
+                }
+            }
+        }
+        return result;
     }
 }
\ No newline at end of file
index 9a08d17937632a20d9f62f897e492f342160fedf..bd634b0f3d50aedfafa50a098180fcf03e1b4d79 100755 (executable)
         "f6d300f7-380a-d090-0d4a-2b2ddefe5104",
         "f9f71d74-a49d-b190-d929-b6772ce0ba73",
         "18032e93-3bc5-9976-4525-fe1e77e98207",
+        "6f6addb7-6d48-e1ef-8cc2-c5841d71c2e5",
+        "20e8b57b-a5e7-a52f-01d6-7b66ea551078",
+        "7714d521-baf0-2dc2-e8ca-4f6228270099",
+        "92bb5645-1804-8174-5e73-2b0780feecfa",
+        "3c387234-5ae9-e589-2fe0-11666b00fec9",
+        "d01abaee-9f84-d625-4dc8-56da031255a1",
+        "6329fb56-9e3b-647f-141a-dad277c303fd",
+        "51384eb0-05f8-7636-90d8-6d55605f80e6",
+        "dd1cd03e-ab78-b6da-5cd8-271e1c6f9c75",
         "22354294-1d01-cebf-180c-d609747be9bc",
         "c8e8f3fd-3bfb-aafa-e3ec-a671a942f426",
         "d362ddc4-1c5f-67d5-e354-c2a8d2ba9d79",
         "538c71b3-e3e6-f01b-cc4c-d2b686686aa8",
         "a13e6877-997e-84e1-c8e8-e83ef5e9a002",
-        "3c86ab7c-a7ee-6b71-3ec1-da7d20f97d1a"
+        "3c86ab7c-a7ee-6b71-3ec1-da7d20f97d1a",
+        "4602c331-5850-0813-c276-d4ec3ae7b3d6",
+        "3b8a86df-fe33-5104-2da7-5e0cbdb7a881"
     ],
     "owner":0,
     "sharedWithTeam":false,
             "time": 1448718837283,
             "name": "Get Specific Operational Physical Port",
             "description": ""
+        },
+        {
+            "collectionId": "19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+            "id": "20e8b57b-a5e7-a52f-01d6-7b66ea551078",
+            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+            "url": "http://{{controllerHost}}:8181/restconf/config/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640",
+            "preRequestScript": "",
+            "pathVariables": {},
+            "method": "POST",
+            "data": [],
+            "dataMode": "raw",
+            "version": 2,
+            "tests": "",
+            "currentHelper": "normal",
+            "helperAttributes": {},
+            "time": 1449132978312,
+            "name": "Create Specific Config UcastMacRemote",
+            "description": "",
+            "rawModeData": "{\n  \"remote-ucast-macs\": [\n        {\n            \"mac-entry-key\": \"11:11:11:11:11:11\",\n            \"logical-switch-ref\": \"ls0\",\n            \"ipaddr\": \"1.1.1.1\",\n            \"locator-ref\": \"/network-topology:network-topology/network-topology:topology[network-topology:topology-id='hwvtep:1']/network-topology:node[network-topology:node-id='hwvtep://{{hwvtepNodeIp}}:6640']/network-topology:termination-point[network-topology:tp-id='vxlan_over_ipv4:{{LocatorIp}}']\"             \n        }\n    ]\n}"
+        },
+        {
+            "collectionId": "19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+            "id": "7714d521-baf0-2dc2-e8ca-4f6228270099",
+            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+            "url": "http://{{controllerHost}}:8181/restconf/config/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640/remote-ucast-macs/11:11:11:11:11:11",
+            "preRequestScript": "",
+            "pathVariables": {},
+            "method": "PUT",
+            "data": [],
+            "dataMode": "raw",
+            "version": 2,
+            "tests": "",
+            "currentHelper": "normal",
+            "helperAttributes": {},
+            "time": 1449310821724,
+            "name": "Update Specific Config UcastMacRemote",
+            "description": "",
+            "rawModeData": "{\n  \"remote-ucast-macs\": [\n        {\n            \"mac-entry-key\": \"11:11:11:11:11:11\",\n            \"logical-switch-ref\": \"ls0\",\n            \"ipaddr\": \"1.1.1.1\",\n            \"locator-ref\": \"/network-topology:network-topology/network-topology:topology[network-topology:topology-id='hwvtep:1']/network-topology:node[network-topology:node-id='hwvtep://{{hwvtepNodeIp}}:6640']/network-topology:termination-point[network-topology:tp-id='vxlan_over_ipv4:{{LocatorIp}}']\"\n        }\n    ]\n}"
+        },
+        {
+            "collectionId": "19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+            "id": "92bb5645-1804-8174-5e73-2b0780feecfa",
+            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+            "url": "http://{{controllerHost}}:8181/restconf/config/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640/remote-ucast-macs/11:11:11:11:11:11",
+            "preRequestScript": "",
+            "pathVariables": {},
+            "method": "GET",
+            "data": [],
+            "dataMode": "params",
+            "version": 2,
+            "tests": "",
+            "currentHelper": "normal",
+            "helperAttributes": {},
+            "time": 1449311389212,
+            "name": "Get Specific Config UcastMacRemote",
+            "description": ""
+        },
+        {
+            "collectionId": "19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+            "id": "3c387234-5ae9-e589-2fe0-11666b00fec9",
+            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+            "url": "http://{{controllerHost}}:8181/restconf/config/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640/remote-ucast-macs/11:11:11:11:11:11",
+            "preRequestScript": "",
+            "pathVariables": {},
+            "method": "DELETE",
+            "data": [],
+            "dataMode": "raw",
+            "version": 2,
+            "tests": "",
+            "currentHelper": "normal",
+            "helperAttributes": {},
+            "time": 1449311417267,
+            "name": "Delete Specific Config UcastMacRemote",
+            "description": "",
+            "rawModeData": ""
+        },
+        {
+            "collectionId": "19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+            "id": "4602c331-5850-0813-c276-d4ec3ae7b3d6",
+            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+            "url": "http://{{controllerHost}}:8181/operational/config/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640/remote-ucast-macs/11:11:11:11:11:11",
+            "preRequestScript": "",
+            "pathVariables": {},
+            "method": "GET",
+            "data": [],
+            "dataMode": "params",
+            "version": 2,
+            "tests": "",
+            "currentHelper": "normal",
+            "helperAttributes": {},
+            "time": 1449314879742,
+            "name": "Get Specific Operational UcastMacRemote",
+            "description": ""
+        },
+        {
+            "collectionId": "19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+            "id": "6f6addb7-6d48-e1ef-8cc2-c5841d71c2e5",
+            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+            "url": "http://{{controllerHost}}:8181/restconf/config/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640",
+            "preRequestScript": "",
+            "pathVariables": {},
+            "method": "POST",
+            "data": [],
+            "dataMode": "raw",
+            "version": 2,
+            "tests": "",
+            "currentHelper": "normal",
+            "helperAttributes": {},
+            "time": 1448972198808,
+            "name": "Create Specific Config Locator",
+            "description": "",
+            "rawModeData": "{\n  \"termination-point\": [\n        {\n            \"tp-id\": \"vxlan_over_ipv4:{{LocatorIp}}\",\n            \"encapsulation-type\": \"encapsulation-type-vxlan-over-ipv4\",\n          \t\"dst-ip\": \"{{LocatorIp}}\"\n\t\t}\n    ]\n}"
+        },
+        {
+            "collectionId": "19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+            "id": "d01abaee-9f84-d625-4dc8-56da031255a1",
+            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+            "url": "http://{{controllerHost}}:8181/restconf/config/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640",
+            "preRequestScript": "",
+            "pathVariables": {},
+            "method": "POST",
+            "data": [],
+            "dataMode": "raw",
+            "version": 2,
+            "tests": "",
+            "currentHelper": "normal",
+            "helperAttributes": {},
+            "time": 1449286080233,
+            "name": "Create Specific Config UcastMacLocal",
+            "description": "",
+            "rawModeData": "{\n  \"local-ucast-macs\": [\n        {\n            \"mac-entry-key\": \"22:22:22:22:22:22\",\n            \"logical-switch-ref\": \"ls0\",\n            \"ipaddr\": \"2.2.2.2\",\n            \"locator-ref\": \"/network-topology:network-topology/network-topology:topology[network-topology:topology-id='hwvtep:1']/network-topology:node[network-topology:node-id='hwvtep://{{hwvtepNodeIp}}:6640']/network-topology:termination-point[network-topology:tp-id='vxlan_over_ipv4:{{LocatorIp}}']\"             \n        }\n    ]\n}"
+        },
+        {
+            "collectionId": "19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+            "id": "6329fb56-9e3b-647f-141a-dad277c303fd",
+            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+            "url": "http://{{controllerHost}}:8181/restconf/config/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640/local-ucast-macs/22:11:11:11:11:11",
+            "preRequestScript": "",
+            "pathVariables": {},
+            "method": "PUT",
+            "data": [],
+            "dataMode": "raw",
+            "version": 2,
+            "tests": "",
+            "currentHelper": "normal",
+            "helperAttributes": {},
+            "time": 1449310498424,
+            "name": "Update Specific Config UcastMacLocal",
+            "description": "",
+            "rawModeData": "{\n  \"local-ucast-macs\": [\n        {\n            \"mac-entry-key\": \"22:22:22:22:22:22\",\n            \"logical-switch-ref\": \"ls0\",\n            \"ipaddr\": \"2.2.2.2\",\n            \"locator-ref\": \"/network-topology:network-topology/network-topology:topology[network-topology:topology-id='hwvtep:1']/network-topology:node[network-topology:node-id='hwvtep://{{hwvtepNodeIp}}:6640']/network-topology:termination-point[network-topology:tp-id='vxlan_over_ipv4:{{LocatorIp}}']\"\n        }\n    ]\n}"
+        },
+        {
+            "collectionId": "19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+            "id": "51384eb0-05f8-7636-90d8-6d55605f80e6",
+            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+            "url": "http://{{controllerHost}}:8181/restconf/config/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640/local-ucast-macs/22:22:22:22:22:22",
+            "preRequestScript": "",
+            "pathVariables": {},
+            "method": "GET",
+            "data": [],
+            "dataMode": "params",
+            "version": 2,
+            "tests": "",
+            "currentHelper": "normal",
+            "helperAttributes": {},
+            "time": 1449311223998,
+            "name": "Get Specific Config UcastMacLocal ",
+            "description": ""
+        },
+        {
+            "collectionId": "19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+            "id": "dd1cd03e-ab78-b6da-5cd8-271e1c6f9c75",
+            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+            "url": "http://{{controllerHost}}:8181/restconf/config/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640/local-ucast-macs/22:22:22:22:22:22",
+            "preRequestScript": "",
+            "pathVariables": {},
+            "method": "DELETE",
+            "data": [],
+            "dataMode": "raw",
+            "version": 2,
+            "tests": "",
+            "currentHelper": "normal",
+            "helperAttributes": {},
+            "time": 1449311421493,
+            "name": "Delete Specific Config UcastMacLocal",
+            "description": "",
+            "rawModeData": ""
+        },
+        {
+            "collectionId": "19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+            "id": "3b8a86df-fe33-5104-2da7-5e0cbdb7a881",
+            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+            "url": "http://{{controllerHost}}:8181/restconf/operational/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640/local-ucast-macs/22:22:22:22:22:22",
+            "preRequestScript": "",
+            "pathVariables": {},
+            "method": "GET",
+            "data": [],
+            "dataMode": "params",
+            "version": 2,
+            "tests": "",
+            "currentHelper": "normal",
+            "helperAttributes": {},
+            "time": 1449315928725,
+            "name": "Get Specific Operational UcastMacLocal ",
+            "description": ""
         }
     ]
 }