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 java.util.Collection;
14 import java.util.Collections;
15 import java.util.HashMap;
16 import java.util.HashSet;
17 import java.util.List;
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.schema.hardwarevtep.PhysicalLocator;
30 import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalLocatorSet;
31 import org.opendaylight.ovsdb.utils.mdsal.utils.ControllerMdsalUtils;
32 import org.opendaylight.ovsdb.utils.mdsal.utils.TransactionType;
33 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressBuilder;
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;
48 public final class TransactUtils {
49 private static final Logger LOG = LoggerFactory.getLogger(TransactUtils.class);
51 private TransactUtils(){
54 public static Node getCreated(final DataObjectModification<Node> mod) {
55 if (mod.getModificationType() == ModificationType.WRITE
56 && mod.getDataBefore() == null) {
57 return mod.getDataAfter();
62 public static Node getRemoved(final DataObjectModification<Node> mod) {
63 if (mod.getModificationType() == ModificationType.DELETE) {
64 return mod.getDataBefore();
69 public static Node getUpdated(final DataObjectModification<Node> mod) {
71 switch (mod.getModificationType()) {
72 case SUBTREE_MODIFIED:
73 node = mod.getDataAfter();
76 if (mod.getDataBefore() != null) {
77 node = mod.getDataAfter();
86 public static Node getOriginal(final DataObjectModification<Node> mod) {
88 switch (mod.getModificationType()) {
89 case SUBTREE_MODIFIED:
91 node = mod.getDataBefore();
94 if (mod.getDataBefore() != null) {
95 node = mod.getDataBefore();
104 //TODO: change this function to be generic
105 public static Map<InstanceIdentifier<Node>, Node> extractCreatedOrUpdatedOrRemoved(
106 final Collection<DataTreeModification<Node>> changes, final 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);
115 Node updated = getUpdated(mod);
116 if (updated != null) {
117 result.put(key, updated);
119 Node deleted = getRemoved(mod);
120 if (deleted != null) {
121 result.put(key, deleted);
127 public static UUID createPhysicalLocatorSet(final HwvtepOperationalState hwvtepOperationalState,
128 final TransactionBuilder transaction, final List<LocatorSet> locatorList) {
129 Set<UUID> locators = new HashSet<>();
130 Set<String> locatorsInfo = new HashSet<>();
131 for (LocatorSet locator: locatorList) {
132 @SuppressWarnings("unchecked")
133 InstanceIdentifier<TerminationPoint> iid =
134 (InstanceIdentifier<TerminationPoint>) locator.getLocatorRef().getValue();
135 UUID locatorUuid = createPhysicalLocator(transaction, hwvtepOperationalState, iid);
136 if (locatorUuid != null) {
137 locators.add(locatorUuid);
138 addLocatorToTransactionHistory(hwvtepOperationalState, locatorsInfo, iid);
141 PhysicalLocatorSet physicalLocatorSet = transaction.getTypedRowWrapper(PhysicalLocatorSet.class);
142 physicalLocatorSet.setLocators(locators);
143 String locatorSetUuid = "PhysicalLocatorSet_" + HwvtepSouthboundMapper.getRandomUUID();
144 transaction.add(op.insert(physicalLocatorSet).withId(locatorSetUuid));
145 hwvtepOperationalState.getDeviceInfo().addToControllerTx(TransactionType.ADD,
146 new StringBuilder(physicalLocatorSet.toString()).append(" Uuid ").append(locatorSetUuid)
147 .append(" ").append(locatorsInfo.toString()));
148 return new UUID(locatorSetUuid);
151 public static UUID createPhysicalLocator(final TransactionBuilder transaction,
152 final HwvtepOperationalState operationalState,
153 final InstanceIdentifier<TerminationPoint> iid) {
154 UUID locatorUuid = null;
155 HwvtepDeviceInfo.DeviceData deviceData = operationalState.getDeviceInfo().getDeviceOperData(
156 TerminationPoint.class, iid);
157 if (deviceData != null && deviceData.getUuid() != null) {
158 locatorUuid = deviceData.getUuid();
161 locatorUuid = operationalState.getUUIDFromCurrentTx(TerminationPoint.class, iid);
162 if (locatorUuid != null) {
165 HwvtepPhysicalLocatorAugmentationBuilder builder = new HwvtepPhysicalLocatorAugmentationBuilder();
166 HwvtepPhysicalLocatorAugmentation locatorAugmentation = null;
167 builder.setEncapsulationType(EncapsulationTypeVxlanOverIpv4.class);
168 String tepKey = iid.firstKeyOf(TerminationPoint.class).getTpId().getValue();
169 String ip = tepKey.substring(tepKey.indexOf(":") + 1);
170 builder.setDstIp(IpAddressBuilder.getDefaultInstance(ip));
171 locatorAugmentation = builder.build();
172 locatorUuid = TransactUtils.createPhysicalLocator(transaction, locatorAugmentation, operationalState);
173 operationalState.updateCurrentTxData(TerminationPoint.class, iid, locatorUuid);
174 operationalState.getDeviceInfo().markKeyAsInTransit(TerminationPoint.class, iid);
178 public static UUID createPhysicalLocator(final TransactionBuilder transaction,
179 final HwvtepPhysicalLocatorAugmentation inputLocator,
180 final HwvtepOperationalState hwvtepOperationalState) {
181 LOG.debug("Creating a physical locator: {}", inputLocator.getDstIp());
182 PhysicalLocator physicalLocator = transaction.getTypedRowWrapper(PhysicalLocator.class);
183 setEncapsulationType(physicalLocator, inputLocator);
184 setDstIp(physicalLocator, inputLocator);
185 String locatorUuid = "PhysicalLocator_" + HwvtepSouthboundMapper.getRandomUUID();
186 transaction.add(op.insert(physicalLocator).withId(locatorUuid));
187 hwvtepOperationalState.getDeviceInfo().addToControllerTx(TransactionType.ADD,
188 new StringBuilder(physicalLocator.toString()).append(" Uuid ").append(locatorUuid));
189 return new UUID(locatorUuid);
192 private static void setEncapsulationType(final PhysicalLocator physicalLocator,
193 final HwvtepPhysicalLocatorAugmentation inputLocator) {
194 if (inputLocator.getEncapsulationType() != null) {
195 String encapType = HwvtepSouthboundConstants.ENCAPS_TYPE_MAP.get(
196 HwvtepSouthboundMapper.createEncapsulationType(""));
197 physicalLocator.setEncapsulationType(encapType);
201 private static void setDstIp(final PhysicalLocator physicalLocator,
202 final HwvtepPhysicalLocatorAugmentation inputLocator) {
203 if (inputLocator.getDstIp() != null) {
204 physicalLocator.setDstIp(inputLocator.getDstIp().getIpv4Address().getValue());
208 static String sanitizeUUID(final HwvtepNodeName hwvtepNodeName) {
209 return sanitizeUUID(hwvtepNodeName.getValue());
212 static String sanitizeUUID(final String nodeName) {
213 //ovs is not accepting '-' in the named uuids
214 return nodeName.replaceAll("-", "_");
217 public static String getLogicalSwitchId(final LogicalSwitches lswitch) {
218 return HwvtepSouthboundConstants.LOGICALSWITCH_UUID_PREFIX + sanitizeUUID(lswitch.getHwvtepNodeName());
221 public static UUID getLogicalSwitchUUID(final InstanceIdentifier<LogicalSwitches> lswitchIid) {
222 return new UUID(HwvtepSouthboundConstants.LOGICALSWITCH_UUID_PREFIX
223 + sanitizeUUID(lswitchIid.firstKeyOf(LogicalSwitches.class).getHwvtepNodeName()));
226 public static UUID getLogicalSwitchUUID(final TransactionBuilder transaction,
227 final HwvtepOperationalState operationalState,
228 final InstanceIdentifier<LogicalSwitches> lswitchIid) {
229 HwvtepDeviceInfo hwvtepDeviceInfo = operationalState.getDeviceInfo();
230 HwvtepDeviceInfo.DeviceData lsData = hwvtepDeviceInfo.getDeviceOperData(LogicalSwitches.class, lswitchIid);
231 if (lsData != null) {
232 if (lsData.getUuid() != null) {
233 return lsData.getUuid();
235 if (lsData.isInTransitState()) {
236 return getLogicalSwitchUUID(lswitchIid);
240 LogicalSwitchUpdateCommand cmd = new LogicalSwitchUpdateCommand(operationalState, Collections.emptyList());
241 ControllerMdsalUtils mdsalUtils = new ControllerMdsalUtils(operationalState.getDataBroker());
242 LogicalSwitches ls = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, lswitchIid);
244 cmd.updateLogicalSwitch(transaction, lswitchIid.firstIdentifierOf(Node.class), Lists.newArrayList(ls));
246 LOG.error("Could not find logical switch in config ds {}", lswitchIid);
249 return getLogicalSwitchUUID(lswitchIid);
252 public static String getLogicalRouterId(final LogicalRouters lrouter) {
253 return HwvtepSouthboundConstants.LOGICALROUTER_UUID_PREFIX + sanitizeUUID(lrouter.getHwvtepNodeName());
256 public static UUID getAclUUID(final InstanceIdentifier<Acls> aclIid) {
257 return new UUID(HwvtepSouthboundConstants.ACL_UUID_PREFIX
258 + sanitizeUUID(aclIid.firstKeyOf(Acls.class).getAclName()));
261 @SuppressWarnings("checkstyle:IllegalCatch")
262 private static void addLocatorToTransactionHistory(final HwvtepOperationalState hwvtepOperationalState,
263 final Set<String> locatorsInfo, final InstanceIdentifier<TerminationPoint> iid) {
265 HwvtepDeviceInfo.DeviceData deviceData = hwvtepOperationalState.getDeviceInfo().getDeviceOperData(
266 TerminationPoint.class, iid);
267 if (deviceData != null) {
268 Object data = deviceData.getData();
269 if (data instanceof PhysicalLocator) {
270 PhysicalLocator locator = (PhysicalLocator) data;
271 locatorsInfo.add(new StringBuilder(locator.getUuid().toString()).append(" ")
272 .append(locator.getDstIpColumn().getData()).toString());
274 LOG.debug("Ignoring unknown data {}", data);
277 } catch (Exception exp) {
278 LOG.warn("Failed to add to Transaction History", exp);