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
8 package org.opendaylight.ovsdb.hwvtepsouthbound.transact;
10 import static org.opendaylight.ovsdb.lib.operations.Operations.op;
12 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
13 import java.util.ArrayList;
14 import java.util.Collection;
15 import java.util.Collections;
16 import java.util.List;
18 import java.util.Map.Entry;
19 import java.util.Objects;
20 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
21 import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepDeviceInfo;
22 import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundConstants;
23 import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundUtil;
24 import org.opendaylight.ovsdb.lib.notation.UUID;
25 import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
26 import org.opendaylight.ovsdb.schema.hardwarevtep.McastMacsRemote;
27 import org.opendaylight.ovsdb.utils.mdsal.utils.TransactionType;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitches;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteMcastMacs;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical.locator.set.attributes.LocatorSet;
32 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
33 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
37 public class McastMacsRemoteUpdateCommand extends AbstractTransactCommand<RemoteMcastMacs, HwvtepGlobalAugmentation> {
38 private static final Logger LOG = LoggerFactory.getLogger(McastMacsRemoteUpdateCommand.class);
39 private static final McastMacUnMetDependencyGetter MCAST_MAC_DATA_VALIDATOR = new McastMacUnMetDependencyGetter();
41 public McastMacsRemoteUpdateCommand(final HwvtepOperationalState state,
42 final Collection<DataTreeModification<Node>> changes) {
43 super(state, changes);
47 public void execute(final TransactionBuilder transaction) {
48 Map<InstanceIdentifier<Node>, List<RemoteMcastMacs>> updateds =
49 extractUpdated(getChanges(),RemoteMcastMacs.class);
50 if (!updateds.isEmpty()) {
51 for (Entry<InstanceIdentifier<Node>, List<RemoteMcastMacs>> updated:
52 updateds.entrySet()) {
53 updateMcastMacRemote(transaction, updated.getKey(), updated.getValue());
58 private void updateMcastMacRemote(final TransactionBuilder transaction,
59 final InstanceIdentifier<Node> instanceIdentifier, final List<RemoteMcastMacs> macList) {
60 for (RemoteMcastMacs mac: macList) {
61 //add / update only if locator set got changed
62 if (!HwvtepSouthboundUtil.isEmpty(mac.getLocatorSet())) {
63 onConfigUpdate(transaction, instanceIdentifier, mac, null);
69 public void onConfigUpdate(final TransactionBuilder transaction,
70 final InstanceIdentifier<Node> nodeIid,
71 final RemoteMcastMacs remoteMcastMac,
72 final InstanceIdentifier macKey,
73 final Object... extraData) {
74 InstanceIdentifier<RemoteMcastMacs> macIid = nodeIid.augmentation(HwvtepGlobalAugmentation.class)
75 .child(RemoteMcastMacs.class, remoteMcastMac.key());
76 processDependencies(MCAST_MAC_DATA_VALIDATOR, transaction, nodeIid, macIid, remoteMcastMac);
80 public void doDeviceTransaction(final TransactionBuilder transaction,
81 final InstanceIdentifier<Node> instanceIdentifier,
82 final RemoteMcastMacs mac,
83 final InstanceIdentifier macKey,
84 final Object... extraData) {
85 LOG.debug("Creating remoteMcastMacs, mac address: {}", mac.getMacEntryKey().getValue());
86 final HwvtepDeviceInfo.DeviceData operationalMacOptional =
87 getDeviceInfo().getDeviceOperData(RemoteMcastMacs.class, macKey);
88 McastMacsRemote mcastMacsRemote = transaction.getTypedRowWrapper(McastMacsRemote.class);
89 setIpAddress(mcastMacsRemote, mac);
90 setLocatorSet(transaction, mcastMacsRemote, mac);
91 setLogicalSwitch(transaction, mcastMacsRemote, mac);
92 if (operationalMacOptional == null) {
93 setMac(mcastMacsRemote, mac);
94 LOG.trace("execute: create RemoteMcastMac entry: {}", mcastMacsRemote);
95 transaction.add(op.insert(mcastMacsRemote));
96 transaction.add(op.comment("McastMacRemote: Creating " + mac.getMacEntryKey().getValue()));
97 updateCurrentTxData(RemoteMcastMacs.class, macKey, TXUUID, mac);
98 updateControllerTxHistory(TransactionType.ADD, mcastMacsRemote);
99 } else if (operationalMacOptional.getUuid() != null) {
100 UUID macEntryUUID = operationalMacOptional.getUuid();
101 McastMacsRemote extraMac = transaction.getTypedRowSchema(McastMacsRemote.class);
102 extraMac.getUuidColumn().setData(macEntryUUID);
103 LOG.trace("execute: update RemoteMcastMac entry: {}", mcastMacsRemote);
104 transaction.add(op.update(mcastMacsRemote)
105 .where(extraMac.getUuidColumn().getSchema().opEqual(macEntryUUID))
107 transaction.add(op.comment("McastMacRemote: Updating " + macEntryUUID));
108 updateControllerTxHistory(TransactionType.UPDATE, mcastMacsRemote);
109 //add to updates so that tep ref counts can be updated upon success
110 addToUpdates(macKey, mac);
112 LOG.warn("Unable to update remoteMcastMacs {} because uuid not found in the operational store",
113 mac.getMacEntryKey().getValue());
117 private void setLogicalSwitch(final TransactionBuilder transaction, final McastMacsRemote mcastMacsRemote,
118 final RemoteMcastMacs inputMac) {
119 if (inputMac.getLogicalSwitchRef() != null) {
120 @SuppressWarnings("unchecked")
121 InstanceIdentifier<LogicalSwitches> lswitchIid =
122 (InstanceIdentifier<LogicalSwitches>) inputMac.getLogicalSwitchRef().getValue();
123 mcastMacsRemote.setLogicalSwitch(TransactUtils.getLogicalSwitchUUID(transaction,
124 getOperationalState(), lswitchIid));
128 private void setLocatorSet(final TransactionBuilder transaction, final McastMacsRemote mcastMacsRemote,
129 final RemoteMcastMacs inputMac) {
130 if (inputMac.getLocatorSet() != null && !inputMac.getLocatorSet().isEmpty()) {
131 UUID locatorSetUuid = TransactUtils.createPhysicalLocatorSet(getOperationalState(),
132 transaction, inputMac.getLocatorSet());
133 mcastMacsRemote.setLocatorSet(locatorSetUuid);
137 private void setIpAddress(final McastMacsRemote mcastMacsRemote, final RemoteMcastMacs inputMac) {
138 if (inputMac.getIpaddr() != null) {
139 mcastMacsRemote.setIpAddress(inputMac.getIpaddr().getIpv4Address().getValue());
143 private void setMac(final McastMacsRemote mcastMacsRemote, final RemoteMcastMacs inputMac) {
144 if (inputMac.getMacEntryKey() != null) {
145 if (inputMac.getMacEntryKey().equals(HwvtepSouthboundConstants.UNKNOWN_DST_MAC)) {
146 mcastMacsRemote.setMac(HwvtepSouthboundConstants.UNKNOWN_DST_STRING);
148 mcastMacsRemote.setMac(inputMac.getMacEntryKey().getValue());
154 protected List<RemoteMcastMacs> getData(final HwvtepGlobalAugmentation augmentation) {
155 return augmentation.getRemoteMcastMacs();
159 protected boolean areEqual(final RemoteMcastMacs macs1, final RemoteMcastMacs macs2) {
160 return macs1.key().equals(macs2.key()) && Objects.equals(macs1.getLocatorSet(), macs2.getLocatorSet());
163 static class McastMacUnMetDependencyGetter extends UnMetDependencyGetter<RemoteMcastMacs> {
166 public List<InstanceIdentifier<?>> getLogicalSwitchDependencies(final RemoteMcastMacs data) {
168 return Collections.emptyList();
170 return Collections.singletonList(data.getLogicalSwitchRef().getValue());
174 public List<InstanceIdentifier<?>> getTerminationPointDependencies(final RemoteMcastMacs data) {
175 if (data == null || HwvtepSouthboundUtil.isEmpty(data.getLocatorSet())) {
176 return Collections.emptyList();
178 List<InstanceIdentifier<?>> locators = new ArrayList<>();
179 for (LocatorSet locator: data.getLocatorSet()) {
180 locators.add(locator.getLocatorRef().getValue());
186 @SuppressFBWarnings("UC_USELESS_OBJECT")
187 private void updateLocatorRefCounts(final MdsalUpdate mdsalUpdate) {
188 //decrement the refcounts from old mcast mac
189 //increment the refcounts for new mcast mac
190 RemoteMcastMacs newMac = (RemoteMcastMacs) mdsalUpdate.getNewData();
191 RemoteMcastMacs oldMac = (RemoteMcastMacs) mdsalUpdate.getOldData();
192 InstanceIdentifier<RemoteMcastMacs> macIid = mdsalUpdate.getKey();
194 if (oldMac != null && !oldMac.equals(newMac)) {
195 if (oldMac.getLocatorSet() != null) {
196 List<LocatorSet> removedLocators = new ArrayList<>(oldMac.getLocatorSet());
197 if (newMac.getLocatorSet() != null) {
198 removedLocators.removeAll(newMac.getLocatorSet());
200 removedLocators.forEach(iid -> getDeviceInfo().decRefCount(macIid, iid.getLocatorRef().getValue()));
206 protected void onCommandSucceeded() {
207 for (MdsalUpdate mdsalUpdate : updates.get(getDeviceTransaction())) {
208 updateLocatorRefCounts(mdsalUpdate);
209 RemoteMcastMacs mac = (RemoteMcastMacs) mdsalUpdate.getNewData();
210 InstanceIdentifier<RemoteMcastMacs> macIid = mdsalUpdate.getKey();
211 getDeviceInfo().updateRemoteMcast(
212 (InstanceIdentifier<LogicalSwitches>) mac.getLogicalSwitchRef().getValue(), macIid, mac);