2 * Copyright © 2015, 2017 China Telecom Beijing Research Institute and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.ovsdb.hwvtepsouthbound.transact;
11 import static org.opendaylight.ovsdb.lib.operations.Operations.op;
13 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
14 import java.util.ArrayList;
15 import java.util.Collection;
16 import java.util.Collections;
17 import java.util.List;
19 import java.util.Map.Entry;
20 import java.util.Objects;
21 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
22 import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepDeviceInfo;
23 import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundConstants;
24 import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundUtil;
25 import org.opendaylight.ovsdb.lib.notation.UUID;
26 import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
27 import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
28 import org.opendaylight.ovsdb.schema.hardwarevtep.McastMacsRemote;
29 import org.opendaylight.ovsdb.utils.mdsal.utils.TransactionType;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitches;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteMcastMacs;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical.locator.set.attributes.LocatorSet;
34 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
35 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
39 public class McastMacsRemoteUpdateCommand extends AbstractTransactCommand<RemoteMcastMacs, HwvtepGlobalAugmentation> {
40 private static final Logger LOG = LoggerFactory.getLogger(McastMacsRemoteUpdateCommand.class);
41 private static final McastMacUnMetDependencyGetter MCAST_MAC_DATA_VALIDATOR = new McastMacUnMetDependencyGetter();
43 public McastMacsRemoteUpdateCommand(HwvtepOperationalState state,
44 Collection<DataTreeModification<Node>> changes) {
45 super(state, changes);
49 public void execute(TransactionBuilder transaction) {
50 Map<InstanceIdentifier<Node>, List<RemoteMcastMacs>> updateds =
51 extractUpdated(getChanges(),RemoteMcastMacs.class);
52 if (!updateds.isEmpty()) {
53 for (Entry<InstanceIdentifier<Node>, List<RemoteMcastMacs>> updated:
54 updateds.entrySet()) {
55 updateMcastMacRemote(transaction, updated.getKey(), updated.getValue());
60 private void updateMcastMacRemote(TransactionBuilder transaction,
61 InstanceIdentifier<Node> instanceIdentifier, List<RemoteMcastMacs> macList) {
62 for (RemoteMcastMacs mac: macList) {
63 //add / update only if locator set got changed
64 if (!HwvtepSouthboundUtil.isEmpty(mac.getLocatorSet())) {
65 onConfigUpdate(transaction, instanceIdentifier, mac, null);
71 public void onConfigUpdate(TransactionBuilder transaction,
72 InstanceIdentifier<Node> nodeIid,
73 RemoteMcastMacs remoteMcastMac,
74 InstanceIdentifier macKey,
75 Object... extraData) {
76 InstanceIdentifier<RemoteMcastMacs> macIid = nodeIid.augmentation(HwvtepGlobalAugmentation.class)
77 .child(RemoteMcastMacs.class, remoteMcastMac.key());
78 processDependencies(MCAST_MAC_DATA_VALIDATOR, transaction, nodeIid, macIid, remoteMcastMac);
82 public void doDeviceTransaction(TransactionBuilder transaction,
83 InstanceIdentifier<Node> instanceIdentifier,
85 InstanceIdentifier macKey,
86 Object... extraData) {
87 LOG.debug("Creating remoteMcastMacs, mac address: {}", mac.getMacEntryKey().getValue());
88 final HwvtepDeviceInfo.DeviceData operationalMacOptional =
89 getDeviceInfo().getDeviceOperData(RemoteMcastMacs.class, macKey);
90 McastMacsRemote mcastMacsRemote = TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(),
91 McastMacsRemote.class);
92 setIpAddress(mcastMacsRemote, mac);
93 setLocatorSet(transaction, mcastMacsRemote, mac);
94 setLogicalSwitch(transaction, mcastMacsRemote, mac);
95 if (operationalMacOptional == null) {
96 setMac(mcastMacsRemote, mac);
97 LOG.trace("execute: create RemoteMcastMac entry: {}", mcastMacsRemote);
98 transaction.add(op.insert(mcastMacsRemote));
99 transaction.add(op.comment("McastMacRemote: Creating " + mac.getMacEntryKey().getValue()));
100 updateCurrentTxData(RemoteMcastMacs.class, macKey, TXUUID, mac);
101 updateControllerTxHistory(TransactionType.ADD, mcastMacsRemote);
102 } else if (operationalMacOptional.getUuid() != null) {
103 UUID macEntryUUID = operationalMacOptional.getUuid();
104 McastMacsRemote extraMac = TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(),
105 McastMacsRemote.class, null);
106 extraMac.getUuidColumn().setData(macEntryUUID);
107 LOG.trace("execute: update RemoteMcastMac entry: {}", mcastMacsRemote);
108 transaction.add(op.update(mcastMacsRemote)
109 .where(extraMac.getUuidColumn().getSchema().opEqual(macEntryUUID))
111 transaction.add(op.comment("McastMacRemote: Updating " + macEntryUUID));
112 updateControllerTxHistory(TransactionType.UPDATE, mcastMacsRemote);
113 //add to updates so that tep ref counts can be updated upon success
114 addToUpdates(macKey, mac);
116 LOG.warn("Unable to update remoteMcastMacs {} because uuid not found in the operational store",
117 mac.getMacEntryKey().getValue());
121 private void setLogicalSwitch(final TransactionBuilder transaction, final McastMacsRemote mcastMacsRemote,
122 final RemoteMcastMacs inputMac) {
123 if (inputMac.getLogicalSwitchRef() != null) {
124 @SuppressWarnings("unchecked")
125 InstanceIdentifier<LogicalSwitches> lswitchIid =
126 (InstanceIdentifier<LogicalSwitches>) inputMac.getLogicalSwitchRef().getValue();
127 mcastMacsRemote.setLogicalSwitch(TransactUtils.getLogicalSwitchUUID(transaction,
128 getOperationalState(), lswitchIid));
132 private void setLocatorSet(TransactionBuilder transaction, McastMacsRemote mcastMacsRemote,
133 RemoteMcastMacs inputMac) {
134 if (inputMac.getLocatorSet() != null && !inputMac.getLocatorSet().isEmpty()) {
135 UUID locatorSetUuid = TransactUtils.createPhysicalLocatorSet(getOperationalState(),
136 transaction, inputMac.getLocatorSet());
137 mcastMacsRemote.setLocatorSet(locatorSetUuid);
141 private void setIpAddress(McastMacsRemote mcastMacsRemote, RemoteMcastMacs inputMac) {
142 if (inputMac.getIpaddr() != null) {
143 mcastMacsRemote.setIpAddress(inputMac.getIpaddr().getIpv4Address().getValue());
147 private void setMac(McastMacsRemote mcastMacsRemote, RemoteMcastMacs inputMac) {
148 if (inputMac.getMacEntryKey() != null) {
149 if (inputMac.getMacEntryKey().equals(HwvtepSouthboundConstants.UNKNOWN_DST_MAC)) {
150 mcastMacsRemote.setMac(HwvtepSouthboundConstants.UNKNOWN_DST_STRING);
152 mcastMacsRemote.setMac(inputMac.getMacEntryKey().getValue());
158 protected List<RemoteMcastMacs> getData(HwvtepGlobalAugmentation augmentation) {
159 return augmentation.getRemoteMcastMacs();
163 protected boolean areEqual(RemoteMcastMacs macs1, RemoteMcastMacs macs2) {
164 return macs1.key().equals(macs2.key()) && Objects.equals(macs1.getLocatorSet(), macs2.getLocatorSet());
167 static class McastMacUnMetDependencyGetter extends UnMetDependencyGetter<RemoteMcastMacs> {
170 public List<InstanceIdentifier<?>> getLogicalSwitchDependencies(RemoteMcastMacs data) {
172 return Collections.emptyList();
174 return Collections.singletonList(data.getLogicalSwitchRef().getValue());
178 public List<InstanceIdentifier<?>> getTerminationPointDependencies(RemoteMcastMacs data) {
179 if (data == null || HwvtepSouthboundUtil.isEmpty(data.getLocatorSet())) {
180 return Collections.emptyList();
182 List<InstanceIdentifier<?>> locators = new ArrayList<>();
183 for (LocatorSet locator: data.getLocatorSet()) {
184 locators.add(locator.getLocatorRef().getValue());
190 @SuppressFBWarnings("UC_USELESS_OBJECT")
191 private void updateLocatorRefCounts(MdsalUpdate mdsalUpdate) {
192 //decrement the refcounts from old mcast mac
193 //increment the refcounts for new mcast mac
194 RemoteMcastMacs newMac = (RemoteMcastMacs) mdsalUpdate.getNewData();
195 RemoteMcastMacs oldMac = (RemoteMcastMacs) mdsalUpdate.getOldData();
196 InstanceIdentifier<RemoteMcastMacs> macIid = mdsalUpdate.getKey();
198 if (oldMac != null && !oldMac.equals(newMac)) {
199 if (oldMac.getLocatorSet() != null) {
200 List<LocatorSet> removedLocators = new ArrayList<>(oldMac.getLocatorSet());
201 if (newMac.getLocatorSet() != null) {
202 removedLocators.removeAll(newMac.getLocatorSet());
204 removedLocators.forEach(iid -> getDeviceInfo().decRefCount(macIid, iid.getLocatorRef().getValue()));
210 protected void onCommandSucceeded() {
211 for (MdsalUpdate mdsalUpdate : updates.get(getDeviceTransaction())) {
212 updateLocatorRefCounts(mdsalUpdate);
213 RemoteMcastMacs mac = (RemoteMcastMacs) mdsalUpdate.getNewData();
214 InstanceIdentifier<RemoteMcastMacs> macIid = mdsalUpdate.getKey();
215 getDeviceInfo().updateRemoteMcast(
216 (InstanceIdentifier<LogicalSwitches>) mac.getLogicalSwitchRef().getValue(), macIid, mac);