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
9 package org.opendaylight.ovsdb.hwvtepsouthbound.transact;
11 import static org.opendaylight.ovsdb.lib.operations.Operations.op;
13 import com.google.common.collect.Lists;
14 import java.util.ArrayList;
15 import java.util.Collection;
16 import java.util.Collections;
17 import java.util.HashMap;
18 import java.util.List;
20 import java.util.Map.Entry;
21 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
22 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
23 import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepDeviceInfo;
24 import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundUtil;
25 import org.opendaylight.ovsdb.lib.notation.UUID;
26 import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
27 import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
28 import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalPort;
29 import org.opendaylight.ovsdb.utils.mdsal.utils.TransactionType;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalPortAugmentation;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitches;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical.port.attributes.VlanBindings;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical.port.attributes.VlanBindingsKey;
34 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
35 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
36 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
37 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
38 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
42 public class PhysicalPortUpdateCommand extends AbstractTransactCommand {
43 private static final Logger LOG = LoggerFactory.getLogger(PhysicalPortUpdateCommand.class);
44 private static final VlanBindingsUnMetDependencyGetter DEPENDENCY_GETTER = new VlanBindingsUnMetDependencyGetter();
46 public PhysicalPortUpdateCommand(HwvtepOperationalState state,
47 Collection<DataTreeModification<Node>> changes) {
48 super(state, changes);
52 public void execute(TransactionBuilder transaction) {
53 Map<InstanceIdentifier<Node>, List<HwvtepPhysicalPortAugmentation>> createds =
54 extractCreated(getChanges(),HwvtepPhysicalPortAugmentation.class);
55 if (!createds.isEmpty()) {
56 for (Entry<InstanceIdentifier<Node>, List<HwvtepPhysicalPortAugmentation>> created:
57 createds.entrySet()) {
58 updatePhysicalPort(transaction, created.getKey(), created.getValue());
61 Map<InstanceIdentifier<Node>, List<HwvtepPhysicalPortAugmentation>> updateds =
62 extractUpdatedPorts(getChanges(), HwvtepPhysicalPortAugmentation.class);
63 if (!updateds.isEmpty()) {
64 for (Entry<InstanceIdentifier<Node>, List<HwvtepPhysicalPortAugmentation>> updated:
65 updateds.entrySet()) {
66 updatePhysicalPort(transaction, updated.getKey(), updated.getValue());
71 public void updatePhysicalPort(final TransactionBuilder transaction,
72 final InstanceIdentifier<Node> psNodeiid,
73 final List<HwvtepPhysicalPortAugmentation> listPort) {
74 //Get physical switch which the port belong to: in operation DS or new created
75 for (HwvtepPhysicalPortAugmentation port : listPort) {
76 LOG.debug("Creating a physical port named: {}", port.getHwvtepNodeName().getValue());
77 HwvtepDeviceInfo.DeviceData deviceOperdata = getDeviceInfo().getDeviceOperData(TerminationPoint.class,
78 getTpIid(psNodeiid, port.getHwvtepNodeName().getValue()));
79 if (deviceOperdata == null) {
80 //create a physical port always happens from device
81 LOG.error("Physical port {} not present in oper datastore", port.getHwvtepNodeName().getValue());
83 PhysicalPort physicalPort = TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(),
85 physicalPort.setName(port.getHwvtepNodeName().getValue());
86 setVlanBindings(psNodeiid, physicalPort, port, transaction);
87 setDescription(physicalPort, port);
88 String existingPhysicalPortName = port.getHwvtepNodeName().getValue();
89 PhysicalPort extraPhyscialPort =
90 TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(), PhysicalPort.class);
91 extraPhyscialPort.setName("");
92 LOG.trace("execute: updating physical port: {}", physicalPort);
93 transaction.add(op.update(physicalPort)
94 .where(extraPhyscialPort.getNameColumn().getSchema().opEqual(existingPhysicalPortName))
96 transaction.add(op.comment("Physical Port: Updating " + existingPhysicalPortName));
97 updateControllerTxHistory(TransactionType.UPDATE, physicalPort);
102 private void setDescription(PhysicalPort physicalPort, HwvtepPhysicalPortAugmentation inputPhysicalPort) {
103 if (inputPhysicalPort.getHwvtepNodeDescription() != null) {
104 physicalPort.setDescription(inputPhysicalPort.getHwvtepNodeDescription());
108 private void setVlanBindings(final InstanceIdentifier<Node> psNodeiid,
109 final PhysicalPort physicalPort,
110 final HwvtepPhysicalPortAugmentation inputPhysicalPort,
111 final TransactionBuilder transaction) {
112 if (inputPhysicalPort.getVlanBindings() != null) {
113 //get UUID by LogicalSwitchRef
114 Map<Long, UUID> bindingMap = new HashMap<>();
115 for (VlanBindings vlanBinding: inputPhysicalPort.getVlanBindings()) {
116 InstanceIdentifier<VlanBindings> vlanIid = getVlanBindingIid(psNodeiid, physicalPort, vlanBinding);
117 @SuppressWarnings("unchecked")
118 InstanceIdentifier<LogicalSwitches> lswitchIid =
119 (InstanceIdentifier<LogicalSwitches>) vlanBinding.getLogicalSwitchRef().getValue();
121 Map inTransitDependencies = DEPENDENCY_GETTER.getInTransitDependencies(
122 getOperationalState(), vlanBinding);
123 Map configDependencies = DEPENDENCY_GETTER.getUnMetConfigDependencies(
124 getOperationalState(), vlanBinding);
126 if (!HwvtepSouthboundUtil.isEmptyMap(configDependencies)) {
127 createConfigWaitJob(psNodeiid, inputPhysicalPort,
128 vlanBinding, configDependencies, vlanIid);
131 if (!HwvtepSouthboundUtil.isEmptyMap(inTransitDependencies)) {
132 createOperWaitingJob(psNodeiid, inputPhysicalPort,
133 vlanBinding, inTransitDependencies, vlanIid);
137 bindingMap.put(vlanBinding.getVlanIdKey().getValue().longValue(),
138 TransactUtils.getLogicalSwitchUUID(transaction, getOperationalState(), lswitchIid));
140 physicalPort.setVlanBindings(bindingMap);
144 private void createOperWaitingJob(final InstanceIdentifier<Node> psNodeiid,
145 final HwvtepPhysicalPortAugmentation inputPhysicalPort,
146 final VlanBindings vlanBinding,
147 final Map inTransitDependencies,
148 final InstanceIdentifier<VlanBindings> vlanIid) {
150 DependentJob<VlanBindings> opWaitingJob = new DependentJob.OpWaitingJob<VlanBindings>(
151 vlanIid, vlanBinding, inTransitDependencies) {
153 public void onDependencyResolved(final HwvtepOperationalState operationalState,
154 final TransactionBuilder transactionBuilder) {
155 hwvtepOperationalState = operationalState;
156 deviceTransaction = transactionBuilder;
157 updatePhysicalPort(transactionBuilder, psNodeiid, Lists.newArrayList(inputPhysicalPort));
160 getDeviceInfo().addJobToQueue(opWaitingJob);
163 private void createConfigWaitJob(final InstanceIdentifier<Node> psNodeiid,
164 final HwvtepPhysicalPortAugmentation inputPhysicalPort,
165 final VlanBindings vlanBinding,
166 final Map configDependencies,
167 final InstanceIdentifier<VlanBindings> vlanIid) {
169 DependentJob<VlanBindings> configWaitingJob = new DependentJob.ConfigWaitingJob<VlanBindings>(
170 vlanIid, vlanBinding, configDependencies) {
172 public void onDependencyResolved(final HwvtepOperationalState operationalState,
173 final TransactionBuilder transactionBuilder) {
174 hwvtepOperationalState = operationalState;
175 deviceTransaction = transactionBuilder;
176 updatePhysicalPort(transactionBuilder, psNodeiid, Lists.newArrayList(inputPhysicalPort));
179 getDeviceInfo().addJobToQueue(configWaitingJob);
182 private InstanceIdentifier<TerminationPoint> getTpIid(final InstanceIdentifier<Node> psNodeiid,
183 final String portName) {
184 return psNodeiid.child(
185 TerminationPoint.class, new TerminationPointKey(new TpId(portName)));
188 private InstanceIdentifier<VlanBindings> getVlanBindingIid(
189 final InstanceIdentifier<Node> psNodeiid,
190 final PhysicalPort physicalPort,
191 final VlanBindings vlanBinding) {
193 return psNodeiid.child(
194 TerminationPoint.class, new TerminationPointKey(new TpId(physicalPort.getName())))
195 .augmentation(HwvtepPhysicalPortAugmentation.class)
196 .child(VlanBindings.class, new VlanBindingsKey(vlanBinding.getVlanIdKey()));
199 static class VlanBindingsUnMetDependencyGetter extends UnMetDependencyGetter<VlanBindings> {
202 public List<InstanceIdentifier<?>> getLogicalSwitchDependencies(VlanBindings data) {
204 return Collections.emptyList();
206 return Collections.singletonList(data.getLogicalSwitchRef().getValue());
210 public List<InstanceIdentifier<?>> getTerminationPointDependencies(VlanBindings data) {
211 return Collections.emptyList();
215 private Map<InstanceIdentifier<Node>, List<HwvtepPhysicalPortAugmentation>> extractCreated(
216 Collection<DataTreeModification<Node>> changes, Class<HwvtepPhysicalPortAugmentation> class1) {
217 Map<InstanceIdentifier<Node>, List<HwvtepPhysicalPortAugmentation>> result = new HashMap<>();
218 if (changes != null && !changes.isEmpty()) {
219 for (DataTreeModification<Node> change : changes) {
220 final InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
221 final DataObjectModification<Node> mod = change.getRootNode();
222 Node created = TransactUtils.getCreated(mod);
223 if (created != null) {
224 List<HwvtepPhysicalPortAugmentation> portListUpdated = new ArrayList<>();
225 if (created.getTerminationPoint() != null) {
226 for (TerminationPoint tp : created.getTerminationPoint()) {
227 HwvtepPhysicalPortAugmentation hppAugmentation =
228 tp.augmentation(HwvtepPhysicalPortAugmentation.class);
229 if (hppAugmentation != null) {
230 portListUpdated.add(hppAugmentation);
234 result.put(key, portListUpdated);
241 private Map<InstanceIdentifier<Node>, List<HwvtepPhysicalPortAugmentation>> extractUpdatedPorts(
242 Collection<DataTreeModification<Node>> changes, Class<HwvtepPhysicalPortAugmentation> class1) {
243 Map<InstanceIdentifier<Node>, List<HwvtepPhysicalPortAugmentation>> result = new HashMap<>();
244 if (changes != null && !changes.isEmpty()) {
245 for (DataTreeModification<Node> change : changes) {
246 final InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
247 final DataObjectModification<Node> mod = change.getRootNode();
248 Node updated = TransactUtils.getUpdated(mod);
249 Node before = mod.getDataBefore();
250 if (updated != null && before != null) {
251 List<HwvtepPhysicalPortAugmentation> portListUpdated = new ArrayList<>();
252 List<HwvtepPhysicalPortAugmentation> portListBefore = new ArrayList<>();
253 if (updated.getTerminationPoint() != null) {
254 for (TerminationPoint tp : updated.getTerminationPoint()) {
255 HwvtepPhysicalPortAugmentation hppAugmentation =
256 tp.augmentation(HwvtepPhysicalPortAugmentation.class);
257 if (hppAugmentation != null) {
258 portListUpdated.add(hppAugmentation);
262 if (before.getTerminationPoint() != null) {
263 for (TerminationPoint tp : before.getTerminationPoint()) {
264 HwvtepPhysicalPortAugmentation hppAugmentation =
265 tp.augmentation(HwvtepPhysicalPortAugmentation.class);
266 if (hppAugmentation != null) {
267 portListBefore.add(hppAugmentation);
271 portListUpdated.removeAll(portListBefore);
272 result.put(key, portListUpdated);