2 * Copyright © 2016, 2017 Inocybe Technologies 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.southbound.ovsdb.transact;
10 import static org.opendaylight.ovsdb.lib.operations.Operations.op;
12 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
13 import java.util.Collection;
14 import java.util.Collections;
16 import java.util.Optional;
17 import java.util.concurrent.ExecutionException;
18 import org.opendaylight.mdsal.binding.api.DataTreeModification;
19 import org.opendaylight.mdsal.binding.api.ReadTransaction;
20 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
21 import org.opendaylight.ovsdb.lib.notation.Mutator;
22 import org.opendaylight.ovsdb.lib.notation.UUID;
23 import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
24 import org.opendaylight.ovsdb.schema.openvswitch.AutoAttach;
25 import org.opendaylight.ovsdb.schema.openvswitch.Bridge;
26 import org.opendaylight.ovsdb.southbound.InstanceIdentifierCodec;
27 import org.opendaylight.ovsdb.southbound.SouthboundProvider;
28 import org.opendaylight.ovsdb.southbound.SouthboundUtil;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeRef;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.Autoattach;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.AutoattachKey;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ManagedNodeEntry;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ManagedNodeEntryKey;
37 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
38 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
42 @SuppressFBWarnings("UPM_UNCALLED_PRIVATE_METHOD")
43 public class AutoAttachRemovedCommand implements TransactCommand {
44 private static final Logger LOG = LoggerFactory.getLogger(AutoAttachRemovedCommand.class);
47 public void execute(final TransactionBuilder transaction, final BridgeOperationalState state,
48 final Collection<DataTreeModification<Node>> modifications,
49 final InstanceIdentifierCodec instanceIdentifierCodec) {
50 execute(transaction, state, TransactUtils.extractOriginal(modifications, OvsdbNodeAugmentation.class),
51 TransactUtils.extractUpdated(modifications, OvsdbNodeAugmentation.class));
55 public void execute(final TransactionBuilder transaction, final BridgeOperationalState state,
56 final DataChangeEvent events, final InstanceIdentifierCodec instanceIdentifierCodec) {
57 execute(transaction, state, TransactUtils.extractOriginal(events, OvsdbNodeAugmentation.class),
58 TransactUtils.extractUpdated(events, OvsdbNodeAugmentation.class));
61 private static void execute(final TransactionBuilder transaction, final BridgeOperationalState state,
62 final Map<InstanceIdentifier<OvsdbNodeAugmentation>, OvsdbNodeAugmentation> original,
63 final Map<InstanceIdentifier<OvsdbNodeAugmentation>, OvsdbNodeAugmentation> updated) {
65 for (final Map.Entry<InstanceIdentifier<OvsdbNodeAugmentation>, OvsdbNodeAugmentation> originalEntry :
66 original.entrySet()) {
67 final InstanceIdentifier<OvsdbNodeAugmentation> ovsdbNodeIid = originalEntry.getKey();
68 final OvsdbNodeAugmentation ovsdbNodeAugmentation = originalEntry.getValue();
69 final OvsdbNodeAugmentation deletedOvsdbNodeAugmentation = updated.get(ovsdbNodeIid);
71 if (ovsdbNodeAugmentation != null && deletedOvsdbNodeAugmentation != null) {
72 final Map<AutoattachKey, Autoattach> origAutoattachList = ovsdbNodeAugmentation.getAutoattach();
73 final Map<AutoattachKey, Autoattach> deletedAutoattachList =
74 deletedOvsdbNodeAugmentation.getAutoattach();
75 if (origAutoattachList != null && !origAutoattachList.isEmpty()
76 && (deletedAutoattachList == null || deletedAutoattachList.isEmpty())) {
79 // FIXME: Remove if loop after ovs community supports external_ids column in AutoAttach Table
80 LOG.info("UNSUPPORTED FUNCTIONALITY: Auto Attach related CRUD operations are not supported for"
81 + " this version of OVSDB schema due to missing external_ids column.");
84 final OvsdbNodeAugmentation currentOvsdbNode =
85 state.getBridgeNode(ovsdbNodeIid).get().augmentation(OvsdbNodeAugmentation.class);
86 final Map<AutoattachKey, Autoattach> currentAutoAttach = currentOvsdbNode.getAutoattach();
87 for (final Autoattach origAutoattach : origAutoattachList.values()) {
88 deleteAutoAttach(transaction, ovsdbNodeIid, getAutoAttachUuid(currentAutoAttach,
89 origAutoattach.key()));
96 private static void deleteAutoAttach(final TransactionBuilder transaction,
97 final InstanceIdentifier<OvsdbNodeAugmentation> ovsdbNodeIid,
98 final Uuid autoattachUuid) {
100 LOG.debug("Received request to delete Autoattach entry {}", autoattachUuid);
101 final OvsdbBridgeAugmentation bridgeAugmentation = getBridge(ovsdbNodeIid, autoattachUuid);
102 if (autoattachUuid != null && bridgeAugmentation != null) {
103 final UUID uuid = new UUID(autoattachUuid.getValue());
104 final AutoAttach autoattach = transaction.getTypedRowSchema(AutoAttach.class);
105 transaction.add(op.delete(autoattach.getSchema())
106 .where(autoattach.getUuidColumn().getSchema().opEqual(uuid))
108 transaction.add(op.comment("AutoAttach: Deleting {} " + uuid
109 + " attached to " + bridgeAugmentation.getBridgeName().getValue()));
111 final Bridge bridge = transaction.getTypedRowSchema(Bridge.class);
112 transaction.add(op.mutate(bridge.getSchema())
113 .addMutation(bridge.getAutoAttachColumn().getSchema(),
114 Mutator.DELETE, Collections.singleton(uuid))
115 .where(bridge.getNameColumn().getSchema()
116 .opEqual(bridgeAugmentation.getBridgeName().getValue())).build());
118 transaction.add(op.comment("Bridge: Mutating " + bridgeAugmentation.getBridgeName().getValue()
119 + " to remove autoattach column " + uuid));
121 LOG.debug("Unable to delete AutoAttach {} for node {} because it was not found in the operational store, "
122 + "and thus we cannot retrieve its UUID", autoattachUuid, ovsdbNodeIid);
126 private static Uuid getAutoAttachUuid(final Map<AutoattachKey, Autoattach> currentAutoAttach,
127 final AutoattachKey autoAttachId) {
128 if (currentAutoAttach != null) {
129 final Autoattach autoAttach = currentAutoAttach.get(autoAttachId);
130 if (autoAttach != null) {
131 return autoAttach.getAutoattachUuid();
137 private static OvsdbBridgeAugmentation getBridge(final InstanceIdentifier<OvsdbNodeAugmentation> key,
139 if (aaUuid == null) {
142 OvsdbBridgeAugmentation bridge = null;
143 final InstanceIdentifier<Node> nodeIid = key.firstIdentifierOf(Node.class);
144 try (ReadTransaction transaction = SouthboundProvider.getDb().newReadOnlyTransaction()) {
145 final Optional<Node> nodeOptional = SouthboundUtil.readNode(transaction, nodeIid);
146 if (nodeOptional.isPresent()) {
147 final Map<ManagedNodeEntryKey, ManagedNodeEntry> managedNodes =
148 nodeOptional.get().augmentation(OvsdbNodeAugmentation.class).getManagedNodeEntry();
149 for (final ManagedNodeEntry managedNode : managedNodes.values()) {
150 final OvsdbBridgeRef ovsdbBridgeRef = managedNode.getBridgeRef();
151 final InstanceIdentifier<OvsdbBridgeAugmentation> brIid = ovsdbBridgeRef.getValue()
152 .firstIdentifierOf(Node.class).augmentation(OvsdbBridgeAugmentation.class);
153 final Optional<OvsdbBridgeAugmentation> optionalBridge =
154 transaction.read(LogicalDatastoreType.OPERATIONAL, brIid).get();
155 bridge = optionalBridge.get();
156 if (bridge != null && bridge.getAutoAttach() != null
157 && bridge.getAutoAttach().equals(aaUuid)) {
162 } catch (InterruptedException | ExecutionException e) {
163 LOG.warn("Error reading from datastore",e);