Bug 6185 - southbound system tests failing when
[ovsdb.git] / hwvtepsouthbound / hwvtepsouthbound-impl / src / main / java / org / opendaylight / ovsdb / hwvtepsouthbound / transact / UcastMacsLocalUpdateCommand.java
1 /*
2  * Copyright (c) 2015, 2016 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 static org.opendaylight.ovsdb.lib.operations.Operations.op;
12
13 import java.util.Collection;
14 import java.util.HashMap;
15 import java.util.List;
16 import java.util.Map;
17 import java.util.Map.Entry;
18
19 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
20 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
21 import org.opendaylight.ovsdb.lib.notation.UUID;
22 import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
23 import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
24 import org.opendaylight.ovsdb.schema.hardwarevtep.UcastMacsLocal;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepNodeName;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalLocatorAugmentation;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LocalUcastMacs;
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.LogicalSwitchesKey;
32 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
33 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
34 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
37
38 import com.google.common.base.Optional;
39
40 public class UcastMacsLocalUpdateCommand extends AbstractTransactCommand {
41     private static final Logger LOG = LoggerFactory.getLogger(UcastMacsLocalUpdateCommand.class);
42
43     public UcastMacsLocalUpdateCommand(HwvtepOperationalState state,
44             Collection<DataTreeModification<Node>> changes) {
45         super(state, changes);
46     }
47
48     @Override
49     public void execute(TransactionBuilder transaction) {
50         Map<InstanceIdentifier<Node>, List<LocalUcastMacs>> createds =
51                 extractCreated(getChanges(),LocalUcastMacs.class);
52         if (!createds.isEmpty()) {
53             for (Entry<InstanceIdentifier<Node>, List<LocalUcastMacs>> created:
54                 createds.entrySet()) {
55                 updateUcastMacsLocal(transaction,  created.getKey(), created.getValue());
56             }
57         }
58         Map<InstanceIdentifier<Node>, List<LocalUcastMacs>> updateds =
59                 extractUpdated(getChanges(),LocalUcastMacs.class);
60         if (!updateds.isEmpty()) {
61             for (Entry<InstanceIdentifier<Node>, List<LocalUcastMacs>> updated:
62                 updateds.entrySet()) {
63                 updateUcastMacsLocal(transaction,  updated.getKey(), updated.getValue());
64             }
65         }
66     }
67
68     private void updateUcastMacsLocal(TransactionBuilder transaction,
69             InstanceIdentifier<Node> instanceIdentifier, List<LocalUcastMacs> localUcastMacs) {
70         for (LocalUcastMacs localUcastMac: localUcastMacs) {
71             LOG.debug("Creating localUcastMacs, mac address: {}", localUcastMac.getMacEntryKey().getValue());
72             Optional<LocalUcastMacs> operationalMacOptional =
73                     getOperationalState().getLocalUcastMacs(instanceIdentifier, localUcastMac.getKey());
74             UcastMacsLocal ucastMacsLocal = TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(), UcastMacsLocal.class);
75             setIpAddress(ucastMacsLocal, localUcastMac);
76             setLocator(transaction, ucastMacsLocal, localUcastMac);
77             setLogicalSwitch(ucastMacsLocal, localUcastMac);
78             if (!operationalMacOptional.isPresent()) {
79                 setMac(ucastMacsLocal, localUcastMac, operationalMacOptional);
80                 LOG.trace("execute: creating LocalUcastMac entry: {}", ucastMacsLocal);
81                 transaction.add(op.insert(ucastMacsLocal));
82                 transaction.add(op.comment("UcastMacLocal: Creating " + localUcastMac.getMacEntryKey().getValue()));
83             } else if (operationalMacOptional.get().getMacEntryUuid() != null) {
84                 UUID macEntryUUID = new UUID(operationalMacOptional.get().getMacEntryUuid().getValue());
85                 UcastMacsLocal extraMac = TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(),
86                                 UcastMacsLocal.class, null);
87                 extraMac.getUuidColumn().setData(macEntryUUID);
88                 LOG.trace("execute: updating LocalUcastMac entry: {}", ucastMacsLocal);
89                 transaction.add(op.update(ucastMacsLocal)
90                         .where(extraMac.getUuidColumn().getSchema().opEqual(macEntryUUID))
91                         .build());
92                 transaction.add(op.comment("UcastMacLocal: Updating " + macEntryUUID));
93             } else {
94                 LOG.warn("Unable to update localUcastMacs {} because uuid not found in the operational store",
95                                 localUcastMac.getMacEntryKey().getValue());
96             }
97         }
98     }
99
100     private void setLogicalSwitch(UcastMacsLocal ucastMacsLocal, LocalUcastMacs inputMac) {
101         if (inputMac.getLogicalSwitchRef() != null) {
102             @SuppressWarnings("unchecked")
103             InstanceIdentifier<LogicalSwitches> lswitchIid = (InstanceIdentifier<LogicalSwitches>) inputMac.getLogicalSwitchRef().getValue();
104             Optional<LogicalSwitches> operationalSwitchOptional =
105                     getOperationalState().getLogicalSwitches(lswitchIid);
106             if (operationalSwitchOptional.isPresent()) {
107                 Uuid logicalSwitchUuid = operationalSwitchOptional.get().getLogicalSwitchUuid();
108                 UUID logicalSwitchUUID = new UUID(logicalSwitchUuid.getValue());
109                 ucastMacsLocal.setLogicalSwitch(logicalSwitchUUID);
110             } else {
111                 LOG.warn("Create or update localUcastMacs: No logical switch with iid {} found in operational datastore!",
112                         lswitchIid);
113             }
114         }
115     }
116
117     private void setLocator(TransactionBuilder transaction, UcastMacsLocal ucastMacsLocal, LocalUcastMacs inputMac) {
118         //get UUID by locatorRef
119         if (inputMac.getLocatorRef() != null) {
120             UUID locatorUuid = null;
121             @SuppressWarnings("unchecked")
122             InstanceIdentifier<TerminationPoint> iid = (InstanceIdentifier<TerminationPoint>) inputMac.getLocatorRef().getValue();
123             //try to find locator in operational DS
124             Optional<HwvtepPhysicalLocatorAugmentation> operationalLocatorOptional =
125                     getOperationalState().getPhysicalLocatorAugmentation(iid);
126             if (operationalLocatorOptional.isPresent()) {
127                 //if exist, get uuid
128                 HwvtepPhysicalLocatorAugmentation locatorAugmentation = operationalLocatorOptional.get();
129                 locatorUuid = new UUID(locatorAugmentation.getPhysicalLocatorUuid().getValue());
130             } else {
131                 //if no, get it from config DS and create id
132                 Optional<TerminationPoint> configLocatorOptional =
133                         TransactUtils.readNodeFromConfig(getOperationalState().getReadWriteTransaction(), iid);
134                 if (configLocatorOptional.isPresent()) {
135                     HwvtepPhysicalLocatorAugmentation locatorAugmentation =
136                             configLocatorOptional.get().getAugmentation(HwvtepPhysicalLocatorAugmentation.class);
137                     locatorUuid = TransactUtils.createPhysicalLocator(transaction, locatorAugmentation);
138                 } else {
139                     LOG.warn("Create or update localUcastMac: No physical locator found in operational datastore!"
140                             + "Its indentifier is {}", inputMac.getLocatorRef().getValue());
141                 }
142             }
143             if (locatorUuid != null) {
144                 ucastMacsLocal.setLocator(locatorUuid);
145             }
146         }
147     }
148
149     private void setIpAddress(UcastMacsLocal ucastMacsLocal, LocalUcastMacs inputMac) {
150         if (inputMac.getIpaddr() != null) {
151             ucastMacsLocal.setIpAddress(inputMac.getIpaddr().getIpv4Address().getValue());
152         }
153     }
154
155     private void setMac(UcastMacsLocal ucastMacsLocal, LocalUcastMacs inputMac,
156             Optional<LocalUcastMacs> inputSwitchOptional) {
157         if (inputMac.getMacEntryKey() != null) {
158             ucastMacsLocal.setMac(inputMac.getMacEntryKey().getValue());
159         } else if (inputSwitchOptional.isPresent() && inputSwitchOptional.get().getMacEntryKey() != null) {
160             ucastMacsLocal.setMac(inputSwitchOptional.get().getMacEntryKey().getValue());
161         }
162     }
163
164     private Map<InstanceIdentifier<Node>, List<LocalUcastMacs>> extractCreated(
165             Collection<DataTreeModification<Node>> changes, Class<LocalUcastMacs> class1) {
166         Map<InstanceIdentifier<Node>, List<LocalUcastMacs>> result
167             = new HashMap<InstanceIdentifier<Node>, List<LocalUcastMacs>>();
168         if (changes != null && !changes.isEmpty()) {
169             for (DataTreeModification<Node> change : changes) {
170                 final InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
171                 final DataObjectModification<Node> mod = change.getRootNode();
172                 Node created = TransactUtils.getCreated(mod);
173                 if (created != null) {
174                     List<LocalUcastMacs> macListUpdated = null;
175                     HwvtepGlobalAugmentation hgAugmentation = created.getAugmentation(HwvtepGlobalAugmentation.class);
176                     if (hgAugmentation != null) {
177                         macListUpdated = hgAugmentation.getLocalUcastMacs();
178                     }
179                     if (macListUpdated != null) {
180                         result.put(key, macListUpdated);
181                     }
182                 }
183             }
184         }
185         return result;
186     }
187
188     private Map<InstanceIdentifier<Node>, List<LocalUcastMacs>> extractUpdated(
189             Collection<DataTreeModification<Node>> changes, Class<LocalUcastMacs> class1) {
190         Map<InstanceIdentifier<Node>, List<LocalUcastMacs>> result
191             = new HashMap<InstanceIdentifier<Node>, List<LocalUcastMacs>>();
192         if (changes != null && !changes.isEmpty()) {
193             for (DataTreeModification<Node> change : changes) {
194                 final InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
195                 final DataObjectModification<Node> mod = change.getRootNode();
196                 Node updated = TransactUtils.getUpdated(mod);
197                 Node before = mod.getDataBefore();
198                 if (updated != null && before != null) {
199                     List<LocalUcastMacs> macListUpdated = null;
200                     List<LocalUcastMacs> macListBefore = null;
201                     HwvtepGlobalAugmentation hgUpdated = updated.getAugmentation(HwvtepGlobalAugmentation.class);
202                     if (hgUpdated != null) {
203                         macListUpdated = hgUpdated.getLocalUcastMacs();
204                     }
205                     HwvtepGlobalAugmentation hgBefore = before.getAugmentation(HwvtepGlobalAugmentation.class);
206                     if (hgBefore != null) {
207                         macListBefore = hgBefore.getLocalUcastMacs();
208                     }
209                     if (macListUpdated != null) {
210                         if (macListBefore != null) {
211                             macListUpdated.removeAll(macListBefore);
212                         }
213                         result.put(key, macListUpdated);
214                     }
215                 }
216             }
217         }
218         return result;
219     }
220 }