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 java.util.ArrayList;
14 import java.util.Collection;
15 import java.util.Collections;
16 import java.util.HashMap;
17 import java.util.List;
19 import java.util.Map.Entry;
21 import com.google.common.collect.Lists;
22 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
23 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
24 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
25 import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepDeviceInfo;
26 import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundMapper;
27 import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundUtil;
28 import org.opendaylight.ovsdb.lib.notation.Mutator;
29 import org.opendaylight.ovsdb.lib.notation.UUID;
30 import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
31 import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
32 import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalPort;
33 import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalSwitch;
34 import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalPortAugmentation;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.PhysicalSwitchAugmentation;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitches;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical.port.attributes.VlanBindings;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical.port.attributes.VlanBindingsKey;
40 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
41 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
42 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
43 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
44 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
45 import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
46 import org.slf4j.Logger;
47 import org.slf4j.LoggerFactory;
49 import com.google.common.base.Optional;
51 public class PhysicalPortUpdateCommand extends AbstractTransactCommand {
52 private static final Logger LOG = LoggerFactory.getLogger(PhysicalPortUpdateCommand.class);
53 private static final VlanBindingsUnMetDependencyGetter DEPENDENCY_GETTER = new VlanBindingsUnMetDependencyGetter();
55 public PhysicalPortUpdateCommand(HwvtepOperationalState state,
56 Collection<DataTreeModification<Node>> changes) {
57 super(state, changes);
61 public void execute(TransactionBuilder transaction) {
62 Map<InstanceIdentifier<Node>, List<HwvtepPhysicalPortAugmentation>> createds =
63 extractCreated(getChanges(),HwvtepPhysicalPortAugmentation.class);
64 Map<InstanceIdentifier<Node>, PhysicalSwitchAugmentation> createdPhysicalSwitches =
65 extractCreatedPhyscialSwitch(getChanges(),PhysicalSwitchAugmentation.class);
66 if (!createds.isEmpty()) {
67 for (Entry<InstanceIdentifier<Node>, List<HwvtepPhysicalPortAugmentation>> created:
68 createds.entrySet()) {
69 updatePhysicalPort(transaction, created.getKey(), created.getValue());
72 Map<InstanceIdentifier<Node>, List<HwvtepPhysicalPortAugmentation>> updateds =
73 extractUpdatedPorts(getChanges(), HwvtepPhysicalPortAugmentation.class);
74 if (!updateds.isEmpty()) {
75 for (Entry<InstanceIdentifier<Node>, List<HwvtepPhysicalPortAugmentation>> updated:
76 updateds.entrySet()) {
77 updatePhysicalPort(transaction, updated.getKey(), updated.getValue());
82 public void updatePhysicalPort(final TransactionBuilder transaction,
83 final InstanceIdentifier<Node> psNodeiid,
84 final List<HwvtepPhysicalPortAugmentation> listPort) {
85 //Get physical switch which the port belong to: in operation DS or new created
86 for (HwvtepPhysicalPortAugmentation port : listPort) {
87 LOG.debug("Creating a physical port named: {}", port.getHwvtepNodeName().getValue());
88 HwvtepDeviceInfo.DeviceData deviceOperdata = getDeviceInfo().getDeviceOperData(TerminationPoint.class,
89 getTpIid(psNodeiid, port.getHwvtepNodeName().getValue()));
90 if (deviceOperdata == null) {
91 //create a physical port always happens from device
92 LOG.error("Physical port {} not present in oper datastore", port.getHwvtepNodeName().getValue());
94 PhysicalPort physicalPort = TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(),
96 physicalPort.setName(port.getHwvtepNodeName().getValue());
97 setVlanBindings(psNodeiid, physicalPort, port, transaction);
98 setDescription(physicalPort, port);
99 String existingPhysicalPortName = port.getHwvtepNodeName().getValue();
100 PhysicalPort extraPhyscialPort =
101 TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(), PhysicalPort.class);
102 extraPhyscialPort.setName("");
103 LOG.trace("execute: updating physical port: {}", physicalPort);
104 transaction.add(op.update(physicalPort)
105 .where(extraPhyscialPort.getNameColumn().getSchema().opEqual(existingPhysicalPortName))
107 transaction.add(op.comment("Physical Port: Updating " + existingPhysicalPortName));
112 private PhysicalSwitchAugmentation getPhysicalSwitchBelong(InstanceIdentifier<Node> psNodeiid,
113 Map<InstanceIdentifier<Node>, PhysicalSwitchAugmentation> createdPhysicalSwitches) {
114 Optional<PhysicalSwitchAugmentation> physicalSwitchOptional =
115 getOperationalState().getPhysicalSwitchAugmentation(psNodeiid);
116 PhysicalSwitchAugmentation physicalSwitchAugmentation = null;
117 if (physicalSwitchOptional.isPresent()) {
118 physicalSwitchAugmentation = physicalSwitchOptional.get();
120 physicalSwitchAugmentation = createdPhysicalSwitches.get(psNodeiid);
122 return physicalSwitchAugmentation;
125 private void setName(PhysicalPort physicalPort, HwvtepPhysicalPortAugmentation inputPhysicalPort,
126 Optional<HwvtepPhysicalPortAugmentation> operationalLogicalSwitchOptional) {
127 if (inputPhysicalPort.getHwvtepNodeName() != null) {
128 physicalPort.setName(inputPhysicalPort.getHwvtepNodeName().getValue());
129 } else if (operationalLogicalSwitchOptional.isPresent()
130 && operationalLogicalSwitchOptional.get().getHwvtepNodeName() != null) {
131 physicalPort.setName(operationalLogicalSwitchOptional.get().getHwvtepNodeName().getValue());
135 private void setDescription(PhysicalPort physicalPort, HwvtepPhysicalPortAugmentation inputPhysicalPort) {
136 if (inputPhysicalPort.getHwvtepNodeDescription() != null) {
137 physicalPort.setDescription(inputPhysicalPort.getHwvtepNodeDescription());
141 private void setVlanBindings(final InstanceIdentifier<Node> psNodeiid,
142 final PhysicalPort physicalPort,
143 final HwvtepPhysicalPortAugmentation inputPhysicalPort,
144 final TransactionBuilder transaction) {
145 if (inputPhysicalPort.getVlanBindings() != null) {
146 //get UUID by LogicalSwitchRef
147 Map<Long, UUID> bindingMap = new HashMap<>();
148 for (VlanBindings vlanBinding: inputPhysicalPort.getVlanBindings()) {
149 InstanceIdentifier<VlanBindings> vlanIid = getVlanBindingIid(psNodeiid, physicalPort, vlanBinding);
150 @SuppressWarnings("unchecked")
151 InstanceIdentifier<LogicalSwitches> lswitchIid =
152 (InstanceIdentifier<LogicalSwitches>) vlanBinding.getLogicalSwitchRef().getValue();
154 Map inTransitDependencies = DEPENDENCY_GETTER.getInTransitDependencies(
155 getOperationalState(), vlanBinding);
156 Map configDependencies = DEPENDENCY_GETTER.getUnMetConfigDependencies(
157 getOperationalState(), vlanBinding);
159 if (!HwvtepSouthboundUtil.isEmptyMap(configDependencies)) {
160 createConfigWaitJob(psNodeiid, inputPhysicalPort,
161 vlanBinding, configDependencies, vlanIid);
164 if (!HwvtepSouthboundUtil.isEmptyMap(inTransitDependencies)) {
165 createOperWaitingJob(psNodeiid, inputPhysicalPort,
166 vlanBinding, inTransitDependencies, vlanIid);
170 bindingMap.put(vlanBinding.getVlanIdKey().getValue().longValue(),
171 TransactUtils.getLogicalSwitchUUID(transaction, getOperationalState(), lswitchIid));
173 physicalPort.setVlanBindings(bindingMap);
177 private void createOperWaitingJob(final InstanceIdentifier<Node> psNodeiid,
178 final HwvtepPhysicalPortAugmentation inputPhysicalPort,
179 final VlanBindings vlanBinding,
180 final Map inTransitDependencies,
181 final InstanceIdentifier<VlanBindings> vlanIid) {
183 DependentJob<VlanBindings> opWaitingJob = new DependentJob.OpWaitingJob(
184 vlanIid, vlanBinding, inTransitDependencies) {
186 public void onDependencyResolved(final HwvtepOperationalState operationalState,
187 final TransactionBuilder transactionBuilder) {
188 PhysicalPortUpdateCommand.this.threadLocalOperationalState.set(operationalState);
189 PhysicalPortUpdateCommand.this.threadLocalDeviceTransaction.set(transactionBuilder);
190 updatePhysicalPort(transactionBuilder, psNodeiid, Lists.newArrayList(inputPhysicalPort));
193 getDeviceInfo().addJobToQueue(opWaitingJob);
196 private void createConfigWaitJob(final InstanceIdentifier<Node> psNodeiid,
197 final HwvtepPhysicalPortAugmentation inputPhysicalPort,
198 final VlanBindings vlanBinding,
199 final Map configDependencies,
200 final InstanceIdentifier<VlanBindings> vlanIid) {
202 DependentJob<VlanBindings> configWaitingJob = new DependentJob.ConfigWaitingJob(
203 vlanIid, vlanBinding, configDependencies) {
205 public void onDependencyResolved(final HwvtepOperationalState operationalState,
206 final TransactionBuilder transactionBuilder) {
207 PhysicalPortUpdateCommand.this.threadLocalOperationalState.set(operationalState);
208 PhysicalPortUpdateCommand.this.threadLocalDeviceTransaction.set(transactionBuilder);
209 updatePhysicalPort(transactionBuilder, psNodeiid, Lists.newArrayList(inputPhysicalPort));
212 getDeviceInfo().addJobToQueue(configWaitingJob);
215 private InstanceIdentifier<TerminationPoint> getTpIid(final InstanceIdentifier<Node> psNodeiid,
216 final String portName) {
217 return psNodeiid.child(
218 TerminationPoint.class, new TerminationPointKey(new TpId(portName)));
221 private InstanceIdentifier<VlanBindings> getVlanBindingIid(
222 final InstanceIdentifier<Node> psNodeiid,
223 final PhysicalPort physicalPort,
224 final VlanBindings vlanBinding) {
226 return psNodeiid.child(
227 TerminationPoint.class, new TerminationPointKey(new TpId(physicalPort.getName())))
228 .augmentation(HwvtepPhysicalPortAugmentation.class)
229 .child(VlanBindings.class, new VlanBindingsKey(vlanBinding.getVlanIdKey()));
232 static class VlanBindingsUnMetDependencyGetter extends UnMetDependencyGetter<VlanBindings> {
234 public List<InstanceIdentifier<?>> getLogicalSwitchDependencies(VlanBindings data) {
236 return Collections.emptyList();
238 return Collections.singletonList(data.getLogicalSwitchRef().getValue());
241 public List<InstanceIdentifier<?>> getTerminationPointDependencies(VlanBindings data) {
242 return Collections.emptyList();
246 private Map<InstanceIdentifier<Node>, List<HwvtepPhysicalPortAugmentation>> extractCreated(
247 Collection<DataTreeModification<Node>> changes, Class<HwvtepPhysicalPortAugmentation> class1) {
248 Map<InstanceIdentifier<Node>, List<HwvtepPhysicalPortAugmentation>> result = new HashMap<>();
249 if (changes != null && !changes.isEmpty()) {
250 for (DataTreeModification<Node> change : changes) {
251 final InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
252 final DataObjectModification<Node> mod = change.getRootNode();
253 Node created = TransactUtils.getCreated(mod);
254 if (created != null) {
255 List<HwvtepPhysicalPortAugmentation> portListUpdated = new ArrayList<>();
256 if (created.getTerminationPoint() != null) {
257 for (TerminationPoint tp : created.getTerminationPoint()) {
258 HwvtepPhysicalPortAugmentation hppAugmentation = tp.getAugmentation(HwvtepPhysicalPortAugmentation.class);
259 if (hppAugmentation != null) {
260 portListUpdated.add(hppAugmentation);
264 result.put(key, portListUpdated);
271 private Map<InstanceIdentifier<Node>, PhysicalSwitchAugmentation> extractCreatedPhyscialSwitch(
272 Collection<DataTreeModification<Node>> changes, Class<PhysicalSwitchAugmentation> class1) {
273 Map<InstanceIdentifier<Node>, PhysicalSwitchAugmentation> result = new HashMap<>();
274 if (changes != null && !changes.isEmpty()) {
275 for (DataTreeModification<Node> change : changes) {
276 final InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
277 final DataObjectModification<Node> mod = change.getRootNode();
278 Node created = TransactUtils.getCreated(mod);
279 if (created != null) {
280 PhysicalSwitchAugmentation physicalSwitch = created.getAugmentation(PhysicalSwitchAugmentation.class);
281 if (physicalSwitch != null) {
282 result.put(key, physicalSwitch);
290 private Map<InstanceIdentifier<Node>, List<HwvtepPhysicalPortAugmentation>> extractUpdatedPorts(
291 Collection<DataTreeModification<Node>> changes, Class<HwvtepPhysicalPortAugmentation> class1) {
292 Map<InstanceIdentifier<Node>, List<HwvtepPhysicalPortAugmentation>> result = new HashMap<>();
293 if (changes != null && !changes.isEmpty()) {
294 for (DataTreeModification<Node> change : changes) {
295 final InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
296 final DataObjectModification<Node> mod = change.getRootNode();
297 Node updated = TransactUtils.getUpdated(mod);
298 Node before = mod.getDataBefore();
299 if (updated != null && before != null) {
300 List<HwvtepPhysicalPortAugmentation> portListUpdated = new ArrayList<>();
301 List<HwvtepPhysicalPortAugmentation> portListBefore = new ArrayList<>();
302 if (updated.getTerminationPoint() != null) {
303 for (TerminationPoint tp : updated.getTerminationPoint()) {
304 HwvtepPhysicalPortAugmentation hppAugmentation = tp.getAugmentation(HwvtepPhysicalPortAugmentation.class);
305 if (hppAugmentation != null) {
306 portListUpdated.add(hppAugmentation);
310 if (before.getTerminationPoint() != null) {
311 for (TerminationPoint tp : before.getTerminationPoint()) {
312 HwvtepPhysicalPortAugmentation hppAugmentation = tp.getAugmentation(HwvtepPhysicalPortAugmentation.class);
313 if (hppAugmentation != null) {
314 portListBefore.add(hppAugmentation);
318 portListUpdated.removeAll(portListBefore);
319 result.put(key, portListUpdated);