2 * Copyright (c) 2016, 2017 NEC Corporation 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.reconciliation.configuration;
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;
18 import org.opendaylight.ovsdb.southbound.InstanceIdentifierCodec;
19 import org.opendaylight.ovsdb.southbound.OvsdbConnectionInstance;
20 import org.opendaylight.ovsdb.southbound.OvsdbConnectionManager;
21 import org.opendaylight.ovsdb.southbound.SouthboundConstants;
22 import org.opendaylight.ovsdb.southbound.SouthboundMapper;
23 import org.opendaylight.ovsdb.southbound.ovsdb.transact.BridgeOperationalState;
24 import org.opendaylight.ovsdb.southbound.ovsdb.transact.DataChangeEvent;
25 import org.opendaylight.ovsdb.southbound.ovsdb.transact.TerminationPointCreateCommand;
26 import org.opendaylight.ovsdb.southbound.ovsdb.transact.TerminationPointDeleteCommand;
27 import org.opendaylight.ovsdb.southbound.reconciliation.ReconciliationManager;
28 import org.opendaylight.ovsdb.southbound.reconciliation.ReconciliationTask;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortExternalIds;
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;
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.
45 public class TerminationPointConfigReconciliationTask extends ReconciliationTask {
47 private static final Logger LOG = LoggerFactory.getLogger(TerminationPointConfigReconciliationTask.class);
48 private final OvsdbConnectionInstance connectionInstance;
49 private final InstanceIdentifierCodec instanceIdentifierCodec;
50 private final Map<InstanceIdentifier<OvsdbTerminationPointAugmentation>, OvsdbTerminationPointAugmentation>
51 operTerminationPoints;
53 public TerminationPointConfigReconciliationTask(final ReconciliationManager reconciliationManager,
54 final OvsdbConnectionManager connectionManager, final Node bridgeNode,
55 final InstanceIdentifier<?> bridgeIid, final OvsdbConnectionInstance connectionInstance,
56 final Map<InstanceIdentifier<OvsdbTerminationPointAugmentation>, OvsdbTerminationPointAugmentation>
57 operTerminationPoints,
58 final InstanceIdentifierCodec instanceIdentifierCodec) {
59 super(reconciliationManager, connectionManager, bridgeIid, bridgeNode);
60 this.connectionInstance = connectionInstance;
61 this.instanceIdentifierCodec = instanceIdentifierCodec;
62 this.operTerminationPoints = operTerminationPoints;
66 public boolean reconcileConfiguration(final OvsdbConnectionManager connectionManager) {
67 final Map<InstanceIdentifier<?>, DataObject> changes = new HashMap<>();
68 final Node configNodeData = ((Node) configData);
69 LOG.debug("Reconcile Termination Point Configuration for node {}", configNodeData.getNodeId());
70 changes.putAll(SouthboundMapper.extractTerminationPointConfigurationChanges(configNodeData));
71 DataChangeEvent changeEvents = new DataChangeEvent() {
73 public Map<InstanceIdentifier<?>, DataObject> getCreatedData() {
78 public Map<InstanceIdentifier<?>, DataObject> getUpdatedData() {
79 return Collections.emptyMap();
83 public Map<InstanceIdentifier<?>, DataObject> getOriginalData() {
84 return Collections.emptyMap();
88 public Set<InstanceIdentifier<?>> getRemovedPaths() {
89 return Collections.emptySet();
93 connectionInstance.transact(new TerminationPointCreateCommand(),
94 new BridgeOperationalState(reconciliationManager.getDb(), changeEvents),
95 changeEvents, instanceIdentifierCodec);
97 List<String> configTerminationPoints = new ArrayList<>();
98 if (configNodeData.getTerminationPoint() != null) {
99 configNodeData.getTerminationPoint().forEach(entry -> {
100 configTerminationPoints.add(entry.getTpId().getValue());
104 Set<InstanceIdentifier<?>> removeTerminationPoints = new HashSet<>();
105 final Map<InstanceIdentifier<?>, DataObject> original = new HashMap<>();
106 final InstanceIdentifier<Node> bridgeNodeIid =
107 SouthboundMapper.createInstanceIdentifier(configNodeData.getNodeId());
108 original.put(bridgeNodeIid, configNodeData);
109 LOG.trace("Config Topology Termination Points during Reconciliation {} for bridge {}",
110 configTerminationPoints, bridgeNodeIid);
111 LOG.trace("Oper Topology Termination Points during Reconciliation {} for bridge {}",
112 operTerminationPoints, bridgeNodeIid);
113 for (Map.Entry<InstanceIdentifier<OvsdbTerminationPointAugmentation>, OvsdbTerminationPointAugmentation> entry :
114 operTerminationPoints.entrySet()) {
115 OvsdbTerminationPointAugmentation terminationPoint = entry.getValue();
116 if (configTerminationPoints.contains(terminationPoint.getName())) {
117 LOG.trace("Termination Point {} from Oper Topology also present in config topology During Reconcile",
118 terminationPoint.getName());
120 LOG.trace("Termination Point {} from Oper Topology NOT present in config topology During Reconcile,"
121 + "checking if this created by ODL and perform delete reconciliation",
122 terminationPoint.getName());
123 List<PortExternalIds> externalIds = terminationPoint.getPortExternalIds();
124 if (externalIds != null) {
125 for (PortExternalIds portExternalIds : externalIds) {
126 if (portExternalIds.getExternalIdKey().equals(SouthboundConstants.CREATED_BY)
127 && portExternalIds.getExternalIdValue().equals(SouthboundConstants.ODL)) {
128 LOG.trace("Termination Point {} created by ODL. Marking for deletion during reconcile",
130 removeTerminationPoints.add(entry.getKey());
131 original.put(entry.getKey(), entry.getValue());
139 DataChangeEvent deleteChangeEvents = new DataChangeEvent() {
141 public Map<InstanceIdentifier<?>, DataObject> getCreatedData() {
142 return Collections.emptyMap();
146 public Map<InstanceIdentifier<?>, DataObject> getUpdatedData() {
151 public Map<InstanceIdentifier<?>, DataObject> getOriginalData() {
156 public Set<InstanceIdentifier<?>> getRemovedPaths() {
157 return removeTerminationPoints;
161 connectionInstance.transact(new TerminationPointDeleteCommand(),
162 new BridgeOperationalState(reconciliationManager.getDb(), deleteChangeEvents),
163 deleteChangeEvents, instanceIdentifierCodec);
169 public void doRetry(boolean wasPreviousAttemptSuccessful) {
173 public void checkReadinessAndProcess() {
177 public long retryDelayInMills() {