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 com.google.common.collect.Lists;
13 import com.google.common.collect.Sets;
14 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
15 import java.util.ArrayList;
16 import java.util.Collection;
17 import java.util.Collections;
18 import java.util.List;
20 import java.util.Map.Entry;
21 import java.util.Objects;
24 import org.opendaylight.mdsal.binding.api.DataTreeModification;
25 import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepDeviceInfo;
26 import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundConstants;
27 import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundUtil;
28 import org.opendaylight.ovsdb.lib.notation.UUID;
29 import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
30 import org.opendaylight.ovsdb.schema.hardwarevtep.McastMacsRemote;
31 import org.opendaylight.ovsdb.utils.mdsal.utils.TransactionType;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitches;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteMcastMacs;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical.locator.set.attributes.LocatorSet;
36 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
37 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
41 public class McastMacsRemoteUpdateCommand extends AbstractTransactCommand<RemoteMcastMacs, HwvtepGlobalAugmentation> {
42 private static final Logger LOG = LoggerFactory.getLogger(McastMacsRemoteUpdateCommand.class);
43 private static final McastMacUnMetDependencyGetter MCAST_MAC_DATA_VALIDATOR = new McastMacUnMetDependencyGetter();
45 public McastMacsRemoteUpdateCommand(final HwvtepOperationalState state,
46 final Collection<DataTreeModification<Node>> changes) {
47 super(state, changes);
51 public void execute(final TransactionBuilder transaction) {
52 Map<InstanceIdentifier<Node>, List<RemoteMcastMacs>> updateds =
53 extractUpdated(getChanges(),RemoteMcastMacs.class);
54 if (!updateds.isEmpty()) {
55 for (Entry<InstanceIdentifier<Node>, List<RemoteMcastMacs>> updated:
56 updateds.entrySet()) {
57 updateMcastMacRemote(transaction, updated.getKey(), updated.getValue());
62 private void updateMcastMacRemote(final TransactionBuilder transaction,
63 final InstanceIdentifier<Node> instanceIdentifier, final List<RemoteMcastMacs> macList) {
64 for (RemoteMcastMacs mac: macList) {
65 //add / update only if locator set got changed
66 InstanceIdentifier<RemoteMcastMacs> macIid = instanceIdentifier
67 .augmentation(HwvtepGlobalAugmentation.class)
68 .child(RemoteMcastMacs.class, mac.key());
69 updateConfigData(RemoteMcastMacs.class, macIid, mac);
70 if (!HwvtepSouthboundUtil.isEmpty(mac.getLocatorSet())) {
71 onConfigUpdate(transaction, instanceIdentifier, mac, null);
77 public void onConfigUpdate(final TransactionBuilder transaction,
78 final InstanceIdentifier<Node> nodeIid,
79 final RemoteMcastMacs remoteMcastMac,
80 final InstanceIdentifier macKey,
81 final Object... extraData) {
82 InstanceIdentifier<RemoteMcastMacs> macIid = nodeIid.augmentation(HwvtepGlobalAugmentation.class)
83 .child(RemoteMcastMacs.class, remoteMcastMac.key());
84 processDependencies(MCAST_MAC_DATA_VALIDATOR, transaction, nodeIid, macIid, remoteMcastMac);
88 public void doDeviceTransaction(final TransactionBuilder transaction,
89 final InstanceIdentifier<Node> instanceIdentifier,
90 final RemoteMcastMacs mac,
91 final InstanceIdentifier macKey,
92 final Object... extraData) {
94 String nodeId = instanceIdentifier.firstKeyOf(Node.class).getNodeId().getValue();
95 LOG.debug("Creating remoteMcastMacs, mac address: {} {}", nodeId, mac.getMacEntryKey().getValue());
97 McastMacsRemote mcastMacsRemote = transaction.getTypedRowWrapper(McastMacsRemote.class);
98 setIpAddress(mcastMacsRemote, mac);
99 setLogicalSwitch(transaction, mcastMacsRemote, mac);
100 setMac(mcastMacsRemote, mac);
101 InstanceIdentifier<RemoteMcastMacs> macIid = instanceIdentifier.augmentation(HwvtepGlobalAugmentation.class)
102 .child(RemoteMcastMacs.class, mac.key());
103 HwvtepDeviceInfo.DeviceData deviceData = super.fetchDeviceData(RemoteMcastMacs.class, macIid);
104 if (deviceData == null) {
105 setLocatorSet(transaction, mcastMacsRemote, mac);
106 transaction.add(op.insert(mcastMacsRemote));
107 updateCurrentTxData(RemoteMcastMacs.class, macIid, new UUID("uuid"), mac);
108 updateControllerTxHistory(TransactionType.ADD, mcastMacsRemote);
109 LOG.info("CONTROLLER - {} {}", TransactionType.ADD, mcastMacsRemote);
110 } else if (deviceData.getUuid() != null) {
111 setLocatorSet(transaction, mcastMacsRemote, mac);
112 UUID macEntryUUID = deviceData.getUuid();
113 McastMacsRemote extraMac = transaction.getTypedRowSchema(McastMacsRemote.class);
114 extraMac.getUuidColumn().setData(macEntryUUID);
115 transaction.add(op.update(mcastMacsRemote)
116 .where(extraMac.getUuidColumn().getSchema().opEqual(macEntryUUID))
118 updateControllerTxHistory(TransactionType.UPDATE, mcastMacsRemote);
119 LOG.info("CONTROLLER - {} {}", TransactionType.UPDATE, mcastMacsRemote);
120 addToUpdates(macIid, mac);
122 LOG.error("Unable to update remoteMcastMacs {} {} because uuid not found in the operational"
123 + " store txId: {}", mac, deviceData, getOperationalState().getTransactionId());
125 updateConfigData(RemoteMcastMacs.class, macIid, mac);
128 private void setLogicalSwitch(final TransactionBuilder transaction, final McastMacsRemote mcastMacsRemote,
129 final RemoteMcastMacs inputMac) {
130 if (inputMac.getLogicalSwitchRef() != null) {
131 @SuppressWarnings("unchecked")
132 InstanceIdentifier<LogicalSwitches> lswitchIid =
133 (InstanceIdentifier<LogicalSwitches>) inputMac.getLogicalSwitchRef().getValue();
134 UUID logicalSwitchUUID = TransactUtils.getLogicalSwitchUUID(transaction, getOperationalState(), lswitchIid);
135 if (logicalSwitchUUID != null) {
136 mcastMacsRemote.setLogicalSwitch(logicalSwitchUUID);
141 private void setLocatorSet(final TransactionBuilder transaction, final McastMacsRemote mcastMacsRemote,
142 final RemoteMcastMacs inputMac) {
143 if (inputMac.getLocatorSet() != null && !inputMac.getLocatorSet().isEmpty()) {
144 UUID locatorSetUuid = TransactUtils.createPhysicalLocatorSet(getOperationalState(),
145 transaction, inputMac.getLocatorSet());
146 mcastMacsRemote.setLocatorSet(locatorSetUuid);
150 private void setIpAddress(final McastMacsRemote mcastMacsRemote, final RemoteMcastMacs inputMac) {
151 if (inputMac.getIpaddr() != null) {
152 mcastMacsRemote.setIpAddress(inputMac.getIpaddr().getIpv4Address().getValue());
156 private void setMac(final McastMacsRemote mcastMacsRemote, final RemoteMcastMacs inputMac) {
157 if (inputMac.getMacEntryKey() != null) {
158 if (inputMac.getMacEntryKey().equals(HwvtepSouthboundConstants.UNKNOWN_DST_MAC)) {
159 mcastMacsRemote.setMac(HwvtepSouthboundConstants.UNKNOWN_DST_STRING);
161 mcastMacsRemote.setMac(inputMac.getMacEntryKey().getValue());
167 protected List<RemoteMcastMacs> getData(final HwvtepGlobalAugmentation augmentation) {
168 return augmentation.getRemoteMcastMacs();
172 protected boolean areEqual(final RemoteMcastMacs macs1, final RemoteMcastMacs macs2) {
173 if (getOperationalState().isInReconciliation()) {
174 return Objects.equals(macs1.key(), macs2.key())
175 && compareLocatorSets(macs1.getLocatorSet(), macs2.getLocatorSet());
177 return Objects.equals(macs1.key(), macs2.key())
178 && Objects.equals(macs1.getLocatorSet(), macs2.getLocatorSet());
181 private boolean compareLocatorSets(List<LocatorSet> locatorSet1, List<LocatorSet> locatorSet2) {
182 if (locatorSet1 == null) {
183 locatorSet1 = Collections.EMPTY_LIST;
185 if (locatorSet2 == null) {
186 locatorSet2 = Collections.EMPTY_LIST;
188 if (locatorSet1.size() != locatorSet2.size()) {
191 Set set1 = Sets.newHashSet(locatorSet1);
192 Set set2 = Sets.newHashSet(locatorSet2);
193 return set1.containsAll(set2);
196 static class McastMacUnMetDependencyGetter extends UnMetDependencyGetter<RemoteMcastMacs> {
199 public List<InstanceIdentifier<?>> getLogicalSwitchDependencies(final RemoteMcastMacs data) {
201 return Collections.EMPTY_LIST;
203 return Lists.newArrayList(data.getLogicalSwitchRef().getValue());
207 public List<InstanceIdentifier<?>> getTerminationPointDependencies(final RemoteMcastMacs data) {
208 if (data == null || HwvtepSouthboundUtil.isEmpty(data.getLocatorSet())) {
209 return Collections.EMPTY_LIST;
211 List<InstanceIdentifier<?>> locators = new ArrayList<>();
212 for (LocatorSet locator: data.getLocatorSet()) {
213 locators.add(locator.getLocatorRef().getValue());
219 @SuppressFBWarnings("UC_USELESS_OBJECT")
220 private void updateLocatorRefCounts(final MdsalUpdate mdsalUpdate) {
221 //decrement the refcounts from old mcast mac
222 //increment the refcounts for new mcast mac
223 RemoteMcastMacs newMac = (RemoteMcastMacs) mdsalUpdate.getNewData();
224 RemoteMcastMacs oldMac = (RemoteMcastMacs) mdsalUpdate.getOldData();
225 InstanceIdentifier<RemoteMcastMacs> macIid = mdsalUpdate.getKey();
227 if (oldMac != null && !oldMac.equals(newMac)) {
228 if (oldMac.getLocatorSet() != null) {
229 List<LocatorSet> removedLocators = new ArrayList<>(oldMac.getLocatorSet());
230 if (newMac.getLocatorSet() != null) {
231 removedLocators.removeAll(newMac.getLocatorSet());
233 removedLocators.forEach(iid -> getDeviceInfo().decRefCount(macIid, iid.getLocatorRef().getValue()));
239 public void onSuccess(TransactionBuilder tx) {
240 for (MdsalUpdate mdsalUpdate : updates) {
241 updateLocatorRefCounts(mdsalUpdate);
242 RemoteMcastMacs mac = (RemoteMcastMacs) mdsalUpdate.getNewData();
243 InstanceIdentifier<RemoteMcastMacs> macIid = mdsalUpdate.getKey();
244 getDeviceInfo().updateRemoteMcast(
245 (InstanceIdentifier<LogicalSwitches>) mac.getLogicalSwitchRef().getValue(), macIid, mac);