From: Chetan Arakere Gowdru Date: Fri, 28 Jun 2019 11:08:08 +0000 (+0530) Subject: Upgrade support of ovsdb reconciliation X-Git-Tag: release/magnesium~23 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=3fef3d0578e11c8d05163b718369fdc0b79f2327;p=ovsdb.git Upgrade support of ovsdb reconciliation Description: When Upgrade in process, the config DS may not be fully populated when reconciliaiton is triggered. This will result in uncessaary deletion on tunnels (as config and oper DS are compared and delta changes will be pushed to switch). Changes are done to postpone the reconcilaiton task until upgrade flag is set to false. Testing Steps. 1) Karaf up and running and tunnels created. 2) Set upgade flag to true. PUT http://localhost:8181/restconf/config/odl-serviceutils-upgrade:upgrade-config { "upgrade-config": { "upgradeInProgress": true } } 3) Close karaf terminal(kill karaf process) 4) Don’t clear data/instance/journal/snapshots 5) del-manager on switches and delete tunnels manually on switches. 6) Start karaf and wait DPN connects. 7) Check the tunnel are not recreated by reconciliation process. 8) Set upgradeInProgress=false and check the tunnels re-created back Change-Id: Id6cc8e1a3aa5e139597fa3071d536e1f5ac0802f Signed-off-by: Chetan Arakere Gowdru Signed-off-by: xcheara --- diff --git a/southbound/southbound-impl/pom.xml b/southbound/southbound-impl/pom.xml index ecc6c87fc..ad62ea7d0 100644 --- a/southbound/southbound-impl/pom.xml +++ b/southbound/southbound-impl/pom.xml @@ -75,6 +75,11 @@ and is available at http://www.eclipse.org/legal/epl-v10.html ready-api 1.7.0-SNAPSHOT + + org.opendaylight.serviceutils + upgrade + 0.5.0-SNAPSHOT + org.opendaylight.infrautils diff --git a/southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/OvsdbConnectionManager.java b/southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/OvsdbConnectionManager.java index 424cc6315..296216ec9 100644 --- a/southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/OvsdbConnectionManager.java +++ b/southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/OvsdbConnectionManager.java @@ -55,6 +55,7 @@ import org.opendaylight.ovsdb.southbound.reconciliation.configuration.BridgeConf 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; @@ -66,6 +67,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class OvsdbConnectionManager implements OvsdbConnectionListener, AutoCloseable { + private final Map clients = new ConcurrentHashMap<>(); private static final Logger LOG = LoggerFactory.getLogger(OvsdbConnectionManager.class); @@ -85,11 +87,13 @@ public class OvsdbConnectionManager implements OvsdbConnectionListener, AutoClos 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; @@ -97,6 +101,7 @@ public class OvsdbConnectionManager implements OvsdbConnectionListener, AutoClos this.ovsdbConnection = ovsdbConnection; this.reconciliationManager = new ReconciliationManager(db, instanceIdentifierCodec); this.instanceIdentifierCodec = instanceIdentifierCodec; + this.upgradeState = upgradeState; } @Override @@ -456,8 +461,10 @@ public class OvsdbConnectionManager implements OvsdbConnectionListener, AutoClos //*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 @@ -642,7 +649,7 @@ public class OvsdbConnectionManager implements OvsdbConnectionListener, AutoClos } } - private void reconcileBridgeConfigurations(final OvsdbConnectionInstance client) { + public void reconcileBridgeConfigurations(final OvsdbConnectionInstance client) { final InstanceIdentifier nodeIid = client.getInstanceIdentifier(); final ReconciliationTask task = new BridgeConfigReconciliationTask( reconciliationManager, OvsdbConnectionManager.this, nodeIid, client, instanceIdentifierCodec); @@ -683,4 +690,8 @@ public class OvsdbConnectionManager implements OvsdbConnectionListener, AutoClos */ ON_DISCONNECT } + + public Map getClients() { + return clients; + } } diff --git a/southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/SouthboundProvider.java b/southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/SouthboundProvider.java index 066b1870e..f19773101 100644 --- a/southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/SouthboundProvider.java +++ b/southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/SouthboundProvider.java @@ -41,8 +41,10 @@ import org.opendaylight.mdsal.eos.binding.api.EntityOwnershipListenerRegistratio 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; @@ -75,12 +77,13 @@ public class SouthboundProvider implements ClusteredDataTreeChangeListener operTopologyRegistration; private final OvsdbDiagStatusProvider ovsdbStatusProvider; private static List reconcileBridgeInclusionList = new ArrayList<>(); private static List reconcileBridgeExclusionList = new ArrayList<>(); + private OvsdbUpgradeStateListener ovsdbUpgradeStateListener; @Inject public SouthboundProvider(@Reference final DataBroker dataBroker, @@ -89,7 +92,8 @@ public class SouthboundProvider implements ClusteredDataTreeChangeListener, 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> registration; + + public OvsdbUpgradeStateListener(final DataBroker db, OvsdbConnectionManager cm) { + + DataTreeIdentifier 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> changes) { + LOG.trace("onDataTreeChanged: {}", changes); + for (DataTreeModification 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 entry : cm.getClients().entrySet()) { + ConnectionInfo connectionInfo = entry.getKey(); + OvsdbConnectionInstance connectionInstance = entry.getValue(); + LOG.trace("ConnectionInfo : {}", connectionInfo); + LOG.trace("OvsdbConnectionInstance : {}", connectionInstance); + cm.reconcileBridgeConfigurations(connectionInstance); + } + } + } + + } + } +} diff --git a/southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/OvsdbDataTreeChangeListenerTest.java b/southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/OvsdbDataTreeChangeListenerTest.java index 25951074c..5e345d562 100644 --- a/southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/OvsdbDataTreeChangeListenerTest.java +++ b/southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/OvsdbDataTreeChangeListenerTest.java @@ -23,6 +23,7 @@ import org.opendaylight.mdsal.eos.binding.api.EntityOwnershipService; 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; @@ -48,9 +49,10 @@ public class OvsdbDataTreeChangeListenerTest extends AbstractConcurrentDataBroke 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 diff --git a/southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/SouthboundProviderTest.java b/southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/SouthboundProviderTest.java index ba5dce982..e7b78c6f6 100644 --- a/southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/SouthboundProviderTest.java +++ b/southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/SouthboundProviderTest.java @@ -41,6 +41,7 @@ import org.opendaylight.mdsal.eos.common.api.CandidateAlreadyRegisteredException 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; @@ -77,7 +78,8 @@ public class SouthboundProviderTest extends AbstractConcurrentDataBrokerTest { 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(); @@ -104,7 +106,8 @@ public class SouthboundProviderTest extends AbstractConcurrentDataBrokerTest { 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(); @@ -133,7 +136,8 @@ public class SouthboundProviderTest extends AbstractConcurrentDataBrokerTest { 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(); @@ -157,7 +161,8 @@ public class SouthboundProviderTest extends AbstractConcurrentDataBrokerTest { 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();