Merge "Remove Logical Switch by Listening on ConfigDS"
[ovsdb.git] / hwvtepsouthbound / hwvtepsouthbound-impl / src / main / java / org / opendaylight / ovsdb / hwvtepsouthbound / transact / LogicalSwitchRemoveCommand.java
1 /*
2  * Copyright (c) 2015 China Telecom Beijing Research Institute 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.hwvtepsouthbound.transact;
10
11 import static org.opendaylight.ovsdb.lib.operations.Operations.op;
12
13 import java.util.ArrayList;
14 import java.util.Collection;
15 import java.util.HashMap;
16 import java.util.List;
17 import java.util.Map;
18 import java.util.Map.Entry;
19
20 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
21 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
22 import org.opendaylight.ovsdb.lib.notation.UUID;
23 import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
24 import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
25 import org.opendaylight.ovsdb.schema.hardwarevtep.LogicalSwitch;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitches;
28 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
29 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
32
33 import com.google.common.base.Optional;
34
35 public class LogicalSwitchRemoveCommand extends AbstractTransactCommand {
36     private static final Logger LOG = LoggerFactory.getLogger(LogicalSwitchRemoveCommand.class);
37
38     public LogicalSwitchRemoveCommand(HwvtepOperationalState state,
39             Collection<DataTreeModification<Node>> changes) {
40         super(state, changes);
41     }
42
43     @Override
44     public void execute(TransactionBuilder transaction) {
45         Map<InstanceIdentifier<Node>, List<LogicalSwitches>> removeds =
46                 extractRemoved(getChanges(),LogicalSwitches.class);
47         if (!removeds.isEmpty()) {
48             for (Entry<InstanceIdentifier<Node>, List<LogicalSwitches>> created:
49                 removeds.entrySet()) {
50                 removeLogicalSwitch(transaction,  created.getKey(), created.getValue());
51             }
52         }
53     }
54
55     private void removeLogicalSwitch(TransactionBuilder transaction,
56             InstanceIdentifier<Node> instanceIdentifier, List<LogicalSwitches> lswitchList) {
57         for (LogicalSwitches lswitch: lswitchList) {
58             LOG.debug("Removing logcial switch named: {}", lswitch.getHwvtepNodeName().getValue());
59             Optional<LogicalSwitches> operationalSwitchOptional =
60                     getOperationalState().getLogicalSwitches(instanceIdentifier, lswitch.getKey());
61             LogicalSwitch logicalSwitch = TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(), LogicalSwitch.class, null);
62
63             if (operationalSwitchOptional.isPresent() &&
64                     operationalSwitchOptional.get().getLogicalSwitchUuid() != null) {
65                 UUID logicalSwitchUuid = new UUID(operationalSwitchOptional.get().getLogicalSwitchUuid().getValue());
66                 transaction.add(op.delete(logicalSwitch.getSchema())
67                         .where(logicalSwitch.getUuidColumn().getSchema().opEqual(logicalSwitchUuid)).build());
68                 transaction.add(op.comment("Logical Switch: Deleting " + lswitch.getHwvtepNodeName().getValue()));
69             } else {
70                 LOG.warn("Unable to delete logical switch {} because it was not found in the operational store",
71                         lswitch.getHwvtepNodeName().getValue());
72             }
73         }
74     }
75
76     private Map<InstanceIdentifier<Node>, List<LogicalSwitches>> extractRemoved(
77             Collection<DataTreeModification<Node>> changes, Class<LogicalSwitches> class1) {
78         Map<InstanceIdentifier<Node>, List<LogicalSwitches>> result
79             = new HashMap<InstanceIdentifier<Node>, List<LogicalSwitches>>();
80         if (changes != null && !changes.isEmpty()) {
81             for (DataTreeModification<Node> change : changes) {
82                 final InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
83                 final DataObjectModification<Node> mod = change.getRootNode();
84                 //If the node which logical switches belong to is removed, all logical switches
85                 //should be removed too.
86                 Node removed = TransactUtils.getRemoved(mod);
87                 if (removed != null) {
88                     List<LogicalSwitches> lswitchListRemoved = null;
89                     if (removed.getAugmentation(HwvtepGlobalAugmentation.class) != null) {
90                         lswitchListRemoved = removed.getAugmentation(HwvtepGlobalAugmentation.class).getLogicalSwitches();
91                     }
92                     if (lswitchListRemoved != null) {
93                         result.put(key, lswitchListRemoved);
94                     }
95                 }
96                 //If the node which logical switches belong to is updated, and logical switches may
97                 //be created or updated or deleted, we need to get deleted ones.
98                 Node updated = TransactUtils.getUpdated(mod);
99                 Node before = mod.getDataBefore();
100                 if (updated != null && before != null) {
101                     List<LogicalSwitches> lswitchListUpdated = null;
102                     List<LogicalSwitches> lswitchListBefore = null;
103                     if (updated.getAugmentation(HwvtepGlobalAugmentation.class) != null) {
104                         lswitchListUpdated = updated.getAugmentation(HwvtepGlobalAugmentation.class).getLogicalSwitches();
105                     }
106                     if (before.getAugmentation(HwvtepGlobalAugmentation.class) != null) {
107                         lswitchListBefore = before.getAugmentation(HwvtepGlobalAugmentation.class).getLogicalSwitches();
108                     }
109                     if (lswitchListBefore != null) {
110                         List<LogicalSwitches> lswitchListRemoved = new ArrayList<LogicalSwitches>();
111                         if (lswitchListUpdated != null) {
112                             lswitchListBefore.removeAll(lswitchListUpdated);
113                         }
114                         //then exclude updated ones
115                         for (LogicalSwitches lswitchBefore: lswitchListBefore) {
116                             int i = 0;
117                             for(; i < lswitchListUpdated.size(); i++) {
118                                 if (lswitchBefore.getHwvtepNodeName().equals(lswitchListUpdated.get(i).getHwvtepNodeName())) {
119                                     break;
120                                 }
121                             }
122                             if (i == lswitchListUpdated.size()) {
123                                 lswitchListRemoved.add(lswitchBefore);
124                             }
125                         }
126                         if (!lswitchListRemoved.isEmpty()) {
127                             result.put(key, lswitchListRemoved);
128                         }
129                     }
130                 }
131             }
132         }
133         return result;
134     }
135 }