Update MRI projects for Aluminium
[ovsdb.git] / southbound / southbound-impl / src / main / java / org / opendaylight / ovsdb / southbound / reconciliation / configuration / TerminationPointConfigReconciliationTask.java
1 /*
2  * Copyright (c) 2016, 2017 NEC Corporation 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 package org.opendaylight.ovsdb.southbound.reconciliation.configuration;
9
10 import java.util.ArrayList;
11 import java.util.Collections;
12 import java.util.HashMap;
13 import java.util.HashSet;
14 import java.util.List;
15 import java.util.Map;
16 import java.util.Set;
17 import org.opendaylight.ovsdb.southbound.InstanceIdentifierCodec;
18 import org.opendaylight.ovsdb.southbound.OvsdbConnectionInstance;
19 import org.opendaylight.ovsdb.southbound.OvsdbConnectionManager;
20 import org.opendaylight.ovsdb.southbound.SouthboundConstants;
21 import org.opendaylight.ovsdb.southbound.SouthboundMapper;
22 import org.opendaylight.ovsdb.southbound.ovsdb.transact.BridgeOperationalState;
23 import org.opendaylight.ovsdb.southbound.ovsdb.transact.DataChangeEvent;
24 import org.opendaylight.ovsdb.southbound.ovsdb.transact.TerminationPointCreateCommand;
25 import org.opendaylight.ovsdb.southbound.ovsdb.transact.TerminationPointDeleteCommand;
26 import org.opendaylight.ovsdb.southbound.reconciliation.ReconciliationManager;
27 import org.opendaylight.ovsdb.southbound.reconciliation.ReconciliationTask;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortExternalIds;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortExternalIdsKey;
31 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
32 import org.opendaylight.yangtools.yang.binding.DataObject;
33 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
36
37 /**
38  * Reconciliation task to reconcile termination point configurations in the config datastore.
39  * When the OVS switch connects to the ODL, the list of all bridge and termination point
40  * configurations in the config datastore are obtained.
41  * We then listens for any new bridge show up in the operational data store.
42  * If the new bridge is in the list of bridges to be reconciled as described above
43  * termination point reconciliation is triggered for that bridge.
44  */
45 public class TerminationPointConfigReconciliationTask extends ReconciliationTask {
46     private static final Logger LOG = LoggerFactory.getLogger(TerminationPointConfigReconciliationTask.class);
47     private static final PortExternalIdsKey CREATED_BY_KEY = new PortExternalIdsKey(SouthboundConstants.CREATED_BY);
48
49     private final OvsdbConnectionInstance connectionInstance;
50     private final InstanceIdentifierCodec instanceIdentifierCodec;
51     private final Map<InstanceIdentifier<OvsdbTerminationPointAugmentation>, OvsdbTerminationPointAugmentation>
52         operTerminationPoints;
53
54     public TerminationPointConfigReconciliationTask(final ReconciliationManager reconciliationManager,
55             final OvsdbConnectionManager connectionManager, final Node bridgeNode,
56             final InstanceIdentifier<?> bridgeIid, final OvsdbConnectionInstance connectionInstance,
57             final Map<InstanceIdentifier<OvsdbTerminationPointAugmentation>, OvsdbTerminationPointAugmentation>
58                 operTerminationPoints,
59             final InstanceIdentifierCodec instanceIdentifierCodec) {
60         super(reconciliationManager, connectionManager, bridgeIid, bridgeNode);
61         this.connectionInstance = connectionInstance;
62         this.instanceIdentifierCodec = instanceIdentifierCodec;
63         this.operTerminationPoints = operTerminationPoints;
64     }
65
66     @Override
67     public boolean reconcileConfiguration(final OvsdbConnectionManager connectionManager) {
68         final Map<InstanceIdentifier<?>, DataObject> changes = new HashMap<>();
69         final Node configNodeData = (Node) configData;
70         LOG.debug("Reconcile Termination Point Configuration for node {}", configNodeData.getNodeId());
71         changes.putAll(SouthboundMapper.extractTerminationPointConfigurationChanges(configNodeData));
72         DataChangeEvent changeEvents = new DataChangeEvent() {
73             @Override
74             public Map<InstanceIdentifier<?>, DataObject> getCreatedData() {
75                 return changes;
76             }
77
78             @Override
79             public Map<InstanceIdentifier<?>, DataObject> getUpdatedData() {
80                 return Collections.emptyMap();
81             }
82
83             @Override
84             public Map<InstanceIdentifier<?>, DataObject> getOriginalData() {
85                 return Collections.emptyMap();
86             }
87
88             @Override
89             public Set<InstanceIdentifier<?>> getRemovedPaths() {
90                 return Collections.emptySet();
91             }
92         };
93
94         connectionInstance.transact(new TerminationPointCreateCommand(),
95                         new BridgeOperationalState(reconciliationManager.getDb(), changeEvents),
96                         changeEvents, instanceIdentifierCodec);
97
98         List<String> configTerminationPoints = new ArrayList<>();
99         if (configNodeData.getTerminationPoint() != null) {
100             configNodeData.getTerminationPoint().values().forEach(entry -> {
101                 configTerminationPoints.add(entry.getTpId().getValue());
102             });
103         }
104
105         Set<InstanceIdentifier<?>> removeTerminationPoints = new HashSet<>();
106         final Map<InstanceIdentifier<?>, DataObject> original = new HashMap<>();
107         final InstanceIdentifier<Node> bridgeNodeIid =
108                 SouthboundMapper.createInstanceIdentifier(configNodeData.getNodeId());
109         original.put(bridgeNodeIid, configNodeData);
110         LOG.trace("Config Topology Termination Points during Reconciliation {} for bridge {}",
111             configTerminationPoints, bridgeNodeIid);
112         LOG.trace("Oper Topology Termination Points during Reconciliation {} for bridge {}",
113             operTerminationPoints, bridgeNodeIid);
114         for (Map.Entry<InstanceIdentifier<OvsdbTerminationPointAugmentation>, OvsdbTerminationPointAugmentation> entry :
115                 operTerminationPoints.entrySet()) {
116             OvsdbTerminationPointAugmentation terminationPoint = entry.getValue();
117             if (configTerminationPoints.contains(terminationPoint.getName())) {
118                 LOG.trace("Termination Point {} from Oper Topology also present in config topology During Reconcile",
119                     terminationPoint.getName());
120             } else {
121                 LOG.trace("Termination Point {} from Oper Topology NOT present in config topology During Reconcile,"
122                         + "checking if this created by ODL and perform delete reconciliation",
123                     terminationPoint.getName());
124                 Map<PortExternalIdsKey, PortExternalIds> externalIds = terminationPoint.getPortExternalIds();
125                 if (externalIds != null) {
126                     final PortExternalIds portExternalIds = externalIds.get(CREATED_BY_KEY);
127                     if (portExternalIds != null
128                             && SouthboundConstants.ODL.equals(portExternalIds.getExternalIdValue())) {
129                         LOG.trace("Termination Point {} created by ODL. Marking for deletion during reconcile",
130                             entry.getKey());
131                         removeTerminationPoints.add(entry.getKey());
132                         original.put(entry.getKey(), entry.getValue());
133                         break;
134                     }
135                 }
136             }
137         }
138
139         DataChangeEvent deleteChangeEvents = new DataChangeEvent() {
140             @Override
141             public Map<InstanceIdentifier<?>, DataObject> getCreatedData() {
142                 return Collections.emptyMap();
143             }
144
145             @Override
146             public Map<InstanceIdentifier<?>, DataObject> getUpdatedData() {
147                 return original;
148             }
149
150             @Override
151             public Map<InstanceIdentifier<?>, DataObject> getOriginalData() {
152                 return original;
153             }
154
155             @Override
156             public Set<InstanceIdentifier<?>> getRemovedPaths() {
157                 return removeTerminationPoints;
158             }
159         };
160
161         connectionInstance.transact(new TerminationPointDeleteCommand(),
162                 new BridgeOperationalState(reconciliationManager.getDb(), deleteChangeEvents),
163                 deleteChangeEvents, instanceIdentifierCodec);
164
165         return true;
166     }
167
168     @Override
169     public void doRetry(boolean wasPreviousAttemptSuccessful) {
170     }
171
172     @Override
173     public void checkReadinessAndProcess() {
174     }
175
176     @Override
177     public long retryDelayInMills() {
178         return 0;
179     }
180 }