2 * Copyright (c) 2016 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
9 package org.opendaylight.ovsdb.southbound.ovsdb.transact;
11 import static org.opendaylight.ovsdb.lib.operations.Operations.op;
13 import java.util.Collection;
14 import java.util.List;
16 import java.util.concurrent.ExecutionException;
18 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
19 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
20 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
21 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
22 import org.opendaylight.ovsdb.lib.notation.Mutator;
23 import org.opendaylight.ovsdb.lib.notation.UUID;
24 import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
25 import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
26 import org.opendaylight.ovsdb.schema.openvswitch.AutoAttach;
27 import org.opendaylight.ovsdb.schema.openvswitch.Bridge;
28 import org.opendaylight.ovsdb.southbound.SouthboundProvider;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeRef;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.Autoattach;
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.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
37 import org.opendaylight.yangtools.yang.binding.DataObject;
38 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
42 import com.google.common.base.Optional;
43 import com.google.common.collect.Sets;
45 public class AutoAttachRemovedCommand implements TransactCommand {
46 private static final Logger LOG = LoggerFactory.getLogger(AutoAttachRemovedCommand.class);
49 public void execute(TransactionBuilder transaction, BridgeOperationalState state,
50 Collection<DataTreeModification<Node>> modifications) {
51 execute(transaction, state, TransactUtils.extractOriginal(modifications, OvsdbNodeAugmentation.class),
52 TransactUtils.extractUpdated(modifications, OvsdbNodeAugmentation.class));
56 public void execute(TransactionBuilder transaction, BridgeOperationalState state,
57 AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> events) {
58 execute(transaction, state, TransactUtils.extractOriginal(events, OvsdbNodeAugmentation.class),
59 TransactUtils.extractUpdated(events, OvsdbNodeAugmentation.class));
62 private void execute(TransactionBuilder transaction, BridgeOperationalState state,
63 Map<InstanceIdentifier<OvsdbNodeAugmentation>, OvsdbNodeAugmentation> original,
64 Map<InstanceIdentifier<OvsdbNodeAugmentation>, OvsdbNodeAugmentation> updated) {
66 // FIXME: Remove if loop after ovs community supports external_ids column in AutoAttach Table
69 throw new UnsupportedOperationException("CRUD operations not supported from ODL for auto_attach column for"
70 + " this version of ovsdb schema due to missing external_ids column");
71 } catch (UnsupportedOperationException e) {
72 LOG.debug(e.getMessage());
77 for (Map.Entry<InstanceIdentifier<OvsdbNodeAugmentation>, OvsdbNodeAugmentation> originalEntry : original.entrySet()) {
78 InstanceIdentifier<OvsdbNodeAugmentation> ovsdbNodeIid = originalEntry.getKey();
79 OvsdbNodeAugmentation ovsdbNodeAugmentation = originalEntry.getValue();
80 OvsdbNodeAugmentation deletedOvsdbNodeAugmentation = updated.get(ovsdbNodeIid);
82 if (ovsdbNodeAugmentation != null && deletedOvsdbNodeAugmentation != null) {
83 List<Autoattach> origAutoattachList = ovsdbNodeAugmentation.getAutoattach();
84 List<Autoattach> deletedAutoattachList = deletedOvsdbNodeAugmentation.getAutoattach();
85 if(origAutoattachList != null && !origAutoattachList.isEmpty() &&
86 (deletedAutoattachList == null || deletedAutoattachList.isEmpty())) {
88 OvsdbNodeAugmentation currentOvsdbNode =
89 state.getBridgeNode(ovsdbNodeIid).get().getAugmentation(OvsdbNodeAugmentation.class);
90 List<Autoattach> currentAutoAttach = currentOvsdbNode.getAutoattach();
91 for (Autoattach origAutoattach : origAutoattachList) {
92 Uri autoAttachId = origAutoattach.getAutoattachId();
93 deleteAutoAttach(transaction, ovsdbNodeIid, getAutoAttachUuid(currentAutoAttach, autoAttachId));
100 private void deleteAutoAttach(TransactionBuilder transaction,
101 InstanceIdentifier<OvsdbNodeAugmentation> ovsdbNodeIid,
102 Uuid autoattachUuid) {
104 LOG.debug("Received request to delete Autoattach entry {}", autoattachUuid);
105 OvsdbBridgeAugmentation bridgeAugmentation = getBridge(ovsdbNodeIid, autoattachUuid);
106 if (autoattachUuid != null && bridgeAugmentation != null) {
107 UUID uuid = new UUID(autoattachUuid.getValue());
108 AutoAttach autoattach = TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(), AutoAttach.class, null);
109 transaction.add(op.delete(autoattach.getSchema())
110 .where(autoattach.getUuidColumn().getSchema().opEqual(uuid))
112 transaction.add(op.comment("AutoAttach: Deleting {} " + uuid
113 + " attached to " + bridgeAugmentation.getBridgeName().getValue()));
115 Bridge bridge = TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(),
118 transaction.add(op.mutate(bridge.getSchema())
119 .addMutation(bridge.getAutoAttachColumn().getSchema(),
120 Mutator.DELETE, Sets.newHashSet(uuid))
121 .where(bridge.getNameColumn().getSchema()
122 .opEqual(bridgeAugmentation.getBridgeName().getValue())).build());
124 transaction.add(op.comment("Bridge: Mutating " + bridgeAugmentation.getBridgeName().getValue()
125 + " to remove autoattach column " + uuid));
127 LOG.debug("Unable to delete AutoAttach {} for node {} because it was not found in the operational store, "
128 + "and thus we cannot retrieve its UUID", autoattachUuid, ovsdbNodeIid);
132 private Uuid getAutoAttachUuid(List<Autoattach> currentAutoAttach, Uri autoAttachId) {
133 if (currentAutoAttach != null && !currentAutoAttach.isEmpty()) {
134 for (Autoattach autoAttach : currentAutoAttach) {
135 if (autoAttach.getAutoattachId().equals(autoAttachId)) {
136 return autoAttach.getAutoattachUuid();
143 private OvsdbBridgeAugmentation getBridge(InstanceIdentifier<OvsdbNodeAugmentation> key, Uuid aaUuid) {
144 if (aaUuid == null) {
147 OvsdbBridgeAugmentation bridge = null;
148 InstanceIdentifier<Node> nodeIid = key.firstIdentifierOf(Node.class);
149 try (ReadOnlyTransaction transaction = SouthboundProvider.getDb().newReadOnlyTransaction()) {
150 Optional<Node> nodeOptional = transaction.read(LogicalDatastoreType.OPERATIONAL, nodeIid).get();
151 if (nodeOptional.isPresent()) {
152 List<ManagedNodeEntry> managedNodes = nodeOptional.get().getAugmentation(OvsdbNodeAugmentation.class).getManagedNodeEntry();
153 for (ManagedNodeEntry managedNode : managedNodes) {
154 OvsdbBridgeRef ovsdbBridgeRef = managedNode.getBridgeRef();
155 InstanceIdentifier<OvsdbBridgeAugmentation> brIid = ovsdbBridgeRef.getValue()
156 .firstIdentifierOf(Node.class).augmentation(OvsdbBridgeAugmentation.class);
157 Optional<OvsdbBridgeAugmentation> optionalBridge = transaction.read(LogicalDatastoreType.OPERATIONAL, brIid).get();
158 bridge = optionalBridge.orNull();
159 if(bridge != null && bridge.getAutoAttach() != null
160 && bridge.getAutoAttach().equals(aaUuid)) {
165 } catch (InterruptedException | ExecutionException e) {
166 LOG.warn("Error reading from datastore",e);