6d6538faca9cbce7a4371c903f054c8c7785cde7
[ovsdb.git] / hwvtepsouthbound / hwvtepsouthbound-impl / src / main / java / org / opendaylight / ovsdb / hwvtepsouthbound / transact / McastMacsRemoteUpdateCommand.java
1 /*
2  * Copyright © 2015, 2017 China Telecom Beijing Research Institute and others.  All rights reserved.
3  *
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
7  */
8
9 package org.opendaylight.ovsdb.hwvtepsouthbound.transact;
10
11 import com.google.common.base.Optional;
12
13 import java.util.ArrayList;
14 import java.util.Collection;
15 import java.util.Collections;
16 import java.util.List;
17 import java.util.Map;
18 import java.util.Map.Entry;
19 import java.util.Objects;
20
21 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
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.lib.schema.typed.TyperUtils;
27 import org.opendaylight.ovsdb.schema.hardwarevtep.McastMacsRemote;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitches;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteMcastMacs;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical.locator.set.attributes.LocatorSet;
33 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
34 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
37
38 import static org.opendaylight.ovsdb.lib.operations.Operations.op;
39
40 public class McastMacsRemoteUpdateCommand extends AbstractTransactCommand<RemoteMcastMacs, HwvtepGlobalAugmentation> {
41     private static final Logger LOG = LoggerFactory.getLogger(McastMacsRemoteUpdateCommand.class);
42     private static final McastMacUnMetDependencyGetter MCAST_MAC_DATA_VALIDATOR = new McastMacUnMetDependencyGetter();
43
44     public McastMacsRemoteUpdateCommand(HwvtepOperationalState state,
45             Collection<DataTreeModification<Node>> changes) {
46         super(state, changes);
47     }
48
49     @Override
50     public void execute(TransactionBuilder transaction) {
51         Map<InstanceIdentifier<Node>, List<RemoteMcastMacs>> updateds =
52                 extractUpdated(getChanges(),RemoteMcastMacs.class);
53         if (!updateds.isEmpty()) {
54             for (Entry<InstanceIdentifier<Node>, List<RemoteMcastMacs>> updated:
55                 updateds.entrySet()) {
56                 updateMcastMacRemote(transaction,  updated.getKey(), updated.getValue());
57             }
58         }
59     }
60
61     private void updateMcastMacRemote(TransactionBuilder transaction,
62             InstanceIdentifier<Node> instanceIdentifier, List<RemoteMcastMacs> macList) {
63         for (RemoteMcastMacs mac: macList) {
64             //add / update only if locator set got changed
65             if (!HwvtepSouthboundUtil.isEmpty(mac.getLocatorSet())) {
66                 onConfigUpdate(transaction, instanceIdentifier, mac, null);
67             }
68         }
69     }
70
71     @Override
72     public void onConfigUpdate(TransactionBuilder transaction,
73                                   InstanceIdentifier<Node> nodeIid,
74                                   RemoteMcastMacs remoteMcastMac,
75                                   InstanceIdentifier macKey,
76                                   Object... extraData) {
77         InstanceIdentifier<RemoteMcastMacs> macIid = nodeIid.augmentation(HwvtepGlobalAugmentation.class).
78                 child(RemoteMcastMacs.class, remoteMcastMac.getKey());
79         processDependencies(MCAST_MAC_DATA_VALIDATOR, transaction, nodeIid, macIid, remoteMcastMac);
80     }
81
82     @Override
83     public void doDeviceTransaction(TransactionBuilder transaction,
84                                        InstanceIdentifier<Node> instanceIdentifier,
85                                        RemoteMcastMacs mac,
86                                        InstanceIdentifier macKey,
87                                        Object... extraData) {
88             LOG.debug("Creating remoteMcastMacs, mac address: {}", mac.getMacEntryKey().getValue());
89             Optional<RemoteMcastMacs> operationalMacOptional =
90                     getOperationalState().getRemoteMcastMacs(instanceIdentifier, mac.getKey());
91             McastMacsRemote mcastMacsRemote = TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(), McastMacsRemote.class);
92             setIpAddress(mcastMacsRemote, mac);
93             setLocatorSet(transaction, mcastMacsRemote, mac);
94             setLogicalSwitch(mcastMacsRemote, mac);
95             if (!operationalMacOptional.isPresent()) {
96                 setMac(mcastMacsRemote, mac, operationalMacOptional);
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                 getOperationalState().getDeviceInfo().markKeyAsInTransit(RemoteMcastMacs.class, macKey);
101             } else if (operationalMacOptional.get().getMacEntryUuid() != null) {
102                 UUID macEntryUUID = new UUID(operationalMacOptional.get().getMacEntryUuid().getValue());
103                 McastMacsRemote extraMac = TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(),
104                                 McastMacsRemote.class, null);
105                 extraMac.getUuidColumn().setData(macEntryUUID);
106                 LOG.trace("execute: update RemoteMcastMac entry: {}", mcastMacsRemote);
107                 transaction.add(op.update(mcastMacsRemote)
108                         .where(extraMac.getUuidColumn().getSchema().opEqual(macEntryUUID))
109                         .build());
110                 transaction.add(op.comment("McastMacRemote: Updating " + macEntryUUID));
111             } else {
112                 LOG.warn("Unable to update remoteMcastMacs {} because uuid not found in the operational store",
113                                 mac.getMacEntryKey().getValue());
114             }
115     }
116
117     private void setLogicalSwitch(McastMacsRemote mcastMacsRemote, RemoteMcastMacs inputMac) {
118         if (inputMac.getLogicalSwitchRef() != null) {
119             @SuppressWarnings("unchecked")
120             InstanceIdentifier<LogicalSwitches> lswitchIid = (InstanceIdentifier<LogicalSwitches>) inputMac.getLogicalSwitchRef().getValue();
121             Optional<LogicalSwitches> operationalSwitchOptional =
122                     getOperationalState().getLogicalSwitches(lswitchIid);
123             if (operationalSwitchOptional.isPresent()) {
124                 Uuid logicalSwitchUuid = operationalSwitchOptional.get().getLogicalSwitchUuid();
125                 UUID logicalSwitchUUID = new UUID(logicalSwitchUuid.getValue());
126                 mcastMacsRemote.setLogicalSwitch(logicalSwitchUUID);
127             } else {
128                 mcastMacsRemote.setLogicalSwitch(TransactUtils.getLogicalSwitchUUID(lswitchIid));
129             }
130         }
131     }
132
133     private void setLocatorSet(TransactionBuilder transaction, McastMacsRemote mcastMacsRemote, RemoteMcastMacs inputMac) {
134         if (inputMac.getLocatorSet() != null && !inputMac.getLocatorSet().isEmpty()) {
135             UUID locatorSetUuid = TransactUtils.createPhysicalLocatorSet(getOperationalState(), transaction, inputMac.getLocatorSet());
136             mcastMacsRemote.setLocatorSet(locatorSetUuid);
137         }
138     }
139
140     private void setIpAddress(McastMacsRemote mcastMacsRemote, RemoteMcastMacs inputMac) {
141         if (inputMac.getIpaddr() != null) {
142             mcastMacsRemote.setIpAddress(inputMac.getIpaddr().getIpv4Address().getValue());
143         }
144     }
145
146     private void setMac(McastMacsRemote mcastMacsRemote, RemoteMcastMacs inputMac,
147             Optional<RemoteMcastMacs> inputSwitchOptional) {
148         if (inputMac.getMacEntryKey() != null) {
149             if (inputMac.getMacEntryKey().equals(HwvtepSouthboundConstants.UNKNOWN_DST_MAC)) {
150                 mcastMacsRemote.setMac(HwvtepSouthboundConstants.UNKNOWN_DST_STRING);
151             } else {
152                 mcastMacsRemote.setMac(inputMac.getMacEntryKey().getValue());
153             }
154         } else if (inputSwitchOptional.isPresent() && inputSwitchOptional.get().getMacEntryKey() != null) {
155             mcastMacsRemote.setMac(inputSwitchOptional.get().getMacEntryKey().getValue());
156         }
157     }
158
159     @Override
160     protected List<RemoteMcastMacs> getData(HwvtepGlobalAugmentation augmentation) {
161         return augmentation.getRemoteMcastMacs();
162     }
163
164     @Override
165     protected boolean areEqual(RemoteMcastMacs a, RemoteMcastMacs b) {
166         return a.getKey().equals(b.getKey()) && Objects.equals(a.getLocatorSet(), b.getLocatorSet());
167     }
168
169     static class McastMacUnMetDependencyGetter extends UnMetDependencyGetter<RemoteMcastMacs> {
170
171         public List<InstanceIdentifier<?>> getLogicalSwitchDependencies(RemoteMcastMacs data) {
172             if (data == null) {
173                 return Collections.emptyList();
174             }
175             return Collections.singletonList(data.getLogicalSwitchRef().getValue());
176         }
177
178         public List<InstanceIdentifier<?>> getTerminationPointDependencies(RemoteMcastMacs data) {
179             if (data == null || HwvtepSouthboundUtil.isEmpty(data.getLocatorSet())) {
180                 return Collections.emptyList();
181             }
182             List<InstanceIdentifier<?>> locators = new ArrayList<>();
183             for (LocatorSet locator: data.getLocatorSet()) {
184                 locators.add(locator.getLocatorRef().getValue());
185             }
186             return locators;
187         }
188     }
189 }