<artifactId>ready-api</artifactId>
<version>1.7.0-SNAPSHOT</version>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.serviceutils</groupId>
+ <artifactId>upgrade</artifactId>
+ <version>0.5.0-SNAPSHOT</version>
+ </dependency>
<!-- external dependencies -->
<dependency>
<groupId>org.opendaylight.infrautils</groupId>
import org.opendaylight.ovsdb.southbound.reconciliation.connection.ConnectionReconciliationTask;
import org.opendaylight.ovsdb.southbound.transactions.md.OvsdbNodeRemoveCommand;
import org.opendaylight.ovsdb.southbound.transactions.md.TransactionInvoker;
+import org.opendaylight.serviceutils.upgrade.UpgradeState;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAttributes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
import org.slf4j.LoggerFactory;
public class OvsdbConnectionManager implements OvsdbConnectionListener, AutoCloseable {
+
private final Map<ConnectionInfo, OvsdbConnectionInstance> clients =
new ConcurrentHashMap<>();
private static final Logger LOG = LoggerFactory.getLogger(OvsdbConnectionManager.class);
private final OvsdbConnection ovsdbConnection;
private final ReconciliationManager reconciliationManager;
private final InstanceIdentifierCodec instanceIdentifierCodec;
+ private final UpgradeState upgradeState;
public OvsdbConnectionManager(final DataBroker db,final TransactionInvoker txInvoker,
final EntityOwnershipService entityOwnershipService,
final OvsdbConnection ovsdbConnection,
- final InstanceIdentifierCodec instanceIdentifierCodec) {
+ final InstanceIdentifierCodec instanceIdentifierCodec,
+ final UpgradeState upgradeState) {
this.db = db;
this.txInvoker = txInvoker;
this.entityOwnershipService = entityOwnershipService;
this.ovsdbConnection = ovsdbConnection;
this.reconciliationManager = new ReconciliationManager(db, instanceIdentifierCodec);
this.instanceIdentifierCodec = instanceIdentifierCodec;
+ this.upgradeState = upgradeState;
}
@Override
//*this* instance of southbound plugin is owner of the device,
//so register for monitor callbacks
ovsdbConnectionInstance.registerCallbacks(instanceIdentifierCodec);
-
- reconcileBridgeConfigurations(ovsdbConnectionInstance);
+ LOG.trace("isUpgradeInProgress {}", upgradeState.isUpgradeInProgress());
+ if (!upgradeState.isUpgradeInProgress()) {
+ reconcileBridgeConfigurations(ovsdbConnectionInstance);
+ }
} else {
//You were owner of the device, but now you are not. With the current ownership
//grant mechanism, this scenario should not occur. Because this scenario will occur
}
}
- private void reconcileBridgeConfigurations(final OvsdbConnectionInstance client) {
+ public void reconcileBridgeConfigurations(final OvsdbConnectionInstance client) {
final InstanceIdentifier<Node> nodeIid = client.getInstanceIdentifier();
final ReconciliationTask task = new BridgeConfigReconciliationTask(
reconciliationManager, OvsdbConnectionManager.this, nodeIid, client, instanceIdentifierCodec);
*/
ON_DISCONNECT
}
+
+ public Map<ConnectionInfo, OvsdbConnectionInstance> getClients() {
+ return clients;
+ }
}
import org.opendaylight.mdsal.eos.binding.api.EntityOwnershipService;
import org.opendaylight.mdsal.eos.common.api.CandidateAlreadyRegisteredException;
import org.opendaylight.ovsdb.lib.OvsdbConnection;
+import org.opendaylight.ovsdb.southbound.reconciliation.OvsdbUpgradeStateListener;
import org.opendaylight.ovsdb.southbound.transactions.md.TransactionInvoker;
import org.opendaylight.ovsdb.southbound.transactions.md.TransactionInvokerImpl;
+import org.opendaylight.serviceutils.upgrade.UpgradeState;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyBuilder;
private final OvsdbConnection ovsdbConnection;
private final InstanceIdentifierCodec instanceIdentifierCodec;
private final SystemReadyMonitor systemReadyMonitor;
-
+ private final UpgradeState upgradeState;
private final AtomicBoolean registered = new AtomicBoolean(false);
private ListenerRegistration<SouthboundProvider> operTopologyRegistration;
private final OvsdbDiagStatusProvider ovsdbStatusProvider;
private static List<String> reconcileBridgeInclusionList = new ArrayList<>();
private static List<String> reconcileBridgeExclusionList = new ArrayList<>();
+ private OvsdbUpgradeStateListener ovsdbUpgradeStateListener;
@Inject
public SouthboundProvider(@Reference final DataBroker dataBroker,
@Reference final DOMSchemaService schemaService,
@Reference final BindingNormalizedNodeSerializer bindingNormalizedNodeSerializer,
@Reference final SystemReadyMonitor systemReadyMonitor,
- @Reference final DiagStatusService diagStatusService) {
+ @Reference final DiagStatusService diagStatusService,
+ @Reference final UpgradeState upgradeState) {
SouthboundProvider.db = dataBroker;
this.entityOwnershipService = entityOwnershipServiceDependency;
registration = null;
this.instanceIdentifierCodec = new InstanceIdentifierCodec(schemaService,
bindingNormalizedNodeSerializer);
this.systemReadyMonitor = systemReadyMonitor;
+ this.upgradeState = upgradeState;
LOG.info("SouthboundProvider ovsdbConnectionService Initialized");
}
ovsdbStatusProvider.reportStatus(ServiceState.STARTING, "OVSDB initialization in progress");
this.txInvoker = new TransactionInvokerImpl(db);
cm = new OvsdbConnectionManager(db, txInvoker, entityOwnershipService, ovsdbConnection,
- instanceIdentifierCodec);
+ instanceIdentifierCodec, upgradeState);
ovsdbDataTreeChangeListener = new OvsdbDataTreeChangeListener(db, cm, instanceIdentifierCodec);
//Register listener for entityOnwership changes
LOG.trace("Registering listener for path {}", treeId);
operTopologyRegistration = db.registerDataTreeChangeListener(treeId, this);
+ ovsdbUpgradeStateListener = new OvsdbUpgradeStateListener(db, cm);
}
@Override
operTopologyRegistration = null;
}
ovsdbStatusProvider.reportStatus(ServiceState.UNREGISTERED, "OVSDB Service stopped");
+ if (ovsdbUpgradeStateListener != null) {
+ ovsdbUpgradeStateListener.close();
+ }
}
private void initializeOvsdbTopology(final LogicalDatastoreType type) {
boolean isRegistered() {
return registered.get();
}
+
+ public UpgradeState getUpgradeState() {
+ return upgradeState;
+ }
}
--- /dev/null
+/*
+ * Copyright (c) 2019 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.ovsdb.southbound.reconciliation;
+
+import java.util.Collection;
+import java.util.Map;
+import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.controller.md.sal.binding.api.ClusteredDataTreeChangeListener;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification.ModificationType;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.ovsdb.southbound.OvsdbConnectionInstance;
+import org.opendaylight.ovsdb.southbound.OvsdbConnectionManager;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfo;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.serviceutils.upgrade.rev180702.UpgradeConfig;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class OvsdbUpgradeStateListener implements ClusteredDataTreeChangeListener<UpgradeConfig>, AutoCloseable {
+
+ private static final Logger LOG = LoggerFactory.getLogger(OvsdbUpgradeStateListener.class);
+
+ private final DataBroker dataBroker;
+
+ /** The connection manager. */
+ private final OvsdbConnectionManager cm;
+
+ /** Our registration. */
+ private final ListenerRegistration<DataTreeChangeListener<UpgradeConfig>> registration;
+
+ public OvsdbUpgradeStateListener(final DataBroker db, OvsdbConnectionManager cm) {
+
+ DataTreeIdentifier<UpgradeConfig> dataTreeIdentifier =
+ new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION,
+ InstanceIdentifier.create(UpgradeConfig.class));
+ registration = db.registerDataTreeChangeListener(dataTreeIdentifier, this);
+
+ this.dataBroker = db;
+ this.cm = cm;
+ LOG.info("OvsdbUpgradeStateListener (ovsdb) initialized");
+ }
+
+ @Override
+ public void close() {
+ registration.close();
+ LOG.info("OVSDB topology listener has been closed.");
+ }
+
+ @Override
+ public void onDataTreeChanged(@NonNull Collection<DataTreeModification<UpgradeConfig>> changes) {
+ LOG.trace("onDataTreeChanged: {}", changes);
+ for (DataTreeModification<UpgradeConfig> change: changes) {
+
+ if (change.getRootNode().getModificationType() == ModificationType.WRITE) {
+ UpgradeConfig before = change.getRootNode().getDataBefore();
+ UpgradeConfig after = change.getRootNode().getDataAfter();
+ if (before != null && before.isUpgradeInProgress() && after != null && !after.isUpgradeInProgress()) {
+ LOG.info("Upgrade Flag is set from {} to {}, Trigger Reconciliation",
+ before.isUpgradeInProgress(), after.isUpgradeInProgress());
+ //TODO Trigger Reconciliation on all the ovsDbConnectionInstance
+ for (Map.Entry<ConnectionInfo, OvsdbConnectionInstance> entry : cm.getClients().entrySet()) {
+ ConnectionInfo connectionInfo = entry.getKey();
+ OvsdbConnectionInstance connectionInstance = entry.getValue();
+ LOG.trace("ConnectionInfo : {}", connectionInfo);
+ LOG.trace("OvsdbConnectionInstance : {}", connectionInstance);
+ cm.reconcileBridgeConfigurations(connectionInstance);
+ }
+ }
+ }
+
+ }
+ }
+}
import org.opendaylight.ovsdb.lib.OvsdbConnection;
import org.opendaylight.ovsdb.southbound.transactions.md.TransactionInvokerImpl;
import org.opendaylight.ovsdb.utils.southbound.utils.SouthboundUtils;
+import org.opendaylight.serviceutils.upgrade.UpgradeState;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfo;
dataBroker = getDataBroker();
EntityOwnershipService entityOwnershipService = mock(EntityOwnershipService.class);
InstanceIdentifierCodec instanceIdentifierCodec = mock(InstanceIdentifierCodec.class);
+ UpgradeState upgradeState = mock(UpgradeState.class);
listener = new OvsdbDataTreeChangeListener(dataBroker,
new OvsdbConnectionManager(dataBroker, new TransactionInvokerImpl(dataBroker), entityOwnershipService,
- ovsdbConnection, instanceIdentifierCodec), instanceIdentifierCodec);
+ ovsdbConnection, instanceIdentifierCodec, upgradeState), instanceIdentifierCodec);
}
@Test
import org.opendaylight.mdsal.eos.common.api.EntityOwnershipChangeState;
import org.opendaylight.mdsal.eos.common.api.EntityOwnershipState;
import org.opendaylight.ovsdb.lib.OvsdbConnection;
+import org.opendaylight.serviceutils.upgrade.UpgradeState;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
Mockito.mock(DOMSchemaService.class),
Mockito.mock(BindingNormalizedNodeSerializer.class),
new TestSystemReadyMonitor(IMMEDIATE),
- Mockito.mock(DiagStatusService.class))) {
+ Mockito.mock(DiagStatusService.class),
+ Mockito.mock(UpgradeState.class))) {
// Initiate the session
southboundProvider.init();
Mockito.mock(DOMSchemaService.class),
Mockito.mock(BindingNormalizedNodeSerializer.class),
new TestSystemReadyMonitor(IMMEDIATE),
- Mockito.mock(DiagStatusService.class))) {
+ Mockito.mock(DiagStatusService.class),
+ Mockito.mock(UpgradeState.class))) {
// Initiate the session
southboundProvider.init();
Mockito.mock(DOMSchemaService.class),
Mockito.mock(BindingNormalizedNodeSerializer.class),
new TestSystemReadyMonitor(IMMEDIATE),
- Mockito.mock(DiagStatusService.class))) {
+ Mockito.mock(DiagStatusService.class),
+ Mockito.mock(UpgradeState.class))) {
southboundProvider.init();
Mockito.mock(DOMSchemaService.class),
Mockito.mock(BindingNormalizedNodeSerializer.class),
new TestSystemReadyMonitor(IMMEDIATE),
- Mockito.mock(DiagStatusService.class))) {
+ Mockito.mock(DiagStatusService.class),
+ Mockito.mock(UpgradeState.class))) {
southboundProvider.init();