Upgrade ietf-{inet,yang}-types to 2013-07-15
[ovsdb.git] / southbound / southbound-impl / src / main / java / org / opendaylight / ovsdb / southbound / ovsdb / transact / AutoAttachRemovedCommand.java
1 /*
2  * Copyright (c) 2016 Inocybe Technologies and others. All rights reserved.
3  *
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
7  */
8
9 package org.opendaylight.ovsdb.southbound.ovsdb.transact;
10
11 import static org.opendaylight.ovsdb.lib.operations.Operations.op;
12
13 import com.google.common.base.Optional;
14 import com.google.common.collect.Sets;
15 import java.util.Collection;
16 import java.util.List;
17 import java.util.Map;
18 import java.util.concurrent.ExecutionException;
19 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
20 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
21 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
22 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
23 import org.opendaylight.ovsdb.lib.notation.Mutator;
24 import org.opendaylight.ovsdb.lib.notation.UUID;
25 import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
26 import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
27 import org.opendaylight.ovsdb.schema.openvswitch.AutoAttach;
28 import org.opendaylight.ovsdb.schema.openvswitch.Bridge;
29 import org.opendaylight.ovsdb.southbound.SouthboundProvider;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeRef;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.Autoattach;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ManagedNodeEntry;
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.DataObject;
39 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
42
43 public class AutoAttachRemovedCommand implements TransactCommand {
44     private static final Logger LOG = LoggerFactory.getLogger(AutoAttachRemovedCommand.class);
45
46     @Override
47     public void execute(TransactionBuilder transaction, BridgeOperationalState state,
48                         Collection<DataTreeModification<Node>> modifications) {
49         execute(transaction, state, TransactUtils.extractOriginal(modifications, OvsdbNodeAugmentation.class),
50                 TransactUtils.extractUpdated(modifications, OvsdbNodeAugmentation.class));
51     }
52
53     @Override
54     public void execute(TransactionBuilder transaction, BridgeOperationalState state,
55                         AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> events) {
56         execute(transaction, state, TransactUtils.extractOriginal(events, OvsdbNodeAugmentation.class),
57                 TransactUtils.extractUpdated(events, OvsdbNodeAugmentation.class));
58     }
59
60     private void execute(TransactionBuilder transaction, BridgeOperationalState state,
61                          Map<InstanceIdentifier<OvsdbNodeAugmentation>, OvsdbNodeAugmentation> original,
62                          Map<InstanceIdentifier<OvsdbNodeAugmentation>, OvsdbNodeAugmentation> updated) {
63
64         for (final Map.Entry<InstanceIdentifier<OvsdbNodeAugmentation>, OvsdbNodeAugmentation> originalEntry :
65                 original.entrySet()) {
66             final InstanceIdentifier<OvsdbNodeAugmentation> ovsdbNodeIid = originalEntry.getKey();
67             final OvsdbNodeAugmentation ovsdbNodeAugmentation = originalEntry.getValue();
68             final OvsdbNodeAugmentation deletedOvsdbNodeAugmentation = updated.get(ovsdbNodeIid);
69
70             if (ovsdbNodeAugmentation != null && deletedOvsdbNodeAugmentation != null) {
71                 final List<Autoattach> origAutoattachList = ovsdbNodeAugmentation.getAutoattach();
72                 final List<Autoattach> deletedAutoattachList = deletedOvsdbNodeAugmentation.getAutoattach();
73                 if (origAutoattachList != null && !origAutoattachList.isEmpty()
74                         && (deletedAutoattachList == null || deletedAutoattachList.isEmpty())) {
75
76                     if (true) {
77                         // FIXME: Remove if loop after ovs community supports external_ids column in AutoAttach Table
78                         LOG.info("UNSUPPORTED FUNCTIONALITY: Auto Attach related CRUD operations are not supported for"
79                                 + " this version of OVSDB schema due to missing external_ids column.");
80                         return;
81                     }
82                     final OvsdbNodeAugmentation currentOvsdbNode =
83                             state.getBridgeNode(ovsdbNodeIid).get().getAugmentation(OvsdbNodeAugmentation.class);
84                     final List<Autoattach> currentAutoAttach = currentOvsdbNode.getAutoattach();
85                     for (final Autoattach origAutoattach : origAutoattachList) {
86                         final Uri autoAttachId = origAutoattach.getAutoattachId();
87                         deleteAutoAttach(transaction, ovsdbNodeIid, getAutoAttachUuid(currentAutoAttach, autoAttachId));
88                     }
89                 }
90             }
91         }
92     }
93
94     private void deleteAutoAttach(TransactionBuilder transaction,
95             InstanceIdentifier<OvsdbNodeAugmentation> ovsdbNodeIid,
96             Uuid autoattachUuid) {
97
98         LOG.debug("Received request to delete Autoattach entry {}", autoattachUuid);
99         final OvsdbBridgeAugmentation bridgeAugmentation = getBridge(ovsdbNodeIid, autoattachUuid);
100         if (autoattachUuid != null && bridgeAugmentation != null) {
101             final UUID uuid = new UUID(autoattachUuid.getValue());
102             final AutoAttach autoattach =
103                     TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(), AutoAttach.class, null);
104             transaction.add(op.delete(autoattach.getSchema())
105                     .where(autoattach.getUuidColumn().getSchema().opEqual(uuid))
106                     .build());
107             transaction.add(op.comment("AutoAttach: Deleting {} " + uuid
108                     + " attached to " + bridgeAugmentation.getBridgeName().getValue()));
109
110             final Bridge bridge = TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(),
111                     Bridge.class,null);
112
113             transaction.add(op.mutate(bridge.getSchema())
114                     .addMutation(bridge.getAutoAttachColumn().getSchema(),
115                             Mutator.DELETE, Sets.newHashSet(uuid))
116                     .where(bridge.getNameColumn().getSchema()
117                             .opEqual(bridgeAugmentation.getBridgeName().getValue())).build());
118
119             transaction.add(op.comment("Bridge: Mutating " + bridgeAugmentation.getBridgeName().getValue()
120                     + " to remove autoattach column " + uuid));
121         } else {
122             LOG.debug("Unable to delete AutoAttach {} for node {} because it was not found in the operational store, "
123                     + "and thus we cannot retrieve its UUID", autoattachUuid, ovsdbNodeIid);
124         }
125     }
126
127     private Uuid getAutoAttachUuid(List<Autoattach> currentAutoAttach, Uri autoAttachId) {
128         if (currentAutoAttach != null && !currentAutoAttach.isEmpty()) {
129             for (final Autoattach autoAttach : currentAutoAttach) {
130                 if (autoAttach.getAutoattachId().equals(autoAttachId)) {
131                     return autoAttach.getAutoattachUuid();
132                 }
133             }
134         }
135         return null;
136     }
137
138     private OvsdbBridgeAugmentation getBridge(InstanceIdentifier<OvsdbNodeAugmentation> key, Uuid aaUuid) {
139         if (aaUuid == null) {
140             return null;
141         }
142         OvsdbBridgeAugmentation bridge = null;
143         final InstanceIdentifier<Node> nodeIid = key.firstIdentifierOf(Node.class);
144         try (ReadOnlyTransaction transaction = SouthboundProvider.getDb().newReadOnlyTransaction()) {
145             final Optional<Node> nodeOptional = transaction.read(LogicalDatastoreType.OPERATIONAL, nodeIid).get();
146             if (nodeOptional.isPresent()) {
147                 final List<ManagedNodeEntry> managedNodes =
148                         nodeOptional.get().getAugmentation(OvsdbNodeAugmentation.class).getManagedNodeEntry();
149                 for (final ManagedNodeEntry managedNode : managedNodes) {
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.orNull();
156                     if (bridge != null && bridge.getAutoAttach() != null
157                             && bridge.getAutoAttach().equals(aaUuid)) {
158                         return bridge;
159                     }
160                 }
161             }
162         } catch (InterruptedException | ExecutionException e) {
163             LOG.warn("Error reading from datastore",e);
164         }
165         return null;
166     }
167 }