From 52cc1d3034c782670abc89e2deb0b4e6eb39dacb Mon Sep 17 00:00:00 2001 From: "K.V Suneelu Verma" Date: Fri, 2 Dec 2016 20:24:50 +0530 Subject: [PATCH] bug 6579 removed boilerplate code removed the boilerplate code from commands moved it to super class pulled the methods extractUpdated and extractRemoved to super class child class implements getData and areEqual methods extractUpdated method compares old data and new data and returns the change set. Comparison logic is taken care by the sub class. extractDeleted gets the deleted keys . for local ucast mac remove command ,If logical switch is deleted , it will return the local ucast macs to be deleted aswell. logical switch removal is fired in seperate transaction to avoid failure of transaction because of some local references which odl is not aware of sometimes due to racing conditions. if mcast mac locator set gets emptied , fire removal of mcast mac if the json rpc transaction fails, clear the intransit data from device info Change-Id: Ia172b5887887f202ba1149ba748862d86f9c9869 Signed-off-by: K.V Suneelu Verma --- .../HwvtepConnectionInstance.java | 2 +- .../hwvtepsouthbound/HwvtepDeviceInfo.java | 31 +++ .../HwvtepSouthboundUtil.java | 16 +- .../GlobalConfigOperationalChangeGetter.java | 12 +- .../transact/AbstractTransactCommand.java | 192 +++++++++++++++++- .../transact/DependencyQueue.java | 4 + .../transact/LogicalSwitchRemoveCommand.java | 106 +++------- .../transact/LogicalSwitchUpdateCommand.java | 74 +------ .../transact/McastMacsLocalRemoveCommand.java | 95 +++------ .../transact/McastMacsLocalUpdateCommand.java | 70 +------ .../McastMacsRemoteRemoveCommand.java | 99 +++------ .../McastMacsRemoteUpdateCommand.java | 93 ++------- .../transact/PhysicalPortRemoveCommand.java | 5 +- .../transact/PhysicalPortUpdateCommand.java | 4 +- .../transact/PhysicalSwitchRemoveCommand.java | 4 +- .../transact/PhysicalSwitchUpdateCommand.java | 4 +- .../transact/TransactInvokerImpl.java | 53 ++++- .../transact/TransactUtils.java | 40 ++-- .../transact/UcastMacsLocalRemoveCommand.java | 95 +++------ .../transact/UcastMacsLocalUpdateCommand.java | 70 +------ .../UcastMacsRemoteRemoveCommand.java | 74 +------ .../UcastMacsRemoteUpdateCommand.java | 93 ++------- .../HwvtepPhysicalLocatorUpdateCommand.java | 4 +- .../DataChangeListenerTestBase.java | 53 ++++- .../HwvtepDataChangeListenerTest.java | 187 ++++++++++++++++- .../HwvtepOperationalDataChangeListener.java | 140 +++++++++++++ .../ovsdb/hwvtepsouthbound/TestBuilders.java | 6 +- .../ovsdb/hwvtepsouthbound/hwvtep_schema.json | 27 +++ 28 files changed, 906 insertions(+), 747 deletions(-) create mode 100644 hwvtepsouthbound/hwvtepsouthbound-impl/src/test/java/org/opendaylight/ovsdb/hwvtepsouthbound/HwvtepOperationalDataChangeListener.java diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/HwvtepConnectionInstance.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/HwvtepConnectionInstance.java index cec5fc852..1741042b7 100644 --- a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/HwvtepConnectionInstance.java +++ b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/HwvtepConnectionInstance.java @@ -80,7 +80,7 @@ public class HwvtepConnectionInstance { this.dataBroker = dataBroker; } - public void transact(TransactCommand command) { + public synchronized void transact(TransactCommand command) { for (TransactInvoker transactInvoker: transactInvokers.values()) { transactInvoker.invoke(command); } diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/HwvtepDeviceInfo.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/HwvtepDeviceInfo.java index ba0b1a388..0c8fec7f9 100644 --- a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/HwvtepDeviceInfo.java +++ b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/HwvtepDeviceInfo.java @@ -10,6 +10,7 @@ package org.opendaylight.ovsdb.hwvtepsouthbound; import org.opendaylight.ovsdb.hwvtepsouthbound.transact.DependencyQueue; import org.opendaylight.ovsdb.hwvtepsouthbound.transact.DependentJob; +import org.opendaylight.ovsdb.hwvtepsouthbound.transact.TransactCommand; import org.opendaylight.ovsdb.lib.notation.UUID; import org.opendaylight.ovsdb.schema.hardwarevtep.LogicalSwitch; import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalLocator; @@ -22,6 +23,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.HashMap; +import java.util.Iterator; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -177,16 +179,22 @@ public class HwvtepDeviceInfo { new DeviceData(key, null, data, DeviceDataStatus.AVAILABLE)); } + public Object getConfigData(Class cls, InstanceIdentifier key) { + return HwvtepSouthboundUtil.getData(configKeyVsData, cls, key); + } + public void clearConfigData(Class cls, InstanceIdentifier key) { HwvtepSouthboundUtil.clearData(configKeyVsData, cls, key); } public void markKeyAsInTransit(Class cls, InstanceIdentifier key) { + LOG.debug("Marking device data as intransit {}", key); HwvtepSouthboundUtil.updateData(opKeyVsData, cls, key, new DeviceData(key, null, null, DeviceDataStatus.IN_TRANSIT)); } public void updateDeviceOpData(Class cls, InstanceIdentifier key, UUID uuid, Object data) { + LOG.debug("Updating device data {}", key); HwvtepSouthboundUtil.updateData(opKeyVsData, cls, key, new DeviceData(key, uuid, data, DeviceDataStatus.AVAILABLE)); HwvtepSouthboundUtil.updateData(uuidVsData, cls, uuid, data); @@ -227,4 +235,27 @@ public class HwvtepDeviceInfo { public void onOpDataAvailable() { dependencyQueue.processReadyJobsFromOpQueue(connectionInstance); } + + public void scheduleTransaction(final TransactCommand transactCommand) { + dependencyQueue.submit(new Runnable() { + @Override + public void run() { + connectionInstance.transact(transactCommand); + } + }); + } + + public void clearInTransitData() { + //TODO restore old data + for (Map map : opKeyVsData.values()) { + Iterator> iterator = map.entrySet().iterator(); + while ( iterator.hasNext() ) { + Map.Entry entry = iterator.next(); + if (entry.getValue().getStatus() == DeviceDataStatus.IN_TRANSIT) { + iterator.remove(); + } + } + } + onOpDataAvailable(); + } } diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/HwvtepSouthboundUtil.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/HwvtepSouthboundUtil.java index eb29948f9..0a21cb73a 100644 --- a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/HwvtepSouthboundUtil.java +++ b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/HwvtepSouthboundUtil.java @@ -21,15 +21,25 @@ 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.HwvtepGlobalRef; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalSwitchAttributes; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.ConnectionInfo; +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.RemoteMcastMacs; +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; +import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.Identifiable; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.data.impl.codec.DeserializationException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.google.common.base.Optional; +import com.google.common.base.Preconditions; +import com.google.common.util.concurrent.CheckedFuture; + +import java.util.Collection; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; public class HwvtepSouthboundUtil { @@ -183,7 +193,11 @@ public class HwvtepSouthboundUtil { } } - public static boolean isEmpty(List list) { + public static boolean isEmpty(Collection list) { return list == null || list.isEmpty(); } + + public static boolean isEmptyMap(Map map) { + return map == null || map.isEmpty(); + } } diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/reconciliation/configuration/GlobalConfigOperationalChangeGetter.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/reconciliation/configuration/GlobalConfigOperationalChangeGetter.java index 599a6bff2..20180ca7c 100644 --- a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/reconciliation/configuration/GlobalConfigOperationalChangeGetter.java +++ b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/reconciliation/configuration/GlobalConfigOperationalChangeGetter.java @@ -38,7 +38,7 @@ public class GlobalConfigOperationalChangeGetter { HwvtepGlobalAugmentationBuilder oldAugmentation = getAugmentationFromNode(opNode); //fire removal of local ucast macs so that logical switches will be deleted - fillLocalMcacsToBeRemoved(oldAugmentation, configNode, opNode); + fillLocalMacsToBeRemoved(oldAugmentation, configNode, opNode); newNodeBuilder.addAugmentation(HwvtepGlobalAugmentation.class, newAugmentation.build()); oldNodeBuilder.addAugmentation(HwvtepGlobalAugmentation.class, oldAugmentation.build()); @@ -46,8 +46,7 @@ public class GlobalConfigOperationalChangeGetter { return new DataTreeModificationImpl(nodeId, newNodeBuilder.build(), oldNodeBuilder.build()); } - static void fillLocalMcacsToBeRemoved(HwvtepGlobalAugmentationBuilder oldAugmentation, Node configNode, - Node opNode) { + static void fillLocalMacsToBeRemoved(HwvtepGlobalAugmentationBuilder oldAugmentation, Node configNode, Node opNode) { Set logicalSwitchNamesToBeRemoved = getLogicalSwitchesToBeRemoved(configNode, opNode); List localUcastMacsToBeRemoved = getLocalUcastMacsToBeRemoved(opNode, logicalSwitchNamesToBeRemoved); @@ -110,9 +109,12 @@ public class GlobalConfigOperationalChangeGetter { Set opSwitchNames = new HashSet<>(); Set cfgSwitchNames = new HashSet<>(); List cfgLogicalSwitches = Lists.newArrayList(); + List opLogicalSwitches = Lists.newArrayList(); - List opLogicalSwitches = opNode.getAugmentation(HwvtepGlobalAugmentation.class).getLogicalSwitches(); - if (configNode != null) { + if (opNode != null && opNode.getAugmentation(HwvtepGlobalAugmentation.class) != null) { + opLogicalSwitches = opNode.getAugmentation(HwvtepGlobalAugmentation.class).getLogicalSwitches(); + } + if (configNode != null && configNode.getAugmentation(HwvtepGlobalAugmentation.class) != null) { cfgLogicalSwitches = configNode.getAugmentation(HwvtepGlobalAugmentation.class).getLogicalSwitches(); } if (opLogicalSwitches != null) { diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/AbstractTransactCommand.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/AbstractTransactCommand.java index c62dc862f..349cf3db2 100644 --- a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/AbstractTransactCommand.java +++ b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/AbstractTransactCommand.java @@ -8,20 +8,38 @@ package org.opendaylight.ovsdb.hwvtepsouthbound.transact; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; import java.util.Map; +import java.util.Objects; +import java.util.Set; import com.google.common.collect.Lists; +import org.opendaylight.controller.md.sal.binding.api.DataObjectModification; import org.opendaylight.controller.md.sal.binding.api.DataTreeModification; import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepDeviceInfo; +import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundUtil; import org.opendaylight.ovsdb.lib.notation.UUID; 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.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint; import org.opendaylight.yangtools.yang.binding.Identifiable; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +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.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.Augmentation; +import org.opendaylight.yangtools.yang.binding.Identifiable; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -public abstract class AbstractTransactCommand implements TransactCommand { +public abstract class AbstractTransactCommand> implements TransactCommand { private HwvtepOperationalState operationalState; private Collection> changes; @@ -43,8 +61,7 @@ public abstract class AbstractTransactCommand implements return changes; } - void updateCurrentTxDeleteData(InstanceIdentifier key, T data) { - Class cls = data.getClass(); + void updateCurrentTxDeleteData(Class cls, InstanceIdentifier key, T data) { operationalState.updateCurrentTxDeleteData(cls, key); operationalState.getDeviceInfo().clearConfigData(cls, key); } @@ -67,17 +84,20 @@ public abstract class AbstractTransactCommand implements //we can skip the config termination point dependency as we can create them in device as part of this tx confingDependencies.remove(TerminationPoint.class); + Type type = getClass().getGenericSuperclass(); + Type classType = ((ParameterizedType)type).getActualTypeArguments()[0]; + //If this key itself is in transit wait for the response of this key itself - if (deviceInfo.isKeyInTransit(data.getClass(), key)) { - inTransitDependencies.put(data.getClass(), Lists.newArrayList(key)); + if (deviceInfo.isKeyInTransit((Class) classType, key)) { + inTransitDependencies.put((Class) classType, Lists.newArrayList(key)); } - if (confingDependencies.isEmpty() && inTransitDependencies.isEmpty()) { + if (HwvtepSouthboundUtil.isEmptyMap(confingDependencies) && HwvtepSouthboundUtil.isEmptyMap(inTransitDependencies)) { doDeviceTransaction(transaction, nodeIid, data, key, extraData); //TODO put proper uuid - updateCurrentTxData(data.getClass(), key, new UUID("uuid"), data); + updateCurrentTxData((Class) classType, key, new UUID("uuid"), data); } - if (!confingDependencies.isEmpty()) { + if (!HwvtepSouthboundUtil.isEmptyMap(confingDependencies)) { DependentJob configWaitingJob = new DependentJob.ConfigWaitingJob( key, data, confingDependencies) { @@ -90,7 +110,7 @@ public abstract class AbstractTransactCommand implements }; deviceInfo.addJobToQueue(configWaitingJob); } - if (inTransitDependencies.size() > 0) { + if (!HwvtepSouthboundUtil.isEmptyMap(inTransitDependencies)) { DependentJob opWaitingJob = new DependentJob.OpWaitingJob( key, data, inTransitDependencies) { @@ -115,4 +135,158 @@ public abstract class AbstractTransactCommand implements InstanceIdentifier key, Object... extraData) { //tobe removed as part of refactoring patch } + + protected Aug getAugmentation(Node node) { + if (node == null) { + return null; + } + ParameterizedType parameterizedType = (ParameterizedType) getClass().getGenericSuperclass(); + Class> augType = (Class>) parameterizedType.getActualTypeArguments()[1]; + Augmentation augmentation = node.getAugmentation(augType); + return (Aug)augmentation; + } + + protected List getData(Aug augmentation) { + return Collections.EMPTY_LIST; + } + + protected List getData(Node node) { + Aug augmentation = getAugmentation(node); + if (augmentation != null) { + List data = getData(augmentation); + if (data != null) { + return Lists.newArrayList(data); + } + } + return Collections.EMPTY_LIST; + } + + protected Map, List> extractRemoved( + Collection> changes, Class class1) { + Map, List> result + = new HashMap, List>(); + List removed = Collections.EMPTY_LIST; + if (changes != null && !changes.isEmpty()) { + for (DataTreeModification change : changes) { + final InstanceIdentifier key = change.getRootPath().getRootIdentifier(); + removed = getRemoved(change); + removed.addAll(getCascadeDeleteData(change)); + result.put(key, removed); + } + } + return result; + } + + protected Map, List> extractUpdated( + Collection> changes, Class class1) { + Map, List> result + = new HashMap, List>(); + if (changes != null && !changes.isEmpty()) { + for (DataTreeModification change : changes) { + InstanceIdentifier key = change.getRootPath().getRootIdentifier(); + result.put(key, getUpdated(change)); + } + } + return result; + } + + List getCascadeDeleteData(DataTreeModification change) { + if (!cascadeDelete()) { + return Collections.EMPTY_LIST; + } + DataObjectModification mod = change.getRootNode(); + Node updatedNode = TransactUtils.getUpdated(mod); + List updatedData = getData(updatedNode); + Set deleted = getOperationalState().getDeletedKeysInCurrentTx(LogicalSwitches.class); + UnMetDependencyGetter dependencyGetter = getDependencyGetter(); + if (!HwvtepSouthboundUtil.isEmpty(deleted) && !HwvtepSouthboundUtil.isEmpty(updatedData) && dependencyGetter != null) { + List removed = new ArrayList(); + for (T ele : updatedData) { + if (deleted.containsAll(dependencyGetter.getLogicalSwitchDependencies(ele))) { + removed.add(ele); + } + } + return removed; + } + return Collections.EMPTY_LIST; + } + + List getRemoved(DataTreeModification change) { + DataObjectModification mod = change.getRootNode(); + + Node removed = TransactUtils.getRemoved(mod); + Node updated = TransactUtils.getUpdated(mod); + Node before = mod.getDataBefore(); + return diffOf(removed, before, updated, true); + } + + List getUpdated(DataTreeModification change) { + DataObjectModification mod = change.getRootNode(); + Node created = TransactUtils.getCreated(mod); + Node updated = TransactUtils.getUpdated(mod); + Node before = mod.getDataBefore(); + return diffOf(created, updated, before, false); + } + + List diffOf(Node include, Node a, Node b, boolean compareKeyOnly) { + List data1 = getData(include); + List data2 = diffOf(a, b, compareKeyOnly); + if (HwvtepSouthboundUtil.isEmpty(data1) && HwvtepSouthboundUtil.isEmpty(data2)) { + return Collections.EMPTY_LIST; + } + List result = Lists.newArrayList(data1); + result.addAll(data2); + return result; + } + + List diffOf(Node a, Node b, boolean compareKeyOnly) { + List result = new ArrayList(); + + List list1 = getData(a); + List list2 = getData(b); + + if (HwvtepSouthboundUtil.isEmpty(list1)) { + return Collections.EMPTY_LIST; + } + if (HwvtepSouthboundUtil.isEmpty(list2)) { + return HwvtepSouthboundUtil.isEmpty(list1) ? Collections.EMPTY_LIST : list1; + } + + Iterator it1 = list1.iterator(); + + while(it1.hasNext()) { + T ele = it1.next(); + Iterator it2 = list2.iterator(); + boolean found = false; + while (it2.hasNext()) { + T other = it2.next(); + found = compareKeyOnly ? Objects.equals(ele.getKey(), other.getKey()) : areEqual(ele, other); + if ( found ) { + it2.remove(); + break; + } + } + if (!found) { + result.add(ele); + } + } + return result; + } + + protected boolean areEqual(T a , T b) { + return a.getKey().equals(b.getKey()); + } + + protected UnMetDependencyGetter getDependencyGetter() { + return null; + } + + /** + * Tells if this object needs to be deleted if its dependent object gets deleted + * Ex : LocalUcastMac and LocalMacstMac + * @return true if this object needs to be deleted if its dependent object gets deleted + */ + protected boolean cascadeDelete() { + return false; + } } diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/DependencyQueue.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/DependencyQueue.java index 0b1b2eff7..c6892649d 100644 --- a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/DependencyQueue.java +++ b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/DependencyQueue.java @@ -131,4 +131,8 @@ public class DependencyQueue { public static void close() { executorService.shutdown(); } + + public void submit(Runnable runnable) { + executorService.submit(runnable); + } } \ No newline at end of file diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/LogicalSwitchRemoveCommand.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/LogicalSwitchRemoveCommand.java index 6c84cc794..0dadf6792 100644 --- a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/LogicalSwitchRemoveCommand.java +++ b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/LogicalSwitchRemoveCommand.java @@ -10,15 +10,14 @@ package org.opendaylight.ovsdb.hwvtepsouthbound.transact; import static org.opendaylight.ovsdb.lib.operations.Operations.op; -import java.util.ArrayList; import java.util.Collection; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.Objects; -import org.opendaylight.controller.md.sal.binding.api.DataObjectModification; import org.opendaylight.controller.md.sal.binding.api.DataTreeModification; +import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundUtil; import org.opendaylight.ovsdb.lib.notation.UUID; import org.opendaylight.ovsdb.lib.operations.TransactionBuilder; import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils; @@ -26,13 +25,14 @@ import org.opendaylight.ovsdb.schema.hardwarevtep.LogicalSwitch; 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.hwvtep.global.attributes.LogicalSwitches; 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.Identifiable; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.base.Optional; -public class LogicalSwitchRemoveCommand extends AbstractTransactCommand { +public class LogicalSwitchRemoveCommand extends AbstractTransactCommand { private static final Logger LOG = LoggerFactory.getLogger(LogicalSwitchRemoveCommand.class); public LogicalSwitchRemoveCommand(HwvtepOperationalState state, @@ -44,17 +44,32 @@ public class LogicalSwitchRemoveCommand extends AbstractTransactCommand { public void execute(TransactionBuilder transaction) { Map, List> removeds = extractRemoved(getChanges(),LogicalSwitches.class); - if (!removeds.isEmpty()) { - for (Entry, List> created: - removeds.entrySet()) { - if (created.getValue() != null) { + if (removeds != null) { + for (Entry, List> created: removeds.entrySet()) { + if (!HwvtepSouthboundUtil.isEmpty(created.getValue())) { for (LogicalSwitches lswitch : created.getValue()) { InstanceIdentifier lsKey = created.getKey().augmentation( HwvtepGlobalAugmentation.class).child(LogicalSwitches.class, lswitch.getKey()); - updateCurrentTxDeleteData(lsKey, lswitch); + updateCurrentTxDeleteData(LogicalSwitches.class, lsKey, lswitch); } + getOperationalState().getDeviceInfo().scheduleTransaction(new TransactCommand() { + @Override + public void execute(TransactionBuilder transactionBuilder) { + LOG.debug("Running delete logical switch in seperate tx {}", created.getKey()); + removeLogicalSwitch(transactionBuilder, created.getKey(), created.getValue()); + } + + @Override + public void onConfigUpdate(TransactionBuilder transaction, InstanceIdentifier nodeIid, + Identifiable data, InstanceIdentifier key, Object... extraData) { + } + + @Override + public void doDeviceTransaction(TransactionBuilder transaction, InstanceIdentifier nodeIid, + Identifiable data, InstanceIdentifier key, Object... extraData) { + } + }); } - removeLogicalSwitch(transaction, created.getKey(), created.getValue()); } } } @@ -80,68 +95,13 @@ public class LogicalSwitchRemoveCommand extends AbstractTransactCommand { } } - private Map, List> extractRemoved( - Collection> changes, Class class1) { - Map, List> result - = new HashMap, List>(); - if (changes != null && !changes.isEmpty()) { - for (DataTreeModification change : changes) { - final InstanceIdentifier key = change.getRootPath().getRootIdentifier(); - final DataObjectModification mod = change.getRootNode(); - //If the node which logical switches belong to is removed, all logical switches - //should be removed too. - Node removed = TransactUtils.getRemoved(mod); - if (removed != null) { - List lswitchListRemoved = null; - if (removed.getAugmentation(HwvtepGlobalAugmentation.class) != null) { - lswitchListRemoved = removed.getAugmentation(HwvtepGlobalAugmentation.class).getLogicalSwitches(); - } - if (lswitchListRemoved != null) { - result.put(key, lswitchListRemoved); - } - } - //If the node which logical switches belong to is updated, and logical switches may - //be created or updated or deleted, we need to get deleted ones. - Node updated = TransactUtils.getUpdated(mod); - Node before = mod.getDataBefore(); - if (updated != null && before != null) { - List lswitchListUpdated = null; - List lswitchListBefore = null; - if (updated.getAugmentation(HwvtepGlobalAugmentation.class) != null) { - lswitchListUpdated = updated.getAugmentation(HwvtepGlobalAugmentation.class).getLogicalSwitches(); - } - if (before.getAugmentation(HwvtepGlobalAugmentation.class) != null) { - lswitchListBefore = before.getAugmentation(HwvtepGlobalAugmentation.class).getLogicalSwitches(); - } - if (lswitchListBefore != null) { - List lswitchListRemoved = new ArrayList(); - if (lswitchListUpdated != null) { - lswitchListBefore = new ArrayList<>(lswitchListBefore); - lswitchListBefore.removeAll(lswitchListUpdated);//operate on copy as it has side effect on LogicalSwitchUpdateCommand - } - //then exclude updated ones - if (lswitchListUpdated != null) { - for (LogicalSwitches lswitchBefore : lswitchListBefore) { - int i = 0; - for (; i < lswitchListUpdated.size(); i++) { - if (lswitchBefore.getHwvtepNodeName().equals(lswitchListUpdated.get(i).getHwvtepNodeName())) { - break; - } - } - if (i == lswitchListUpdated.size()) { - lswitchListRemoved.add(lswitchBefore); - } - } - } else { - lswitchListRemoved.addAll(lswitchListBefore); - } - if (!lswitchListRemoved.isEmpty()) { - result.put(key, lswitchListRemoved); - } - } - } - } - } - return result; + @Override + protected List getData(HwvtepGlobalAugmentation augmentation) { + return augmentation.getLogicalSwitches(); + } + + @Override + protected boolean areEqual(LogicalSwitches a , LogicalSwitches b) { + return a.getKey().equals(b.getKey()) && Objects.equals(a.getTunnelKey(), b.getTunnelKey()); } } diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/LogicalSwitchUpdateCommand.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/LogicalSwitchUpdateCommand.java index a0068d40e..693edb2c1 100644 --- a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/LogicalSwitchUpdateCommand.java +++ b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/LogicalSwitchUpdateCommand.java @@ -11,16 +11,14 @@ 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.HashSet; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.Objects; import java.util.Set; -import org.opendaylight.controller.md.sal.binding.api.DataObjectModification; import org.opendaylight.controller.md.sal.binding.api.DataTreeModification; -import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundUtil; import org.opendaylight.ovsdb.lib.notation.UUID; import org.opendaylight.ovsdb.lib.operations.TransactionBuilder; import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils; @@ -34,7 +32,7 @@ import org.slf4j.LoggerFactory; import com.google.common.base.Optional; -public class LogicalSwitchUpdateCommand extends AbstractTransactCommand { +public class LogicalSwitchUpdateCommand extends AbstractTransactCommand { private static final Logger LOG = LoggerFactory.getLogger(LogicalSwitchUpdateCommand.class); public LogicalSwitchUpdateCommand(HwvtepOperationalState state, @@ -44,14 +42,6 @@ public class LogicalSwitchUpdateCommand extends AbstractTransactCommand { @Override public void execute(TransactionBuilder transaction) { - Map, List> createds = - extractCreated(getChanges(),LogicalSwitches.class); - if (!createds.isEmpty()) { - for (Entry, List> created: - createds.entrySet()) { - updateLogicalSwitch(transaction, created.getKey(), created.getValue()); - } - } Map, List> updateds = extractUpdated(getChanges(),LogicalSwitches.class); if (!updateds.isEmpty()) { @@ -78,6 +68,8 @@ public class LogicalSwitchUpdateCommand extends AbstractTransactCommand { LOG.trace("execute: creating LogicalSwitch entry: {}", logicalSwitch); transaction.add(op.insert(logicalSwitch).withId(TransactUtils.getLogicalSwitchId(lswitch))); transaction.add(op.comment("Logical Switch: Creating " + lswitch.getHwvtepNodeName().getValue())); + UUID lsUuid = new UUID(TransactUtils.getLogicalSwitchId(lswitch)); + updateCurrentTxData(LogicalSwitches.class, lsKey, lsUuid, lswitch); } else { LogicalSwitches updatedLSwitch = operationalSwitchOptional.get(); String existingLogicalSwitchName = updatedLSwitch.getHwvtepNodeName().getValue(); @@ -90,8 +82,6 @@ public class LogicalSwitchUpdateCommand extends AbstractTransactCommand { .build()); transaction.add(op.comment("Logical Switch: Updating " + existingLogicalSwitchName)); } - UUID lsUuid = new UUID(TransactUtils.getLogicalSwitchId(lswitch)); - updateCurrentTxData(LogicalSwitches.class, lsKey, lsUuid, lswitch); } } @@ -118,57 +108,13 @@ public class LogicalSwitchUpdateCommand extends AbstractTransactCommand { } } - private Map, List> extractCreated( - Collection> changes, Class class1) { - Map, List> result - = new HashMap, List>(); - if (changes != null && !changes.isEmpty()) { - for (DataTreeModification change : changes) { - final InstanceIdentifier key = change.getRootPath().getRootIdentifier(); - final DataObjectModification mod = change.getRootNode(); - Node created = TransactUtils.getCreated(mod); - if (created != null) { - List lswitchListUpdated = null; - if (created.getAugmentation(HwvtepGlobalAugmentation.class) != null) { - lswitchListUpdated = created.getAugmentation(HwvtepGlobalAugmentation.class).getLogicalSwitches(); - } - if (lswitchListUpdated != null) { - result.put(key, lswitchListUpdated); - } - } - } - } - return result; + @Override + protected List getData(HwvtepGlobalAugmentation augmentation) { + return augmentation.getLogicalSwitches(); } - private Map, List> extractUpdated( - Collection> changes, Class class1) { - Map, List> result - = new HashMap, List>(); - if (changes != null && !changes.isEmpty()) { - for (DataTreeModification change : changes) { - final InstanceIdentifier key = change.getRootPath().getRootIdentifier(); - final DataObjectModification mod = change.getRootNode(); - Node updated = TransactUtils.getUpdated(mod); - Node before = mod.getDataBefore(); - if (updated != null && before != null) { - List lswitchListUpdated = null; - List lswitchListBefore = null; - if (updated.getAugmentation(HwvtepGlobalAugmentation.class) != null) { - lswitchListUpdated = updated.getAugmentation(HwvtepGlobalAugmentation.class).getLogicalSwitches(); - } - if (before.getAugmentation(HwvtepGlobalAugmentation.class) != null) { - lswitchListBefore = before.getAugmentation(HwvtepGlobalAugmentation.class).getLogicalSwitches(); - } - if (lswitchListUpdated != null) { - if (lswitchListBefore != null) { - lswitchListUpdated.removeAll(lswitchListBefore); - } - result.put(key, lswitchListUpdated); - } - } - } - } - return result; + @Override + protected boolean areEqual(LogicalSwitches a , LogicalSwitches b) { + return a.getKey().equals(b.getKey()) && Objects.equals(a.getTunnelKey(), b.getTunnelKey()); } } diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/McastMacsLocalRemoveCommand.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/McastMacsLocalRemoveCommand.java index e67b9d38f..1d6783dc0 100644 --- a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/McastMacsLocalRemoveCommand.java +++ b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/McastMacsLocalRemoveCommand.java @@ -10,16 +10,14 @@ package org.opendaylight.ovsdb.hwvtepsouthbound.transact; import static org.opendaylight.ovsdb.lib.operations.Operations.op; -import java.util.ArrayList; import java.util.Collection; -import java.util.HashMap; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Map.Entry; -import org.opendaylight.controller.md.sal.binding.api.DataObjectModification; +import com.google.common.collect.Lists; import org.opendaylight.controller.md.sal.binding.api.DataTreeModification; -import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundConstants; import org.opendaylight.ovsdb.lib.notation.UUID; import org.opendaylight.ovsdb.lib.operations.TransactionBuilder; import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils; @@ -33,7 +31,7 @@ import org.slf4j.LoggerFactory; import com.google.common.base.Optional; -public class McastMacsLocalRemoveCommand extends AbstractTransactCommand { +public class McastMacsLocalRemoveCommand extends AbstractTransactCommand { private static final Logger LOG = LoggerFactory.getLogger(McastMacsLocalRemoveCommand.class); public McastMacsLocalRemoveCommand(HwvtepOperationalState state, @@ -76,68 +74,31 @@ public class McastMacsLocalRemoveCommand extends AbstractTransactCommand { } } - private Map, List> extractRemoved( - Collection> changes, Class class1) { - Map, List> result - = new HashMap, List>(); - if (changes != null && !changes.isEmpty()) { - for (DataTreeModification change : changes) { - final InstanceIdentifier key = change.getRootPath().getRootIdentifier(); - final DataObjectModification mod = change.getRootNode(); - //If the node which localMcastMacs belong to is removed, all localMcastMacs should be removed too. - Node removed = TransactUtils.getRemoved(mod); - if (removed != null) { - List macListRemoved = null; - if (removed.getAugmentation(HwvtepGlobalAugmentation.class) != null) { - macListRemoved = removed.getAugmentation(HwvtepGlobalAugmentation.class).getLocalMcastMacs(); - } - if (macListRemoved != null) { - result.put(key, macListRemoved); - } - } - //If the node which localMcastMacs belong to is updated, and localMcastMacs may - //be created or updated or deleted, we need to get deleted ones. - Node updated = TransactUtils.getUpdated(mod); - Node before = mod.getDataBefore(); - if (updated != null && before != null) { - List macListUpdated = null; - List macListBefore = null; - HwvtepGlobalAugmentation hgUpdated = updated.getAugmentation(HwvtepGlobalAugmentation.class); - if (hgUpdated != null) { - macListUpdated = hgUpdated.getLocalMcastMacs(); - } - HwvtepGlobalAugmentation hgBefore = before.getAugmentation(HwvtepGlobalAugmentation.class); - if (hgBefore != null) { - macListBefore = hgBefore.getLocalMcastMacs(); - } - if (macListBefore != null) { - List macListRemoved = new ArrayList(); - if (macListUpdated != null) { - macListBefore.removeAll(macListUpdated); - } - //then exclude updated localMcastMacs - if (macListUpdated != null) { - for (LocalMcastMacs macBefore : macListBefore) { - int i = 0; - for (; i < macListUpdated.size(); i++) { - if (macBefore.getKey().equals(macListUpdated.get(i).getKey())) { - break; - } - } - if (i == macListUpdated.size()) { - macListRemoved.add(macBefore); - } - } - } else { - macListRemoved.addAll(macListBefore); - } - if (!macListRemoved.isEmpty()) { - result.put(key, macListRemoved); - } - } - } - } + @Override + protected List getData(HwvtepGlobalAugmentation augmentation) { + return augmentation.getLocalMcastMacs(); + } + + @Override + protected boolean cascadeDelete() { + return true; + } + + @Override + protected UnMetDependencyGetter getDependencyGetter() { + return MAC_DEPENDENCY_GETTER; + } + + static UnMetDependencyGetter MAC_DEPENDENCY_GETTER = new MacDependencyGetter(); + + public static class MacDependencyGetter extends UnMetDependencyGetter { + public List> getLogicalSwitchDependencies(LocalMcastMacs data) { + return Lists.newArrayList(data.getLogicalSwitchRef().getValue()); + } + + @Override + public List> getTerminationPointDependencies(LocalMcastMacs data) { + return Collections.EMPTY_LIST; } - return result; } } diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/McastMacsLocalUpdateCommand.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/McastMacsLocalUpdateCommand.java index facfecfaa..bad6cdd75 100644 --- a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/McastMacsLocalUpdateCommand.java +++ b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/McastMacsLocalUpdateCommand.java @@ -11,12 +11,10 @@ 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.hwvtepsouthbound.HwvtepSouthboundConstants; import org.opendaylight.ovsdb.lib.notation.UUID; @@ -34,7 +32,7 @@ import org.slf4j.LoggerFactory; import com.google.common.base.Optional; -public class McastMacsLocalUpdateCommand extends AbstractTransactCommand { +public class McastMacsLocalUpdateCommand extends AbstractTransactCommand { private static final Logger LOG = LoggerFactory.getLogger(McastMacsLocalUpdateCommand.class); public McastMacsLocalUpdateCommand(HwvtepOperationalState state, @@ -44,14 +42,6 @@ public class McastMacsLocalUpdateCommand extends AbstractTransactCommand { @Override public void execute(TransactionBuilder transaction) { - Map, List> createds = - extractCreated(getChanges(),LocalMcastMacs.class); - if (!createds.isEmpty()) { - for (Entry, List> created: - createds.entrySet()) { - updateMcastMacsLocal(transaction, created.getKey(), created.getValue()); - } - } Map, List> updateds = extractUpdated(getChanges(),LocalMcastMacs.class); if (!updateds.isEmpty()) { @@ -137,60 +127,8 @@ public class McastMacsLocalUpdateCommand extends AbstractTransactCommand { } } - private Map, List> extractCreated( - Collection> changes, Class class1) { - Map, List> result - = new HashMap, List>(); - if (changes != null && !changes.isEmpty()) { - for (DataTreeModification change : changes) { - final InstanceIdentifier key = change.getRootPath().getRootIdentifier(); - final DataObjectModification mod = change.getRootNode(); - Node created = TransactUtils.getCreated(mod); - if (created != null) { - List macListUpdated = null; - HwvtepGlobalAugmentation hgAugmentation = created.getAugmentation(HwvtepGlobalAugmentation.class); - if (hgAugmentation != null) { - macListUpdated = hgAugmentation.getLocalMcastMacs(); - } - if (macListUpdated != null) { - result.put(key, macListUpdated); - } - } - } - } - return result; - } - - private Map, List> extractUpdated( - Collection> changes, Class class1) { - Map, List> result - = new HashMap, List>(); - if (changes != null && !changes.isEmpty()) { - for (DataTreeModification change : changes) { - final InstanceIdentifier key = change.getRootPath().getRootIdentifier(); - final DataObjectModification mod = change.getRootNode(); - Node updated = TransactUtils.getUpdated(mod); - Node before = mod.getDataBefore(); - if (updated != null && before != null) { - List macListUpdated = null; - List macListBefore = null; - HwvtepGlobalAugmentation hgUpdated = updated.getAugmentation(HwvtepGlobalAugmentation.class); - if (hgUpdated != null) { - macListUpdated = hgUpdated.getLocalMcastMacs(); - } - HwvtepGlobalAugmentation hgBefore = before.getAugmentation(HwvtepGlobalAugmentation.class); - if (hgBefore != null) { - macListBefore = hgBefore.getLocalMcastMacs(); - } - if (macListUpdated != null) { - if (macListBefore != null) { - macListUpdated.removeAll(macListBefore); - } - result.put(key, macListUpdated); - } - } - } - } - return result; + @Override + protected List getData(HwvtepGlobalAugmentation augmentation) { + return augmentation.getLocalMcastMacs(); } } \ No newline at end of file diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/McastMacsRemoteRemoveCommand.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/McastMacsRemoteRemoveCommand.java index 6ccb81b7a..95814f617 100644 --- a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/McastMacsRemoteRemoveCommand.java +++ b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/McastMacsRemoteRemoveCommand.java @@ -12,14 +12,13 @@ import static org.opendaylight.ovsdb.lib.operations.Operations.op; import java.util.ArrayList; import java.util.Collection; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.Objects; -import org.opendaylight.controller.md.sal.binding.api.DataObjectModification; import org.opendaylight.controller.md.sal.binding.api.DataTreeModification; -import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundConstants; +import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundUtil; import org.opendaylight.ovsdb.lib.notation.UUID; import org.opendaylight.ovsdb.lib.operations.TransactionBuilder; import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils; @@ -33,7 +32,7 @@ import org.slf4j.LoggerFactory; import com.google.common.base.Optional; -public class McastMacsRemoteRemoveCommand extends AbstractTransactCommand { +public class McastMacsRemoteRemoveCommand extends AbstractTransactCommand { private static final Logger LOG = LoggerFactory.getLogger(McastMacsRemoteRemoveCommand.class); public McastMacsRemoteRemoveCommand(HwvtepOperationalState state, @@ -51,6 +50,24 @@ public class McastMacsRemoteRemoveCommand extends AbstractTransactCommand { removeMcastMacRemote(transaction, removed.getKey(), removed.getValue()); } } + //Remove the ones whose locator set got emptied + Map, List> updated = + extractUpdated(getChanges(),RemoteMcastMacs.class); + if (!HwvtepSouthboundUtil.isEmptyMap(updated)) { + for (Entry, List> entry: + updated.entrySet()) { + List updatedList = entry.getValue(); + List tobeRemovedList = new ArrayList<>(); + if (!HwvtepSouthboundUtil.isEmpty(updatedList)) { + for (RemoteMcastMacs mac: updatedList) { + if (HwvtepSouthboundUtil.isEmpty(mac.getLocatorSet())) { + tobeRemovedList.add(mac); + } + } + removeMcastMacRemote(transaction, entry.getKey(), tobeRemovedList); + } + } + } } private void removeMcastMacRemote(TransactionBuilder transaction, @@ -75,73 +92,17 @@ public class McastMacsRemoteRemoveCommand extends AbstractTransactCommand { } InstanceIdentifier macIid = instanceIdentifier.augmentation(HwvtepGlobalAugmentation.class). child(RemoteMcastMacs.class, mac.getKey()); - updateCurrentTxDeleteData(macIid, mac); + updateCurrentTxDeleteData(RemoteMcastMacs.class, macIid, mac); } } - private Map, List> extractRemoved( - Collection> changes, Class class1) { - Map, List> result - = new HashMap, List>(); - if (changes != null && !changes.isEmpty()) { - for (DataTreeModification change : changes) { - final InstanceIdentifier key = change.getRootPath().getRootIdentifier(); - final DataObjectModification mod = change.getRootNode(); - //If the node which remoteMcastMacs belong to is removed, all remoteMcastMacs should be removed too. - Node removed = TransactUtils.getRemoved(mod); - if (removed != null) { - List macListRemoved = null; - if (removed.getAugmentation(HwvtepGlobalAugmentation.class) != null) { - macListRemoved = removed.getAugmentation(HwvtepGlobalAugmentation.class).getRemoteMcastMacs(); - } - if (macListRemoved != null) { - result.put(key, macListRemoved); - } - } - //If the node which remoteMcastMacs belong to is updated, and remoteMcastMacs may - //be created or updated or deleted, we need to get deleted ones. - Node updated = TransactUtils.getUpdated(mod); - Node before = mod.getDataBefore(); - if (updated != null && before != null) { - List macListUpdated = null; - List macListBefore = null; - HwvtepGlobalAugmentation hgUpdated = updated.getAugmentation(HwvtepGlobalAugmentation.class); - if (hgUpdated != null) { - macListUpdated = hgUpdated.getRemoteMcastMacs(); - } - HwvtepGlobalAugmentation hgBefore = before.getAugmentation(HwvtepGlobalAugmentation.class); - if (hgBefore != null) { - macListBefore = hgBefore.getRemoteMcastMacs(); - } - if (macListBefore != null) { - List macListRemoved = new ArrayList(); - if (macListUpdated != null) { - macListBefore = new ArrayList<>(macListBefore); - macListBefore.removeAll(macListUpdated); - } - //then exclude updated remoteMcastMacs - if (macListUpdated != null) { - for (RemoteMcastMacs macBefore : macListBefore) { - int i = 0; - for (; i < macListUpdated.size(); i++) { - if (macBefore.getKey().equals(macListUpdated.get(i).getKey())) { - break; - } - } - if (i == macListUpdated.size()) { - macListRemoved.add(macBefore); - } - } - } else { - macListRemoved.addAll(macListBefore); - } - if (!macListRemoved.isEmpty()) { - result.put(key, macListRemoved); - } - } - } - } - } - return result; + @Override + protected List getData(HwvtepGlobalAugmentation augmentation) { + return augmentation.getRemoteMcastMacs(); + } + + @Override + protected boolean areEqual(RemoteMcastMacs a, RemoteMcastMacs b) { + return a.getKey().equals(b.getKey()) && Objects.equals(a.getLocatorSet(), b.getLocatorSet()); } } diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/McastMacsRemoteUpdateCommand.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/McastMacsRemoteUpdateCommand.java index 30e40ad66..1bb7666ac 100644 --- a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/McastMacsRemoteUpdateCommand.java +++ b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/McastMacsRemoteUpdateCommand.java @@ -9,8 +9,17 @@ package org.opendaylight.ovsdb.hwvtepsouthbound.transact; import com.google.common.base.Optional; +import static org.opendaylight.ovsdb.lib.operations.Operations.op; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Objects; + import com.google.common.collect.Lists; -import org.opendaylight.controller.md.sal.binding.api.DataObjectModification; import org.opendaylight.controller.md.sal.binding.api.DataTreeModification; import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundConstants; import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundUtil; @@ -28,17 +37,9 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - import static org.opendaylight.ovsdb.lib.operations.Operations.op; -public class McastMacsRemoteUpdateCommand extends AbstractTransactCommand { +public class McastMacsRemoteUpdateCommand extends AbstractTransactCommand { private static final Logger LOG = LoggerFactory.getLogger(McastMacsRemoteUpdateCommand.class); private static final McastMacUnMetDependencyGetter MCAST_MAC_DATA_VALIDATOR = new McastMacUnMetDependencyGetter(); @@ -49,14 +50,6 @@ public class McastMacsRemoteUpdateCommand extends AbstractTransactCommand, List> createds = - extractCreated(getChanges(),RemoteMcastMacs.class); - if (!createds.isEmpty()) { - for (Entry, List> created: - createds.entrySet()) { - updateMcastMacRemote(transaction, created.getKey(), created.getValue()); - } - } Map, List> updateds = extractUpdated(getChanges(),RemoteMcastMacs.class); if (!updateds.isEmpty()) { @@ -70,7 +63,10 @@ public class McastMacsRemoteUpdateCommand extends AbstractTransactCommand instanceIdentifier, List macList) { for (RemoteMcastMacs mac: macList) { - onConfigUpdate(transaction, instanceIdentifier, mac, null); + //add / update only if locator set got changed + if (!HwvtepSouthboundUtil.isEmpty(mac.getLocatorSet())) { + onConfigUpdate(transaction, instanceIdentifier, mac, null); + } } } @@ -161,61 +157,14 @@ public class McastMacsRemoteUpdateCommand extends AbstractTransactCommand, List> extractCreated( - Collection> changes, Class class1) { - Map, List> result - = new HashMap, List>(); - if (changes != null && !changes.isEmpty()) { - for (DataTreeModification change : changes) { - final InstanceIdentifier key = change.getRootPath().getRootIdentifier(); - final DataObjectModification mod = change.getRootNode(); - Node created = TransactUtils.getCreated(mod); - if (created != null) { - List macListUpdated = null; - HwvtepGlobalAugmentation hgAugmentation = created.getAugmentation(HwvtepGlobalAugmentation.class); - if (hgAugmentation != null) { - macListUpdated = hgAugmentation.getRemoteMcastMacs(); - } - if (macListUpdated != null) { - result.put(key, macListUpdated); - } - } - } - } - return result; + @Override + protected List getData(HwvtepGlobalAugmentation augmentation) { + return augmentation.getRemoteMcastMacs(); } - private Map, List> extractUpdated( - Collection> changes, Class class1) { - Map, List> result - = new HashMap, List>(); - if (changes != null && !changes.isEmpty()) { - for (DataTreeModification change : changes) { - final InstanceIdentifier key = change.getRootPath().getRootIdentifier(); - final DataObjectModification mod = change.getRootNode(); - Node updated = TransactUtils.getUpdated(mod); - Node before = mod.getDataBefore(); - if (updated != null && before != null) { - List macListUpdated = null; - List macListBefore = null; - HwvtepGlobalAugmentation hgUpdated = updated.getAugmentation(HwvtepGlobalAugmentation.class); - if (hgUpdated != null) { - macListUpdated = hgUpdated.getRemoteMcastMacs(); - } - HwvtepGlobalAugmentation hgBefore = before.getAugmentation(HwvtepGlobalAugmentation.class); - if (hgBefore != null) { - macListBefore = hgBefore.getRemoteMcastMacs(); - } - if (macListUpdated != null) { - if (macListBefore != null) { - macListUpdated.removeAll(macListBefore); - } - result.put(key, macListUpdated); - } - } - } - } - return result; + @Override + protected boolean areEqual(RemoteMcastMacs a, RemoteMcastMacs b) { + return a.getKey().equals(b.getKey()) && Objects.equals(a.getLocatorSet(), b.getLocatorSet()); } static class McastMacUnMetDependencyGetter extends UnMetDependencyGetter { diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/PhysicalPortRemoveCommand.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/PhysicalPortRemoveCommand.java index 38cfae9ec..dbadaeb02 100644 --- a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/PhysicalPortRemoveCommand.java +++ b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/PhysicalPortRemoveCommand.java @@ -45,8 +45,9 @@ public class PhysicalPortRemoveCommand extends AbstractTransactCommand { @Override public void execute(TransactionBuilder transaction) { + //TODO reuse from base class instead of extractRemovedPorts Map, List> removeds = - extractRemoved(getChanges(),HwvtepPhysicalPortAugmentation.class); + extractRemovedPorts(getChanges(), HwvtepPhysicalPortAugmentation.class); if (!removeds.isEmpty()) { for (Entry, List> removed: removeds.entrySet()) { @@ -83,7 +84,7 @@ public class PhysicalPortRemoveCommand extends AbstractTransactCommand { } } - private Map, List> extractRemoved( + protected Map, List> extractRemovedPorts( Collection> changes, Class class1) { Map, List> result = new HashMap, List>(); diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/PhysicalPortUpdateCommand.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/PhysicalPortUpdateCommand.java index 3ecdd6007..68ab9df57 100644 --- a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/PhysicalPortUpdateCommand.java +++ b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/PhysicalPortUpdateCommand.java @@ -61,7 +61,7 @@ public class PhysicalPortUpdateCommand extends AbstractTransactCommand { } } Map, List> updateds = - extractUpdated(getChanges(),HwvtepPhysicalPortAugmentation.class); + extractUpdatedPorts(getChanges(), HwvtepPhysicalPortAugmentation.class); if (!updateds.isEmpty()) { for (Entry, List> updated: updateds.entrySet()) { @@ -217,7 +217,7 @@ public class PhysicalPortUpdateCommand extends AbstractTransactCommand { return result; } - private Map, List> extractUpdated( + private Map, List> extractUpdatedPorts( Collection> changes, Class class1) { Map, List> result = new HashMap, List>(); diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/PhysicalSwitchRemoveCommand.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/PhysicalSwitchRemoveCommand.java index e72813505..1f81f3b04 100644 --- a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/PhysicalSwitchRemoveCommand.java +++ b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/PhysicalSwitchRemoveCommand.java @@ -43,7 +43,7 @@ public class PhysicalSwitchRemoveCommand extends AbstractTransactCommand { @Override public void execute(TransactionBuilder transaction) { Map, PhysicalSwitchAugmentation> removeds = - extractRemoved(getChanges(),PhysicalSwitchAugmentation.class); + extractRemovedSwitches(getChanges(),PhysicalSwitchAugmentation.class); if (!removeds.isEmpty()) { for (Entry, PhysicalSwitchAugmentation> removed: removeds.entrySet()) { @@ -76,7 +76,7 @@ public class PhysicalSwitchRemoveCommand extends AbstractTransactCommand { } } - private Map, PhysicalSwitchAugmentation> extractRemoved( + private Map, PhysicalSwitchAugmentation> extractRemovedSwitches( Collection> changes, Class class1) { Map, PhysicalSwitchAugmentation> result = new HashMap, PhysicalSwitchAugmentation>(); diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/PhysicalSwitchUpdateCommand.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/PhysicalSwitchUpdateCommand.java index e7a33b0ba..8d776c275 100644 --- a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/PhysicalSwitchUpdateCommand.java +++ b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/PhysicalSwitchUpdateCommand.java @@ -67,7 +67,7 @@ public class PhysicalSwitchUpdateCommand extends AbstractTransactCommand { } } Map, PhysicalSwitchAugmentation> updated = - extractUpdated(getChanges(),PhysicalSwitchAugmentation.class); + extractUpdatedSwitches(getChanges(),PhysicalSwitchAugmentation.class); if (!updated.isEmpty()) { for (Entry, PhysicalSwitchAugmentation> physicalSwitchEntry: updated.entrySet()) { @@ -316,7 +316,7 @@ public class PhysicalSwitchUpdateCommand extends AbstractTransactCommand { return result; } - private Map, PhysicalSwitchAugmentation> extractUpdated( + private Map, PhysicalSwitchAugmentation> extractUpdatedSwitches( Collection> changes, Class class1) { Map, PhysicalSwitchAugmentation> result = new HashMap, PhysicalSwitchAugmentation>(); diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/TransactInvokerImpl.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/TransactInvokerImpl.java index 5ea0be4dc..ec2fb75f2 100644 --- a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/TransactInvokerImpl.java +++ b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/TransactInvokerImpl.java @@ -9,10 +9,16 @@ package org.opendaylight.ovsdb.hwvtepsouthbound.transact; import java.util.List; +import java.util.Map; +import com.google.common.base.Strings; import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepConnectionInstance; +import org.opendaylight.ovsdb.lib.operations.Delete; +import org.opendaylight.ovsdb.lib.operations.Insert; +import org.opendaylight.ovsdb.lib.operations.Operation; import org.opendaylight.ovsdb.lib.operations.OperationResult; import org.opendaylight.ovsdb.lib.operations.TransactionBuilder; +import org.opendaylight.ovsdb.lib.operations.Update; import org.opendaylight.ovsdb.lib.schema.DatabaseSchema; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -38,7 +44,21 @@ public class TransactInvokerImpl implements TransactInvoker { if (tb.getOperations().size() > 0) { try { List got = result.get(); - LOG.debug("OVSDB transaction result: {}", got); + LOG.debug("HWVTEP transaction result: {}", got); + boolean errorOccured = false; + if (got != null && got.size() > 0) { + for (OperationResult opResult : got) { + if (!Strings.isNullOrEmpty(opResult.getError())) { + LOG.error("HWVTEP transaction operation failed {} {}", + opResult.getError(), opResult.getDetails()); + errorOccured = true; + } + } + } + if (errorOccured) { + connectionInstance.getDeviceInfo().clearInTransitData(); + printError(tb); + } } catch (Exception e) { LOG.warn("Transact execution exception: ", e); } @@ -46,4 +66,35 @@ public class TransactInvokerImpl implements TransactInvoker { } } + void printError(TransactionBuilder tb) { + StringBuffer sb = new StringBuffer(); + for (Operation op : tb.getOperations()) { + if (op instanceof Insert) { + Insert insert = (Insert)op; + Map row = insert.getRow(); + sb.append("insert ["); + if (row != null) { + for (Object key : row.keySet()) { + sb.append(key + " : "+row.get(key)+" , "); + } + } + sb.append("] "); + } else if (op instanceof Delete) { + Delete delete = (Delete)op; + sb.append("delete from " ); + sb.append(delete.getTableSchema().getName()); + } else if (op instanceof Update) { + Update update = (Update)op; + sb.append("update [" ); + Map row = update.getRow(); + if (row != null) { + for (Object key : row.keySet()) { + sb.append(key + " : "+row.get(key)+" , "); + } + } + sb.append("]"); + } + } + LOG.error("Failed transaction {}", sb); + } } diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/TransactUtils.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/TransactUtils.java index 711a365ef..98400fd3d 100644 --- a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/TransactUtils.java +++ b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/TransactUtils.java @@ -17,6 +17,7 @@ import java.util.Map; import java.util.Set; import org.opendaylight.controller.md.sal.binding.api.DataObjectModification; +import org.opendaylight.controller.md.sal.binding.api.DataObjectModification.ModificationType; 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; @@ -29,8 +30,11 @@ 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.ovsdb.schema.hardwarevtep.PhysicalLocatorSet; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.EncapsulationTypeVxlanOverIpv4; 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.HwvtepPhysicalLocatorAugmentationBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical.locator.set.attributes.LocatorSet; 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.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node; @@ -147,20 +151,9 @@ public class TransactUtils { HwvtepPhysicalLocatorAugmentation locatorAugmentation = operationalLocatorOptional.get(); locatorUuid = new UUID(locatorAugmentation.getPhysicalLocatorUuid().getValue()); } else { - locatorUuid = hwvtepOperationalState.getPhysicalLocatorInFlight(iid); + locatorUuid = hwvtepOperationalState.getUUIDFromCurrentTx(TerminationPoint.class, iid); if (locatorUuid == null) { - //if no, get it from config DS and create id - Optional configLocatorOptional = - readNodeFromConfig(hwvtepOperationalState.getReadWriteTransaction(), iid); - if (configLocatorOptional.isPresent()) { - HwvtepPhysicalLocatorAugmentation locatorAugmentation = - configLocatorOptional.get().getAugmentation(HwvtepPhysicalLocatorAugmentation.class); - locatorUuid = TransactUtils.createPhysicalLocator(transaction, locatorAugmentation); - hwvtepOperationalState.setPhysicalLocatorInFlight(iid, locatorUuid); - } else { - LOG.warn("Create or update localMcastMac: No physical locator found in operational datastore!" - + "Its indentifier is {}", locator.getLocatorRef().getValue()); - } + locatorUuid = createPhysicalLocator(transaction, hwvtepOperationalState, iid); } } if (locatorUuid != null) { @@ -174,6 +167,27 @@ public class TransactUtils { return new UUID(locatorSetUuid); } + public static UUID createPhysicalLocator(TransactionBuilder transaction, HwvtepOperationalState operationalState, + InstanceIdentifier iid) { + Optional configLocatorOptional = TransactUtils.readNodeFromConfig( + operationalState.getReadWriteTransaction(), iid); + HwvtepPhysicalLocatorAugmentationBuilder builder = new HwvtepPhysicalLocatorAugmentationBuilder(); + HwvtepPhysicalLocatorAugmentation locatorAugmentation = null; + if (configLocatorOptional.isPresent()) { + locatorAugmentation = configLocatorOptional.get().getAugmentation(HwvtepPhysicalLocatorAugmentation.class); + } else { + builder.setEncapsulationType(EncapsulationTypeVxlanOverIpv4.class); + String tepKey = iid.firstKeyOf(TerminationPoint.class).getTpId().getValue(); + String ip = tepKey.substring(tepKey.indexOf(":")+1); + builder.setDstIp(new IpAddress(ip.toCharArray())); + locatorAugmentation = builder.build(); + } + UUID locatorUuid = TransactUtils.createPhysicalLocator(transaction, locatorAugmentation); + operationalState.updateCurrentTxData(TerminationPoint.class, iid, locatorUuid); + operationalState.getDeviceInfo().markKeyAsInTransit(TerminationPoint.class, iid); + return locatorUuid; + } + public static UUID createPhysicalLocator(TransactionBuilder transaction, HwvtepPhysicalLocatorAugmentation inputLocator) { LOG.debug("Creating a physical locator: {}", inputLocator.getDstIp()); PhysicalLocator physicalLocator = TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(), PhysicalLocator.class); diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/UcastMacsLocalRemoveCommand.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/UcastMacsLocalRemoveCommand.java index 9b1556169..1cec98b0c 100644 --- a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/UcastMacsLocalRemoveCommand.java +++ b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/UcastMacsLocalRemoveCommand.java @@ -10,14 +10,13 @@ package org.opendaylight.ovsdb.hwvtepsouthbound.transact; import static org.opendaylight.ovsdb.lib.operations.Operations.op; -import java.util.ArrayList; import java.util.Collection; -import java.util.HashMap; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Map.Entry; -import org.opendaylight.controller.md.sal.binding.api.DataObjectModification; +import com.google.common.collect.Lists; import org.opendaylight.controller.md.sal.binding.api.DataTreeModification; import org.opendaylight.ovsdb.lib.notation.UUID; import org.opendaylight.ovsdb.lib.operations.TransactionBuilder; @@ -32,7 +31,7 @@ import org.slf4j.LoggerFactory; import com.google.common.base.Optional; -public class UcastMacsLocalRemoveCommand extends AbstractTransactCommand { +public class UcastMacsLocalRemoveCommand extends AbstractTransactCommand { private static final Logger LOG = LoggerFactory.getLogger(UcastMacsLocalRemoveCommand.class); public UcastMacsLocalRemoveCommand(HwvtepOperationalState state, @@ -75,68 +74,32 @@ public class UcastMacsLocalRemoveCommand extends AbstractTransactCommand { } } - private Map, List> extractRemoved( - Collection> changes, Class class1) { - Map, List> result - = new HashMap, List>(); - if (changes != null && !changes.isEmpty()) { - for (DataTreeModification change : changes) { - final InstanceIdentifier key = change.getRootPath().getRootIdentifier(); - final DataObjectModification mod = change.getRootNode(); - //If the node which remoteUcastMacs belong to is removed, all remoteUcastMacs should be removed too. - Node removed = TransactUtils.getRemoved(mod); - if (removed != null) { - List macListRemoved = null; - if (removed.getAugmentation(HwvtepGlobalAugmentation.class) != null) { - macListRemoved = removed.getAugmentation(HwvtepGlobalAugmentation.class).getLocalUcastMacs(); - } - if (macListRemoved != null) { - result.put(key, macListRemoved); - } - } - //If the node which remoteUcastMacs belong to is updated, and remoteUcastMacs may - //be created or updated or deleted, we need to get deleted ones. - Node updated = TransactUtils.getUpdated(mod); - Node before = mod.getDataBefore(); - if (updated != null && before != null) { - List macListUpdated = null; - List 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 (macListBefore != null) { - List macListRemoved = new ArrayList(); - if (macListUpdated != null) { - macListBefore.removeAll(macListUpdated); - } - //then exclude updated remoteUcastMacs - if (macListUpdated != null) { - for (LocalUcastMacs macBefore : macListBefore) { - int i = 0; - for (; i < macListUpdated.size(); i++) { - if (macBefore.getKey().equals(macListUpdated.get(i).getKey())) { - break; - } - } - if (i == macListUpdated.size()) { - macListRemoved.add(macBefore); - } - } - } else { - macListRemoved.addAll(macListBefore); - } - if (!macListRemoved.isEmpty()) { - result.put(key, macListRemoved); - } - } - } - } + @Override + protected List getData(HwvtepGlobalAugmentation augmentation) { + return augmentation.getLocalUcastMacs(); + } + + @Override + protected boolean cascadeDelete() { + return true; + } + + @Override + protected UnMetDependencyGetter getDependencyGetter() { + return MAC_DEPENDENCY_GETTER; + } + + static UnMetDependencyGetter MAC_DEPENDENCY_GETTER = new MacDependencyGetter(); + + public static class MacDependencyGetter extends UnMetDependencyGetter { + @Override + public List> getLogicalSwitchDependencies(LocalUcastMacs data) { + return Lists.newArrayList(data.getLogicalSwitchRef().getValue()); + } + + @Override + public List> getTerminationPointDependencies(LocalUcastMacs data) { + return Collections.EMPTY_LIST; } - return result; } } \ No newline at end of file diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/UcastMacsLocalUpdateCommand.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/UcastMacsLocalUpdateCommand.java index f9a161e81..1f5b5cc06 100644 --- a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/UcastMacsLocalUpdateCommand.java +++ b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/UcastMacsLocalUpdateCommand.java @@ -11,12 +11,10 @@ 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; @@ -24,11 +22,9 @@ 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; @@ -37,7 +33,7 @@ import org.slf4j.LoggerFactory; import com.google.common.base.Optional; -public class UcastMacsLocalUpdateCommand extends AbstractTransactCommand { +public class UcastMacsLocalUpdateCommand extends AbstractTransactCommand { private static final Logger LOG = LoggerFactory.getLogger(UcastMacsLocalUpdateCommand.class); public UcastMacsLocalUpdateCommand(HwvtepOperationalState state, @@ -47,14 +43,6 @@ public class UcastMacsLocalUpdateCommand extends AbstractTransactCommand { @Override public void execute(TransactionBuilder transaction) { - Map, List> createds = - extractCreated(getChanges(),LocalUcastMacs.class); - if (!createds.isEmpty()) { - for (Entry, List> created: - createds.entrySet()) { - updateUcastMacsLocal(transaction, created.getKey(), created.getValue()); - } - } Map, List> updateds = extractUpdated(getChanges(),LocalUcastMacs.class); if (!updateds.isEmpty()) { @@ -161,60 +149,8 @@ public class UcastMacsLocalUpdateCommand extends AbstractTransactCommand { } } - private Map, List> extractCreated( - Collection> changes, Class class1) { - Map, List> result - = new HashMap, List>(); - if (changes != null && !changes.isEmpty()) { - for (DataTreeModification change : changes) { - final InstanceIdentifier key = change.getRootPath().getRootIdentifier(); - final DataObjectModification mod = change.getRootNode(); - Node created = TransactUtils.getCreated(mod); - if (created != null) { - List macListUpdated = null; - HwvtepGlobalAugmentation hgAugmentation = created.getAugmentation(HwvtepGlobalAugmentation.class); - if (hgAugmentation != null) { - macListUpdated = hgAugmentation.getLocalUcastMacs(); - } - if (macListUpdated != null) { - result.put(key, macListUpdated); - } - } - } - } - return result; + protected List getData(HwvtepGlobalAugmentation augmentation) { + return augmentation.getLocalUcastMacs(); } - private Map, List> extractUpdated( - Collection> changes, Class class1) { - Map, List> result - = new HashMap, List>(); - if (changes != null && !changes.isEmpty()) { - for (DataTreeModification change : changes) { - final InstanceIdentifier key = change.getRootPath().getRootIdentifier(); - final DataObjectModification mod = change.getRootNode(); - Node updated = TransactUtils.getUpdated(mod); - Node before = mod.getDataBefore(); - if (updated != null && before != null) { - List macListUpdated = null; - List 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; - } } diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/UcastMacsRemoteRemoveCommand.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/UcastMacsRemoteRemoveCommand.java index 16ca422a6..3883fed20 100644 --- a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/UcastMacsRemoteRemoveCommand.java +++ b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/UcastMacsRemoteRemoveCommand.java @@ -10,21 +10,17 @@ package org.opendaylight.ovsdb.hwvtepsouthbound.transact; import static org.opendaylight.ovsdb.lib.operations.Operations.op; -import java.util.ArrayList; 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.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation; -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.RemoteUcastMacs; 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; @@ -33,7 +29,7 @@ import org.slf4j.LoggerFactory; import com.google.common.base.Optional; -public class UcastMacsRemoteRemoveCommand extends AbstractTransactCommand { +public class UcastMacsRemoteRemoveCommand extends AbstractTransactCommand { private static final Logger LOG = LoggerFactory.getLogger(UcastMacsRemoteRemoveCommand.class); public UcastMacsRemoteRemoveCommand(HwvtepOperationalState state, @@ -75,72 +71,12 @@ public class UcastMacsRemoteRemoveCommand extends AbstractTransactCommand { } InstanceIdentifier macIid = instanceIdentifier.augmentation(HwvtepGlobalAugmentation.class). child(RemoteUcastMacs.class, mac.getKey()); - updateCurrentTxDeleteData(macIid, mac); + updateCurrentTxDeleteData(RemoteUcastMacs.class, macIid, mac); } } - private Map, List> extractRemoved( - Collection> changes, Class class1) { - Map, List> result - = new HashMap, List>(); - if (changes != null && !changes.isEmpty()) { - for (DataTreeModification change : changes) { - final InstanceIdentifier key = change.getRootPath().getRootIdentifier(); - final DataObjectModification mod = change.getRootNode(); - //If the node which remoteUcastMacs belong to is removed, all remoteUcastMacs should be removed too. - Node removed = TransactUtils.getRemoved(mod); - if (removed != null) { - List macListRemoved = null; - if (removed.getAugmentation(HwvtepGlobalAugmentation.class) != null) { - macListRemoved = removed.getAugmentation(HwvtepGlobalAugmentation.class).getRemoteUcastMacs(); - } - if (macListRemoved != null) { - result.put(key, macListRemoved); - } - } - //If the node which remoteUcastMacs belong to is updated, and remoteUcastMacs may - //be created or updated or deleted, we need to get deleted ones. - Node updated = TransactUtils.getUpdated(mod); - Node before = mod.getDataBefore(); - if (updated != null && before != null) { - List macListUpdated = null; - List 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 (macListBefore != null) { - List macListRemoved = new ArrayList(); - if (macListUpdated != null) { - macListBefore.removeAll(macListUpdated); - } - //then exclude updated remoteUcastMacs - if (macListUpdated != null) { - for (RemoteUcastMacs macBefore : macListBefore) { - int i = 0; - for (; i < macListUpdated.size(); i++) { - if (macBefore.getKey().equals(macListUpdated.get(i).getKey())) { - break; - } - } - if (i == macListUpdated.size()) { - macListRemoved.add(macBefore); - } - } - } else { - macListRemoved.addAll(macListBefore); - } - if (!macListRemoved.isEmpty()) { - result.put(key, macListRemoved); - } - } - } - } - } - return result; + protected List getData(HwvtepGlobalAugmentation augmentation) { + return augmentation.getRemoteUcastMacs(); } + } diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/UcastMacsRemoteUpdateCommand.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/UcastMacsRemoteUpdateCommand.java index 378fa2e9b..b4de21c84 100644 --- a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/UcastMacsRemoteUpdateCommand.java +++ b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transact/UcastMacsRemoteUpdateCommand.java @@ -10,15 +10,21 @@ package org.opendaylight.ovsdb.hwvtepsouthbound.transact; import com.google.common.base.Optional; import com.google.common.collect.Lists; -import org.opendaylight.controller.md.sal.binding.api.DataObjectModification; + +import static org.opendaylight.ovsdb.lib.operations.Operations.op; + 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.inet.types.rev130715.IpAddress; 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.EncapsulationTypeBase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.EncapsulationTypeVxlanOverIpv4; 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.HwvtepPhysicalLocatorAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalLocatorAugmentationBuilder; 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.RemoteUcastMacs; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node; @@ -36,7 +42,7 @@ import java.util.Map.Entry; import static org.opendaylight.ovsdb.lib.operations.Operations.op; -public class UcastMacsRemoteUpdateCommand extends AbstractTransactCommand { +public class UcastMacsRemoteUpdateCommand extends AbstractTransactCommand { private static final Logger LOG = LoggerFactory.getLogger(UcastMacsRemoteUpdateCommand.class); private static final UcastMacUnMetDependencyGetter UCAST_MAC_DATA_VALIDATOR = new UcastMacUnMetDependencyGetter(); @@ -47,14 +53,6 @@ public class UcastMacsRemoteUpdateCommand extends AbstractTransactCommand, List> createds = - extractCreated(getChanges(),RemoteUcastMacs.class); - if (!createds.isEmpty()) { - for (Entry, List> created: - createds.entrySet()) { - updateUcastMacsRemote(transaction, created.getKey(), created.getValue()); - } - } Map, List> updateds = extractUpdated(getChanges(),RemoteUcastMacs.class); if (!updateds.isEmpty()) { @@ -151,21 +149,11 @@ public class UcastMacsRemoteUpdateCommand extends AbstractTransactCommand configLocatorOptional = - TransactUtils.readNodeFromConfig(getOperationalState().getReadWriteTransaction(), iid); - if (configLocatorOptional.isPresent()) { - HwvtepPhysicalLocatorAugmentation locatorAugmentation = - configLocatorOptional.get().getAugmentation(HwvtepPhysicalLocatorAugmentation.class); - locatorUuid = TransactUtils.createPhysicalLocator(transaction, locatorAugmentation); - getOperationalState().setPhysicalLocatorInFlight(iid, locatorUuid); - } else { - LOG.warn("Create or update remoteUcastMac: No physical locator found in operational datastore!" - + "Its indentifier is {}", inputMac.getLocatorRef().getValue()); - } + locatorUuid = TransactUtils.createPhysicalLocator(transaction, getOperationalState(), + (InstanceIdentifier) inputMac.getLocatorRef().getValue()); + updateCurrentTxData(TerminationPoint.class, iid, locatorUuid, null); } } if (locatorUuid != null) { @@ -189,61 +177,8 @@ public class UcastMacsRemoteUpdateCommand extends AbstractTransactCommand, List> extractCreated( - Collection> changes, Class class1) { - Map, List> result - = new HashMap, List>(); - if (changes != null && !changes.isEmpty()) { - for (DataTreeModification change : changes) { - final InstanceIdentifier key = change.getRootPath().getRootIdentifier(); - final DataObjectModification mod = change.getRootNode(); - Node created = TransactUtils.getCreated(mod); - if (created != null) { - List 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, List> extractUpdated( - Collection> changes, Class class1) { - Map, List> result - = new HashMap, List>(); - if (changes != null && !changes.isEmpty()) { - for (DataTreeModification change : changes) { - final InstanceIdentifier key = change.getRootPath().getRootIdentifier(); - final DataObjectModification mod = change.getRootNode(); - Node updated = TransactUtils.getUpdated(mod); - Node before = mod.getDataBefore(); - if (updated != null && before != null) { - List macListUpdated = null; - List 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; + protected List getData(HwvtepGlobalAugmentation augmentation) { + return augmentation.getRemoteUcastMacs(); } static class UcastMacUnMetDependencyGetter extends UnMetDependencyGetter { diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/HwvtepPhysicalLocatorUpdateCommand.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/HwvtepPhysicalLocatorUpdateCommand.java index 13b25e37a..86d11f37d 100644 --- a/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/HwvtepPhysicalLocatorUpdateCommand.java +++ b/hwvtepsouthbound/hwvtepsouthbound-impl/src/main/java/org/opendaylight/ovsdb/hwvtepsouthbound/transactions/md/HwvtepPhysicalLocatorUpdateCommand.java @@ -78,9 +78,9 @@ public class HwvtepPhysicalLocatorUpdateCommand extends AbstractTransactionComma } else { transaction.put(LogicalDatastoreType.OPERATIONAL, tpPath, tpBuilder.build()); - getOvsdbConnectionInstance().getDeviceInfo().updateDeviceOpData( - TerminationPoint.class, tpPath, pLoc.getUuid(), pLoc); } + getOvsdbConnectionInstance().getDeviceInfo().updateDeviceOpData( + TerminationPoint.class, tpPath, pLoc.getUuid(), pLoc); } } } diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/test/java/org/opendaylight/ovsdb/hwvtepsouthbound/DataChangeListenerTestBase.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/test/java/org/opendaylight/ovsdb/hwvtepsouthbound/DataChangeListenerTestBase.java index 79ba56f70..08875c74a 100644 --- a/hwvtepsouthbound/hwvtepsouthbound-impl/src/test/java/org/opendaylight/ovsdb/hwvtepsouthbound/DataChangeListenerTestBase.java +++ b/hwvtepsouthbound/hwvtepsouthbound-impl/src/test/java/org/opendaylight/ovsdb/hwvtepsouthbound/DataChangeListenerTestBase.java @@ -25,10 +25,12 @@ import org.opendaylight.ovsdb.hwvtepsouthbound.transactions.md.TransactionInvoke import org.opendaylight.ovsdb.hwvtepsouthbound.transactions.md.TransactionInvokerImpl; import org.opendaylight.ovsdb.lib.OvsdbClient; import org.opendaylight.ovsdb.lib.OvsdbConnectionInfo; -import org.opendaylight.ovsdb.lib.operations.Comment; +import org.opendaylight.ovsdb.lib.operations.Delete; import org.opendaylight.ovsdb.lib.operations.Insert; import org.opendaylight.ovsdb.lib.operations.OperationResult; import org.opendaylight.ovsdb.lib.operations.Operations; +import org.opendaylight.ovsdb.lib.operations.Update; +import org.opendaylight.ovsdb.lib.operations.Where; import org.opendaylight.ovsdb.lib.schema.DatabaseSchema; import org.opendaylight.ovsdb.lib.schema.typed.TypedBaseTable; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri; @@ -180,12 +182,17 @@ public class DataChangeListenerTestBase extends AbstractDataBrokerTest { */ void resetOperations() { insertOpCapture = ArgumentCaptor.forClass(TypedBaseTable.class); + Update update = mock(Update.class); Insert insert = mock(Insert.class); + Delete delete = mock(Delete.class); + Where where = mock(Where.class); + when(delete.where(any())).thenReturn(where); when(insert.withId(any(String.class))).thenReturn(insert); Operations.op = PowerMockito.mock(Operations.class); - when(Operations.op.comment(any(String.class))).thenReturn(mock(Comment.class)); when(Operations.op.insert(insertOpCapture.capture())).thenReturn(insert); - + when(Operations.op.update(insertOpCapture.capture())).thenReturn(update); + when(update.where(any())).thenReturn(where); + when(Operations.op.delete(any())).thenReturn(delete); ListenableFuture> ft = mock(ListenableFuture.class); transactCaptor = ArgumentCaptor.forClass(List.class); when(ovsdbClient.transact(any(DatabaseSchema.class), transactCaptor.capture())).thenReturn(ft); @@ -206,7 +213,7 @@ public class DataChangeListenerTestBase extends AbstractDataBrokerTest { tx.submit(); } - void addData(LogicalDatastoreType logicalDatastoreType, Class dataObject, + Node addData(LogicalDatastoreType logicalDatastoreType, Class dataObject, String[]... data) { NodeBuilder nodeBuilder = prepareNode(nodeIid); HwvtepGlobalAugmentationBuilder builder = new HwvtepGlobalAugmentationBuilder(); @@ -223,7 +230,43 @@ public class DataChangeListenerTestBase extends AbstractDataBrokerTest { TestBuilders.addRemoteMcastMacs(nodeIid, builder, data); } nodeBuilder.addAugmentation(HwvtepGlobalAugmentation.class, builder.build()); - mergeNode(logicalDatastoreType, nodeIid, nodeBuilder); + return mergeNode(logicalDatastoreType, nodeIid, nodeBuilder); + } + + void deleteData(LogicalDatastoreType logicalDatastoreType, Class dataObject, + String[]... data) { + NodeBuilder nodeBuilder = prepareNode(nodeIid); + ReadWriteTransaction tx = dataBroker.newReadWriteTransaction(); + HwvtepGlobalAugmentationBuilder builder = new HwvtepGlobalAugmentationBuilder(); + if (LogicalSwitches.class == dataObject) { + List logicalSwitches = TestBuilders.addLogicalSwitches(builder, data); + + for (LogicalSwitches ls : logicalSwitches) { + InstanceIdentifier key = nodeIid.augmentation(HwvtepGlobalAugmentation.class). + child(LogicalSwitches.class, ls.getKey()); + tx.delete(logicalDatastoreType, key); + } + } + if (TerminationPoint.class == dataObject) { + TestBuilders.addGlobalTerminationPoints(nodeBuilder, nodeIid, data); + } + if (RemoteUcastMacs.class == dataObject) { + List macs = TestBuilders.addRemoteUcastMacs(nodeIid, builder, data); + for (RemoteUcastMacs mac : macs) { + InstanceIdentifier key = nodeIid.augmentation(HwvtepGlobalAugmentation.class). + child(RemoteUcastMacs.class, mac.getKey()); + tx.delete(logicalDatastoreType, key); + } + } + if (RemoteMcastMacs.class == dataObject) { + List macs = TestBuilders.addRemoteMcastMacs(nodeIid, builder, data); + for (RemoteMcastMacs mac : macs) { + InstanceIdentifier key = nodeIid.augmentation(HwvtepGlobalAugmentation.class). + child(RemoteMcastMacs.class, mac.getKey()); + tx.delete(logicalDatastoreType, key); + } + } + tx.submit(); } NodeBuilder prepareNode(InstanceIdentifier iid) { diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/test/java/org/opendaylight/ovsdb/hwvtepsouthbound/HwvtepDataChangeListenerTest.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/test/java/org/opendaylight/ovsdb/hwvtepsouthbound/HwvtepDataChangeListenerTest.java index 1b787c785..f4cd1017e 100644 --- a/hwvtepsouthbound/hwvtepsouthbound-impl/src/test/java/org/opendaylight/ovsdb/hwvtepsouthbound/HwvtepDataChangeListenerTest.java +++ b/hwvtepsouthbound/hwvtepsouthbound-impl/src/test/java/org/opendaylight/ovsdb/hwvtepsouthbound/HwvtepDataChangeListenerTest.java @@ -9,10 +9,14 @@ package org.opendaylight.ovsdb.hwvtepsouthbound; import com.google.common.collect.Lists; +import com.google.common.util.concurrent.MoreExecutors; +import org.apache.commons.lang3.reflect.FieldUtils; +import org.junit.After; +import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Matchers; -import org.opendaylight.ovsdb.lib.notation.UUID; +import org.opendaylight.ovsdb.hwvtepsouthbound.transact.DependencyQueue; import org.opendaylight.ovsdb.lib.operations.Operations; import org.opendaylight.ovsdb.lib.schema.DatabaseSchema; import org.opendaylight.ovsdb.lib.schema.typed.TypedBaseTable; @@ -22,6 +26,7 @@ import org.opendaylight.ovsdb.schema.hardwarevtep.UcastMacsRemote; 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.RemoteMcastMacs; 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; 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.DataObject; import org.powermock.core.classloader.annotations.PrepareForTest; @@ -29,6 +34,8 @@ import org.powermock.modules.junit4.PowerMockRunner; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; import java.util.Iterator; import java.util.List; @@ -73,6 +80,45 @@ public class HwvtepDataChangeListenerTest extends DataChangeListenerTestBase { {"FF:FF:FF:FF:FF:FF", "ls1", "192.168.122.10", "192.168.122.30"} }; + String[][] mcastMac2 = new String[][]{ + {"FF:FF:FF:FF:FF:FF", "ls0", "192.168.122.20", "192.168.122.10"}, + {"FF:FF:FF:FF:FF:FF", "ls1", "192.168.122.10", "192.168.122.20"} + }; + + String[][] mcastMac3WithZeroLocators = new String[][]{ + {"FF:FF:FF:FF:FF:FF", "ls0"}, + {"FF:FF:FF:FF:FF:FF", "ls1"} + }; + + HwvtepOperationalDataChangeListener opDataChangeListener; + + @Before + public void setupListener() throws Exception { + setFinalStatic(DependencyQueue.class, "executorService", MoreExecutors.sameThreadExecutor()); + opDataChangeListener = new HwvtepOperationalDataChangeListener(dataBroker, hwvtepConnectionManager, connectionInstance); + } + + @After + public void cleanupListener() { + try { + opDataChangeListener.close(); + } catch (Exception e) { + } + } + + void setFinalStatic(Class cls, String fieldName, Object newValue) throws Exception { + Field fields[] = FieldUtils.getAllFields(cls); + for (Field field : fields) { + if (fieldName.equals(field.getName())) { + field.setAccessible(true); + Field modifiersField = Field.class.getDeclaredField("modifiers"); + modifiersField.setAccessible(true); + modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); + field.set(null, newValue); + break; + } + } + } @Test public void testLogicalSwitchAdd() throws Exception { @@ -80,12 +126,19 @@ public class HwvtepDataChangeListenerTest extends DataChangeListenerTestBase { verifyThatLogicalSwitchCreated(); } + @Test + public void testLogicalSwitchDelete() throws Exception { + addData(CONFIGURATION, LogicalSwitches.class, logicalSwitches); + addData(OPERATIONAL, LogicalSwitches.class, logicalSwitches); + resetOperations(); + deleteData(CONFIGURATION, LogicalSwitches.class, logicalSwitches); + verify(Operations.op, times(2)).delete(any()); + } + @Test public void testUcastMacAdd() throws Exception { addData(CONFIGURATION, LogicalSwitches.class, logicalSwitches); addData(OPERATIONAL, LogicalSwitches.class, logicalSwitches); - connectionInstance.getDeviceInfo().updateDeviceOpData(LogicalSwitches.class, ls0Iid, new UUID("ls0"), "ls0"); - connectionInstance.getDeviceInfo().updateDeviceOpData(LogicalSwitches.class, ls1Iid, new UUID("ls1"), "ls1"); resetOperations(); addData(CONFIGURATION, TerminationPoint.class, terminationPoints); addData(CONFIGURATION, RemoteUcastMacs.class, ucastMacs); @@ -94,12 +147,36 @@ public class HwvtepDataChangeListenerTest extends DataChangeListenerTestBase { //TODO add finer grained validation } + @Test + public void testUcastMacAddWithoutConfigTep() throws Exception { + addData(CONFIGURATION, LogicalSwitches.class, logicalSwitches); + addData(OPERATIONAL, LogicalSwitches.class, logicalSwitches); + resetOperations(); + addData(CONFIGURATION, RemoteUcastMacs.class, ucastMacs); + //4 ucast macs + 2 termination points + verify(Operations.op, times(6)).insert(any(UcastMacsRemote.class)); + //TODO add finer grained validation + } + + @Test + public void testUcastMacDelete() throws Exception { + addData(CONFIGURATION, LogicalSwitches.class, logicalSwitches); + addData(OPERATIONAL, LogicalSwitches.class, logicalSwitches); + addData(CONFIGURATION, TerminationPoint.class, terminationPoints); + addData(CONFIGURATION, RemoteUcastMacs.class, ucastMacs); + addData(OPERATIONAL, RemoteUcastMacs.class, ucastMacs); + addData(OPERATIONAL, TerminationPoint.class, terminationPoints); + + resetOperations(); + deleteData(CONFIGURATION, RemoteUcastMacs.class, ucastMacs); + verify(Operations.op, times(4)).delete(any()); + //TODO add finer grained validation + } + @Test public void testMcastMacAdd() throws Exception { addData(CONFIGURATION, LogicalSwitches.class, logicalSwitches); addData(OPERATIONAL, LogicalSwitches.class, logicalSwitches); - connectionInstance.getDeviceInfo().updateDeviceOpData(LogicalSwitches.class, ls0Iid, new UUID("ls0"), "ls0"); - connectionInstance.getDeviceInfo().updateDeviceOpData(LogicalSwitches.class, ls1Iid, new UUID("ls1"), "ls0"); resetOperations(); addData(CONFIGURATION, TerminationPoint.class, terminationPoints); addData(CONFIGURATION, RemoteMcastMacs.class, mcastMacs); @@ -108,11 +185,33 @@ public class HwvtepDataChangeListenerTest extends DataChangeListenerTestBase { } @Test - public void testAddMacs() throws Exception { + public void testMcastMacAddWithoutConfigTep() throws Exception { addData(CONFIGURATION, LogicalSwitches.class, logicalSwitches); addData(OPERATIONAL, LogicalSwitches.class, logicalSwitches); - connectionInstance.getDeviceInfo().updateDeviceOpData(LogicalSwitches.class, ls0Iid, new UUID("ls0"), "ls0"); - connectionInstance.getDeviceInfo().updateDeviceOpData(LogicalSwitches.class, ls1Iid, new UUID("ls1"), "ls0"); + resetOperations(); + addData(CONFIGURATION, RemoteMcastMacs.class, mcastMacs); + //2 mcast macs + 2 locator sets + 3 termination points + verify(Operations.op, times(7)).insert(Matchers.any()); + } + + @Test + public void testMcastMacDelete() throws Exception { + addData(CONFIGURATION, LogicalSwitches.class, logicalSwitches); + addData(OPERATIONAL, LogicalSwitches.class, logicalSwitches); + addData(CONFIGURATION, TerminationPoint.class, terminationPoints); + addData(CONFIGURATION, RemoteMcastMacs.class, mcastMacs); + addData(OPERATIONAL, TerminationPoint.class, terminationPoints); + addData(OPERATIONAL, RemoteMcastMacs.class, mcastMacs); + + resetOperations(); + deleteData(CONFIGURATION, RemoteMcastMacs.class, mcastMacs); + verify(Operations.op, times(2)).delete(Matchers.any()); + } + + @Test + public void testAddMacs() throws Exception { + Node node = addData(CONFIGURATION, LogicalSwitches.class, logicalSwitches); + addData(OPERATIONAL, LogicalSwitches.class, logicalSwitches); resetOperations(); addData(CONFIGURATION, TerminationPoint.class, terminationPoints); addData(CONFIGURATION, RemoteUcastMacs.class, ucastMacs); @@ -120,11 +219,83 @@ public class HwvtepDataChangeListenerTest extends DataChangeListenerTestBase { addData(OPERATIONAL, TerminationPoint.class, terminationPoints); addData(OPERATIONAL, RemoteUcastMacs.class, ucastMacs); + resetOperations(); + addData(CONFIGURATION, RemoteMcastMacs.class, mcastMacs); + //2 mcast mac + 2 locator sets ( termination point already added ) + verify(Operations.op, times(4)).insert(Matchers.any()); + } + + @Test + public void testUpdateMacs() throws Exception { + Node node = addData(CONFIGURATION, LogicalSwitches.class, logicalSwitches); + addData(OPERATIONAL, LogicalSwitches.class, logicalSwitches); + resetOperations(); + addData(CONFIGURATION, TerminationPoint.class, terminationPoints); + addData(CONFIGURATION, RemoteUcastMacs.class, ucastMacs); + verify(Operations.op, times(6)).insert(any(UcastMacsRemote.class)); + + addData(OPERATIONAL, TerminationPoint.class, terminationPoints); + addData(OPERATIONAL, RemoteUcastMacs.class, ucastMacs); + resetOperations(); + addData(CONFIGURATION, RemoteMcastMacs.class, mcastMacs); + verify(Operations.op, times(4)).insert(Matchers.any()); + addData(OPERATIONAL, RemoteMcastMacs.class, mcastMacs); + + resetOperations(); + addData(CONFIGURATION, RemoteMcastMacs.class, mcastMac2); + verify(Operations.op, times(2)).insert(Matchers.any()); + verify(Operations.op, times(2)).update(Matchers.any()); + verify(Operations.op, times(0)).delete(Matchers.any()); + } + + @Test + public void testUpdateMacsWithZeroLocators() throws Exception { + Node node = addData(CONFIGURATION, LogicalSwitches.class, logicalSwitches); + addData(OPERATIONAL, LogicalSwitches.class, logicalSwitches); + resetOperations(); + addData(CONFIGURATION, TerminationPoint.class, terminationPoints); + addData(CONFIGURATION, RemoteUcastMacs.class, ucastMacs); + verify(Operations.op, times(6)).insert(any(UcastMacsRemote.class)); + + addData(OPERATIONAL, TerminationPoint.class, terminationPoints); + addData(OPERATIONAL, RemoteUcastMacs.class, ucastMacs); + resetOperations(); + addData(CONFIGURATION, RemoteMcastMacs.class, mcastMacs); + verify(Operations.op, times(4)).insert(Matchers.any()); + addData(OPERATIONAL, RemoteMcastMacs.class, mcastMacs); + + resetOperations(); + addData(CONFIGURATION, RemoteMcastMacs.class, mcastMac3WithZeroLocators); + verify(Operations.op, times(2)).delete(Matchers.any()); + } + + @Test + public void testBackToBackMacsUpdate() throws Exception { + Node node = addData(CONFIGURATION, LogicalSwitches.class, logicalSwitches); + addData(OPERATIONAL, LogicalSwitches.class, logicalSwitches); + resetOperations(); + addData(CONFIGURATION, TerminationPoint.class, terminationPoints); + addData(CONFIGURATION, RemoteUcastMacs.class, ucastMacs); + verify(Operations.op, times(6)).insert(any(UcastMacsRemote.class)); resetOperations(); addData(CONFIGURATION, RemoteMcastMacs.class, mcastMacs); //2 mcast mac + 2 locator sets ( termination point already added ) + verify(Operations.op, times(0)).insert(Matchers.any()); + resetOperations(); + addData(OPERATIONAL, TerminationPoint.class, terminationPoints); + addData(OPERATIONAL, RemoteUcastMacs.class, ucastMacs); + connectionInstance.getDeviceInfo().onOpDataAvailable(); + //2 mcast mac + 2 locator sets ( termination point already added ) verify(Operations.op, times(4)).insert(Matchers.any()); + + resetOperations(); + addData(CONFIGURATION, RemoteMcastMacs.class, mcastMac2); + verify(Operations.op, times(0)).insert(Matchers.any()); + addData(OPERATIONAL, RemoteMcastMacs.class, mcastMacs); + connectionInstance.getDeviceInfo().onOpDataAvailable(); + verify(Operations.op, times(2)).insert(Matchers.any()); + verify(Operations.op, times(2)).update(Matchers.any()); } private void verifyThatLogicalSwitchCreated() { diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/test/java/org/opendaylight/ovsdb/hwvtepsouthbound/HwvtepOperationalDataChangeListener.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/test/java/org/opendaylight/ovsdb/hwvtepsouthbound/HwvtepOperationalDataChangeListener.java new file mode 100644 index 000000000..d139a5c28 --- /dev/null +++ b/hwvtepsouthbound/hwvtepsouthbound-impl/src/test/java/org/opendaylight/ovsdb/hwvtepsouthbound/HwvtepOperationalDataChangeListener.java @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2015 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.ovsdb.hwvtepsouthbound; + +import org.opendaylight.controller.md.sal.binding.api.ClusteredDataTreeChangeListener; +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.DataObjectModification.ModificationType; +import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier; +import org.opendaylight.controller.md.sal.binding.api.DataTreeModification; +import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.ovsdb.lib.notation.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.hwvtep.global.attributes.LogicalSwitches; +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.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.NetworkTopology; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node; +import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.opendaylight.yangtools.yang.binding.ChildOf; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.Identifiable; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Collection; + +public class HwvtepOperationalDataChangeListener implements ClusteredDataTreeChangeListener, AutoCloseable { + + private static final Logger LOG = LoggerFactory.getLogger(HwvtepOperationalDataChangeListener.class); + + private final ListenerRegistration registration; + private final HwvtepConnectionManager hcm; + private final DataBroker db; + private final HwvtepConnectionInstance connectionInstance; + + HwvtepOperationalDataChangeListener(DataBroker db, HwvtepConnectionManager hcm, HwvtepConnectionInstance connectionInstance) { + this.db = db; + this.hcm = hcm; + this.connectionInstance = connectionInstance; + DataTreeIdentifier treeId = + new DataTreeIdentifier(LogicalDatastoreType.OPERATIONAL, getWildcardPath()); + registration = db.registerDataTreeChangeListener(treeId, HwvtepOperationalDataChangeListener.this); + } + + @Override + public void close() throws Exception { + if(registration != null) { + registration.close(); + } + } + + @Override + public void onDataTreeChanged(Collection> changes) { + for (DataTreeModification change : changes) { + final InstanceIdentifier key = change.getRootPath().getRootIdentifier(); + final DataObjectModification mod = change.getRootNode(); + for (DataObjectModification child : mod.getModifiedChildren()) { + updateDeviceOpData(key, child); + } + DataObjectModification aug = mod.getModifiedAugmentation(HwvtepGlobalAugmentation.class); + if (aug != null && getModificationType(aug) != null) { + Collection> children = aug.getModifiedChildren(); + for (DataObjectModification child : children) { + updateDeviceOpData(key, child); + } + } + } + } + + private void updateDeviceOpData(InstanceIdentifier key, DataObjectModification mod) { + ModificationType type = getModificationType(mod); + if (type == null) { + return; + } + Class childClass = (Class) mod.getDataType(); + InstanceIdentifier instanceIdentifier = getKey(key, mod, mod.getDataAfter()); + switch(type) { + case WRITE: + connectionInstance.getDeviceInfo().updateDeviceOpData(childClass, instanceIdentifier, + new UUID("uuid"), mod.getDataAfter()); + break; + case DELETE: + connectionInstance.getDeviceInfo().clearDeviceOpData(childClass, instanceIdentifier); + break; + case SUBTREE_MODIFIED: + } + } + + private ModificationType getModificationType(DataObjectModification mod) { + try { + return mod.getModificationType(); + } catch (IllegalStateException e) { + LOG.debug("Failed to get the modification type ", e); + } + return null; + } + + private InstanceIdentifier getKey(InstanceIdentifier key, DataObjectModification child, + DataObject data) { + Class childClass = child.getDataType(); + InstanceIdentifier instanceIdentifier = null; + if (LogicalSwitches.class == childClass) { + LogicalSwitches ls = (LogicalSwitches)data; + instanceIdentifier = key.augmentation(HwvtepGlobalAugmentation.class).child(LogicalSwitches.class, ls.getKey()); + } else if (org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint.class == childClass) { + TerminationPoint tp = (TerminationPoint)data; + instanceIdentifier = key.child(TerminationPoint.class, tp.getKey()); + } else if (RemoteUcastMacs.class == childClass) { + RemoteUcastMacs mac = (RemoteUcastMacs)data; + instanceIdentifier = key.augmentation(HwvtepGlobalAugmentation.class).child(RemoteUcastMacs.class, mac.getKey()); + } else if (RemoteMcastMacs.class == childClass) { + RemoteMcastMacs mac = (RemoteMcastMacs)data; + instanceIdentifier = key.augmentation(HwvtepGlobalAugmentation.class).child(RemoteMcastMacs.class, mac.getKey()); + } + return instanceIdentifier; + } + + Class> getClass(Class cls) { + return (Class>) cls; + } + + private InstanceIdentifier getWildcardPath() { + InstanceIdentifier path = InstanceIdentifier + .create(NetworkTopology.class) + .child(Topology.class, new TopologyKey(HwvtepSouthboundConstants.HWVTEP_TOPOLOGY_ID)) + .child(Node.class); + return path; + } +} diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/test/java/org/opendaylight/ovsdb/hwvtepsouthbound/TestBuilders.java b/hwvtepsouthbound/hwvtepsouthbound-impl/src/test/java/org/opendaylight/ovsdb/hwvtepsouthbound/TestBuilders.java index 25628546e..2290920b1 100644 --- a/hwvtepsouthbound/hwvtepsouthbound-impl/src/test/java/org/opendaylight/ovsdb/hwvtepsouthbound/TestBuilders.java +++ b/hwvtepsouthbound/hwvtepsouthbound-impl/src/test/java/org/opendaylight/ovsdb/hwvtepsouthbound/TestBuilders.java @@ -44,15 +44,16 @@ public class TestBuilders { public static final String VXLAN_OVER_IPV4 = "vxlan_over_ipv4"; - public static void addLogicalSwitches(HwvtepGlobalAugmentationBuilder augmentationBuilder, String[]... data) { + public static List addLogicalSwitches(HwvtepGlobalAugmentationBuilder augmentationBuilder, String[]... data) { List logicalSwitcheses = Lists.newArrayList(); for (String row[] : data) { logicalSwitcheses.add(TestBuilders.buildLogicalSwitch(row)); } augmentationBuilder.setLogicalSwitches(logicalSwitcheses); + return logicalSwitcheses; } - public static void addRemoteMcastMacs(InstanceIdentifier iid, + public static List addRemoteMcastMacs(InstanceIdentifier iid, HwvtepGlobalAugmentationBuilder augmentationBuilder, String[]... data) { List remoteMcastMacses = Lists.newArrayList(); for (String row[] : data) { @@ -60,6 +61,7 @@ public class TestBuilders { remoteMcastMacses.add(TestBuilders.buildRemoteMcastMacs(iid, row[0], row[1], teps)); } augmentationBuilder.setRemoteMcastMacs(remoteMcastMacses); + return remoteMcastMacses; } public static List addRemoteUcastMacs(InstanceIdentifier iid, diff --git a/hwvtepsouthbound/hwvtepsouthbound-impl/src/test/resources/org/opendaylight/ovsdb/hwvtepsouthbound/hwvtep_schema.json b/hwvtepsouthbound/hwvtepsouthbound-impl/src/test/resources/org/opendaylight/ovsdb/hwvtepsouthbound/hwvtep_schema.json index 3d34523f7..dfb9d31ca 100644 --- a/hwvtepsouthbound/hwvtepsouthbound-impl/src/test/resources/org/opendaylight/ovsdb/hwvtepsouthbound/hwvtep_schema.json +++ b/hwvtepsouthbound/hwvtepsouthbound-impl/src/test/resources/org/opendaylight/ovsdb/hwvtepsouthbound/hwvtep_schema.json @@ -195,6 +195,9 @@ "ipaddr": { "type": "string" }, + "_uuid": { + "type": "string" + }, "locator_set": { "type": { "key": { @@ -222,6 +225,9 @@ "ipaddr": { "type": "string" }, + "_uuid": { + "type": "string" + }, "locator_set": { "type": { "key": { @@ -257,6 +263,9 @@ } } }, + "_uuid": { + "type": "string" + }, "indexes": [ [ "encapsulation_type", @@ -266,6 +275,9 @@ }, "Physical_Locator_Set": { "columns": { + "_uuid": { + "type": "string" + }, "locators": { "mutable": false, "type": { @@ -283,6 +295,9 @@ "description": { "type": "string" }, + "_uuid": { + "type": "string" + }, "name": { "type": "string" }, @@ -331,6 +346,9 @@ "description": { "type": "string" }, + "_uuid": { + "type": "string" + }, "management_ips": { "type": { "key": "string", @@ -443,6 +461,9 @@ "ipaddr": { "type": "string" }, + "_uuid": { + "type": "string" + }, "locator": { "type": { "key": { @@ -470,6 +491,12 @@ "ipaddr": { "type": "string" }, + "_uuid": { + "type": "uuid" + }, + "uuid": { + "type": "uuid" + }, "locator": { "type": { "key": { -- 2.36.6