Fix findbugs violations in hwvtepsouthbound-impl
[ovsdb.git] / hwvtepsouthbound / hwvtepsouthbound-impl / src / main / java / org / opendaylight / ovsdb / hwvtepsouthbound / transact / TransactUtils.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 package org.opendaylight.ovsdb.hwvtepsouthbound.transact;
9
10 import static org.opendaylight.ovsdb.lib.operations.Operations.op;
11
12 import com.google.common.collect.Lists;
13 import java.util.Collection;
14 import java.util.Collections;
15 import java.util.HashMap;
16 import java.util.HashSet;
17 import java.util.List;
18 import java.util.Map;
19 import java.util.Set;
20 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
21 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification.ModificationType;
22 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
23 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
24 import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepDeviceInfo;
25 import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundConstants;
26 import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundMapper;
27 import org.opendaylight.ovsdb.lib.notation.UUID;
28 import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
29 import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
30 import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalLocator;
31 import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalLocatorSet;
32 import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
33 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.EncapsulationTypeVxlanOverIpv4;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepNodeName;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalLocatorAugmentation;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalLocatorAugmentationBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.Acls;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalRouters;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitches;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical.locator.set.attributes.LocatorSet;
42 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
43 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
44 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
45 import org.slf4j.Logger;
46 import org.slf4j.LoggerFactory;
47
48 public final class TransactUtils {
49     private static final Logger LOG = LoggerFactory.getLogger(TransactUtils.class);
50
51     private TransactUtils(){
52     }
53
54     public static Node getCreated(DataObjectModification<Node> mod) {
55         if (mod.getModificationType() == ModificationType.WRITE
56                         && mod.getDataBefore() == null) {
57             return mod.getDataAfter();
58         }
59         return null;
60     }
61
62     public static Node getRemoved(DataObjectModification<Node> mod) {
63         if (mod.getModificationType() == ModificationType.DELETE) {
64             return mod.getDataBefore();
65         }
66         return null;
67     }
68
69     public static Node getUpdated(DataObjectModification<Node> mod) {
70         Node node = null;
71         switch (mod.getModificationType()) {
72             case SUBTREE_MODIFIED:
73                 node = mod.getDataAfter();
74                 break;
75             case WRITE:
76                 if (mod.getDataBefore() != null) {
77                     node = mod.getDataAfter();
78                 }
79                 break;
80             default:
81                 break;
82         }
83         return node;
84     }
85
86     public static Node getOriginal(DataObjectModification<Node> mod) {
87         Node node = null;
88         switch (mod.getModificationType()) {
89             case SUBTREE_MODIFIED:
90             case DELETE:
91                 node = mod.getDataBefore();
92                 break;
93             case WRITE:
94                 if (mod.getDataBefore() !=  null) {
95                     node = mod.getDataBefore();
96                 }
97                 break;
98             default:
99                 break;
100         }
101         return node;
102     }
103
104     //TODO: change this function to be generic
105     public static Map<InstanceIdentifier<Node>, Node> extractCreatedOrUpdatedOrRemoved(
106             Collection<DataTreeModification<Node>> changes, Class<Node> class1) {
107         Map<InstanceIdentifier<Node>, Node> result = new HashMap<>();
108         for (DataTreeModification<Node> change : changes) {
109             final InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
110             final DataObjectModification<Node> mod = change.getRootNode();
111             Node created = getCreated(mod);
112             if (created != null) {
113                 result.put(key, created);
114             }
115             Node updated = getUpdated(mod);
116             if (updated != null) {
117                 result.put(key, updated);
118             }
119             Node deleted = getRemoved(mod);
120             if (deleted != null) {
121                 result.put(key, deleted);
122             }
123         }
124         return result;
125     }
126
127     public static UUID createPhysicalLocatorSet(HwvtepOperationalState hwvtepOperationalState,
128             TransactionBuilder transaction, List<LocatorSet> locatorList) {
129         Set<UUID> locators = new HashSet<>();
130         for (LocatorSet locator: locatorList) {
131             @SuppressWarnings("unchecked")
132             InstanceIdentifier<TerminationPoint> iid =
133                     (InstanceIdentifier<TerminationPoint>) locator.getLocatorRef().getValue();
134             UUID locatorUuid = createPhysicalLocator(transaction, hwvtepOperationalState, iid);
135             if (locatorUuid != null) {
136                 locators.add(locatorUuid);
137             }
138         }
139         PhysicalLocatorSet physicalLocatorSet = TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(),
140                 PhysicalLocatorSet.class);
141         physicalLocatorSet.setLocators(locators);
142         String locatorSetUuid = "PhysicalLocatorSet_" + HwvtepSouthboundMapper.getRandomUUID();
143         transaction.add(op.insert(physicalLocatorSet).withId(locatorSetUuid));
144         return new UUID(locatorSetUuid);
145     }
146
147     public static UUID createPhysicalLocator(TransactionBuilder transaction, HwvtepOperationalState operationalState,
148                                              InstanceIdentifier<TerminationPoint> iid) {
149         UUID locatorUuid = null;
150         HwvtepDeviceInfo.DeviceData deviceData = operationalState.getDeviceInfo().getDeviceOperData(
151                 TerminationPoint.class, iid);
152         if (deviceData != null && deviceData.getUuid() != null) {
153             locatorUuid = deviceData.getUuid();
154             return locatorUuid;
155         }
156         locatorUuid = operationalState.getUUIDFromCurrentTx(TerminationPoint.class, iid);
157         if (locatorUuid != null) {
158             return locatorUuid;
159         }
160         HwvtepPhysicalLocatorAugmentationBuilder builder = new HwvtepPhysicalLocatorAugmentationBuilder();
161         HwvtepPhysicalLocatorAugmentation locatorAugmentation = null;
162         builder.setEncapsulationType(EncapsulationTypeVxlanOverIpv4.class);
163         String tepKey = iid.firstKeyOf(TerminationPoint.class).getTpId().getValue();
164         String ip = tepKey.substring(tepKey.indexOf(":") + 1);
165         builder.setDstIp(new IpAddress(ip.toCharArray()));
166         locatorAugmentation = builder.build();
167         locatorUuid = TransactUtils.createPhysicalLocator(transaction, locatorAugmentation);
168         operationalState.updateCurrentTxData(TerminationPoint.class, iid, locatorUuid);
169         operationalState.getDeviceInfo().markKeyAsInTransit(TerminationPoint.class, iid);
170         return locatorUuid;
171     }
172
173     public static UUID createPhysicalLocator(TransactionBuilder transaction,
174             HwvtepPhysicalLocatorAugmentation inputLocator) {
175         LOG.debug("Creating a physical locator: {}", inputLocator.getDstIp());
176         PhysicalLocator physicalLocator = TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(),
177                 PhysicalLocator.class);
178         setEncapsulationType(physicalLocator, inputLocator);
179         setDstIp(physicalLocator, inputLocator);
180         String locatorUuid = "PhysicalLocator_" + HwvtepSouthboundMapper.getRandomUUID();
181         transaction.add(op.insert(physicalLocator).withId(locatorUuid));
182         return new UUID(locatorUuid);
183     }
184
185     private static void setEncapsulationType(PhysicalLocator physicalLocator,
186             HwvtepPhysicalLocatorAugmentation inputLocator) {
187         if (inputLocator.getEncapsulationType() != null) {
188             String encapType = HwvtepSouthboundConstants.ENCAPS_TYPE_MAP.get(
189                     HwvtepSouthboundMapper.createEncapsulationType(""));
190             physicalLocator.setEncapsulationType(encapType);
191         }
192     }
193
194     private static void setDstIp(PhysicalLocator physicalLocator,
195             HwvtepPhysicalLocatorAugmentation inputLocator) {
196         if (inputLocator.getDstIp() != null) {
197             physicalLocator.setDstIp(inputLocator.getDstIp().getIpv4Address().getValue());
198         }
199     }
200
201     static String sanitizeUUID(HwvtepNodeName hwvtepNodeName) {
202         return sanitizeUUID(hwvtepNodeName.getValue());
203     }
204
205     static String sanitizeUUID(String nodeName) {
206         //ovs is not accepting '-' in the named uuids
207         return nodeName.replaceAll("-", "_");
208     }
209
210     public static String getLogicalSwitchId(LogicalSwitches lswitch) {
211         return HwvtepSouthboundConstants.LOGICALSWITCH_UUID_PREFIX + sanitizeUUID(lswitch.getHwvtepNodeName());
212     }
213
214     public static UUID getLogicalSwitchUUID(InstanceIdentifier<LogicalSwitches> lswitchIid) {
215         return new UUID(HwvtepSouthboundConstants.LOGICALSWITCH_UUID_PREFIX
216                 + sanitizeUUID(lswitchIid.firstKeyOf(LogicalSwitches.class).getHwvtepNodeName()));
217     }
218
219     public static UUID getLogicalSwitchUUID(final TransactionBuilder transaction,
220                                             final HwvtepOperationalState operationalState,
221                                             final InstanceIdentifier<LogicalSwitches> lswitchIid) {
222         HwvtepDeviceInfo hwvtepDeviceInfo = operationalState.getDeviceInfo();
223         HwvtepDeviceInfo.DeviceData lsData = hwvtepDeviceInfo.getDeviceOperData(LogicalSwitches.class, lswitchIid);
224         if (lsData != null) {
225             if (lsData.getUuid() != null) {
226                 return lsData.getUuid();
227             }
228             if (lsData.isInTransitState()) {
229                 return getLogicalSwitchUUID(lswitchIid);
230             }
231             return null;
232         }
233         LogicalSwitchUpdateCommand cmd = new LogicalSwitchUpdateCommand(operationalState, Collections.EMPTY_LIST);
234         MdsalUtils mdsalUtils = new MdsalUtils(operationalState.getDataBroker());
235         LogicalSwitches ls = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, lswitchIid);
236         if (ls != null) {
237             cmd.updateLogicalSwitch(transaction, lswitchIid.firstIdentifierOf(Node.class), Lists.newArrayList(ls));
238         } else {
239             LOG.error("Could not find logical switch in config ds {}", lswitchIid);
240             return null;
241         }
242         return getLogicalSwitchUUID(lswitchIid);
243     }
244
245     public static String getLogicalRouterId(final LogicalRouters lrouter) {
246         return HwvtepSouthboundConstants.LOGICALROUTER_UUID_PREFIX + sanitizeUUID(lrouter.getHwvtepNodeName());
247     }
248
249     public static UUID getAclUUID(final InstanceIdentifier<Acls> aclIid) {
250         return new UUID(HwvtepSouthboundConstants.ACL_UUID_PREFIX
251                 + sanitizeUUID(aclIid.firstKeyOf(Acls.class).getAclName()));
252     }
253 }