From 31c5d8ecd11af442838358ad5c1458b5869827df Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Thu, 13 Oct 2022 20:57:00 +0200 Subject: [PATCH] Migrate topology-manager to CompositeListener Do not use generated Listener interface and prefer a CompositeListeners, which allow more flexible dispatch. A husk FlowCapableTopologyExporter is left intact for testing. Change-Id: I2577fabc9eb8f50a3f98ef57977670f2a24535a3 Signed-off-by: Robert Varga --- .../manager/FlowCapableTopologyExporter.java | 130 ++++++++++-------- .../manager/FlowCapableTopologyProvider.java | 35 +++-- 2 files changed, 92 insertions(+), 73 deletions(-) diff --git a/applications/topology-manager/src/main/java/org/opendaylight/openflowplugin/applications/topology/manager/FlowCapableTopologyExporter.java b/applications/topology-manager/src/main/java/org/opendaylight/openflowplugin/applications/topology/manager/FlowCapableTopologyExporter.java index 2935fe077d..6198b25d35 100644 --- a/applications/topology-manager/src/main/java/org/opendaylight/openflowplugin/applications/topology/manager/FlowCapableTopologyExporter.java +++ b/applications/topology-manager/src/main/java/org/opendaylight/openflowplugin/applications/topology/manager/FlowCapableTopologyExporter.java @@ -8,89 +8,109 @@ package org.opendaylight.openflowplugin.applications.topology.manager; import static java.util.Objects.requireNonNull; -import static org.opendaylight.openflowplugin.applications.topology.manager.FlowCapableNodeMapping.toTopologyLink; +import com.google.common.annotations.VisibleForTesting; import java.util.Optional; +import java.util.Set; import java.util.concurrent.ExecutionException; +import org.opendaylight.mdsal.binding.api.NotificationService.CompositeListener; +import org.opendaylight.mdsal.binding.api.NotificationService.CompositeListener.Component; +import org.opendaylight.mdsal.binding.api.NotificationService.Listener; import org.opendaylight.mdsal.common.api.LogicalDatastoreType; import org.opendaylight.openflowplugin.common.txchain.TransactionChainManager; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.FlowTopologyDiscoveryListener; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkDiscovered; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkOverutilized; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkRemoved; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkUtilizationNormal; 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.topology.Link; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -class FlowCapableTopologyExporter implements FlowTopologyDiscoveryListener { - +class FlowCapableTopologyExporter { private static final Logger LOG = LoggerFactory.getLogger(FlowCapableTopologyExporter.class); + private final InstanceIdentifier iiToTopology; private final OperationProcessor processor; FlowCapableTopologyExporter(final OperationProcessor processor, final InstanceIdentifier topology) { this.processor = requireNonNull(processor); - this.iiToTopology = requireNonNull(topology); + iiToTopology = requireNonNull(topology); } - @Override - @Deprecated - public void onLinkDiscovered(final LinkDiscovered notification) { - processor.enqueueOperation(new TopologyOperation() { - @Override - public void applyOperation(final TransactionChainManager manager) { - final Link link = toTopologyLink(notification); - final InstanceIdentifier path = TopologyManagerUtil.linkPath(link, iiToTopology); - manager.mergeToTransaction(LogicalDatastoreType.OPERATIONAL, path, link, true); - } + CompositeListener toListener() { + return new CompositeListener(Set.of( + new Component(LinkDiscovered.class, (Listener) this::onLinkDiscovered), + new Component(LinkRemoved.class, (Listener) this::onLinkRemoved))); + } - @Override - public String toString() { - return "onLinkDiscovered"; - } - }); + @VisibleForTesting + void onLinkDiscovered(final LinkDiscovered notification) { + processor.enqueueOperation(new OnLinkDiscovered(notification)); } - @Override - @Deprecated - public void onLinkOverutilized(final LinkOverutilized notification) { - // NOOP + @VisibleForTesting + void onLinkRemoved(final LinkRemoved notification) { + processor.enqueueOperation(new OnLinkRemoved(notification)); } - @Override - @Deprecated - public void onLinkRemoved(final LinkRemoved notification) { - processor.enqueueOperation(new TopologyOperation() { - @Override - public void applyOperation(final TransactionChainManager manager) { - Optional linkOptional = Optional.empty(); - try { - // read that checks if link exists (if we do not do this we might get an exception on delete) - linkOptional = manager.readFromTransaction(LogicalDatastoreType.OPERATIONAL, - TopologyManagerUtil.linkPath(toTopologyLink(notification), iiToTopology)).get(); - } catch (InterruptedException | ExecutionException e) { - LOG.warn("Error occurred when trying to read Link: {}", e.getMessage()); - LOG.debug("Error occurred when trying to read Link.. ", e); - } - if (linkOptional.isPresent()) { - manager.addDeleteOperationToTxChain(LogicalDatastoreType.OPERATIONAL, - TopologyManagerUtil.linkPath(toTopologyLink(notification), iiToTopology)); - } - } + private abstract static class AbstractLinkOperation implements TopologyOperation { + private final org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.Link link; - @Override - public String toString() { - return "onLinkRemoved"; - } - }); + AbstractLinkOperation( + final org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.Link link) { + this.link = requireNonNull(link); + } + + @Override + public final void applyOperation(final TransactionChainManager manager) { + applyOperation(manager, FlowCapableNodeMapping.toTopologyLink(link)); + } + + abstract void applyOperation(TransactionChainManager manager, Link link); } - @Override - @Deprecated - public void onLinkUtilizationNormal(final LinkUtilizationNormal notification) { - // NOOP + private final class OnLinkDiscovered extends AbstractLinkOperation { + OnLinkDiscovered(final LinkDiscovered notification) { + super(notification); + } + + @Override + public void applyOperation(final TransactionChainManager manager, final Link link) { + manager.mergeToTransaction(LogicalDatastoreType.OPERATIONAL, + TopologyManagerUtil.linkPath(link, iiToTopology), link, true); + } + + @Override + public String toString() { + return "onLinkDiscovered"; + } + } + + private final class OnLinkRemoved extends AbstractLinkOperation { + OnLinkRemoved(final LinkRemoved notification) { + super(notification); + } + + @Override + public void applyOperation(final TransactionChainManager manager, final Link link) { + final var linkPath = TopologyManagerUtil.linkPath(link, iiToTopology); + + Optional linkOptional = Optional.empty(); + try { + // read that checks if link exists (if we do not do this we might get an exception on delete) + linkOptional = manager.readFromTransaction(LogicalDatastoreType.OPERATIONAL, linkPath).get(); + } catch (InterruptedException | ExecutionException e) { + LOG.warn("Error occurred when trying to read Link: {}", e.getMessage()); + LOG.debug("Error occurred when trying to read Link.. ", e); + } + if (linkOptional.isPresent()) { + manager.addDeleteOperationToTxChain(LogicalDatastoreType.OPERATIONAL, linkPath); + } + } + + @Override + public String toString() { + return "onLinkRemoved"; + } } } diff --git a/applications/topology-manager/src/main/java/org/opendaylight/openflowplugin/applications/topology/manager/FlowCapableTopologyProvider.java b/applications/topology-manager/src/main/java/org/opendaylight/openflowplugin/applications/topology/manager/FlowCapableTopologyProvider.java index d765949c07..b0594925e5 100644 --- a/applications/topology-manager/src/main/java/org/opendaylight/openflowplugin/applications/topology/manager/FlowCapableTopologyProvider.java +++ b/applications/topology-manager/src/main/java/org/opendaylight/openflowplugin/applications/topology/manager/FlowCapableTopologyProvider.java @@ -28,9 +28,8 @@ import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology. 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; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey; -import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.opendaylight.yangtools.concepts.Registration; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.opendaylight.yangtools.yang.binding.NotificationListener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -46,7 +45,7 @@ public class FlowCapableTopologyProvider implements ClusterSingletonService, Aut private final ClusterSingletonServiceProvider clusterSingletonServiceProvider; private InstanceIdentifier topologyPathIID; private TransactionChainManager transactionChainManager; - private ListenerRegistration listenerRegistration; + private Registration listenerRegistration; private ClusterSingletonServiceRegistration singletonServiceRegistration; @Inject @@ -66,31 +65,31 @@ public class FlowCapableTopologyProvider implements ClusterSingletonService, Aut @PostConstruct public void start() { final TopologyKey key = new TopologyKey(new TopologyId(TOPOLOGY_ID)); - this.topologyPathIID = InstanceIdentifier.create(NetworkTopology.class).child(Topology.class, key); + topologyPathIID = InstanceIdentifier.create(NetworkTopology.class).child(Topology.class, key); - final FlowCapableTopologyExporter listener = new FlowCapableTopologyExporter(processor, topologyPathIID); - this.listenerRegistration = notificationService.registerNotificationListener(listener); - this.transactionChainManager = new TransactionChainManager(dataBroker, TOPOLOGY_PROVIDER); - this.transactionChainManager.activateTransactionManager(); - this.transactionChainManager.initialSubmitWriteTransaction(); - this.singletonServiceRegistration = this.clusterSingletonServiceProvider.registerClusterSingletonService(this); + listenerRegistration = notificationService.registerCompositeListener( + new FlowCapableTopologyExporter(processor, topologyPathIID).toListener()); + transactionChainManager = new TransactionChainManager(dataBroker, TOPOLOGY_PROVIDER); + transactionChainManager.activateTransactionManager(); + transactionChainManager.initialSubmitWriteTransaction(); + singletonServiceRegistration = clusterSingletonServiceProvider.registerClusterSingletonService(this); LOG.info("Topology Manager service started."); } @Override @PreDestroy public void close() { - this.transactionChainManager.close(); - if (this.listenerRegistration != null) { + transactionChainManager.close(); + if (listenerRegistration != null) { LOG.info("Closing notification listener registration."); - this.listenerRegistration.close(); - this.listenerRegistration = null; + listenerRegistration.close(); + listenerRegistration = null; } - if (this.singletonServiceRegistration != null) { + if (singletonServiceRegistration != null) { LOG.info("Closing clustering singleton service registration."); - this.singletonServiceRegistration.close(); - this.singletonServiceRegistration = null; + singletonServiceRegistration.close(); + singletonServiceRegistration = null; } LOG.debug("Topology Manager instance is stopped."); } @@ -118,7 +117,7 @@ public class FlowCapableTopologyProvider implements ClusterSingletonService, Aut private boolean isFlowTopologyExist(final InstanceIdentifier path) { try { - Optional ofTopology = this.transactionChainManager + Optional ofTopology = transactionChainManager .readFromTransaction(LogicalDatastoreType.OPERATIONAL, path).get(); LOG.debug("OpenFlow topology exist in the operational data store at {}", path); if (ofTopology.isPresent()) { -- 2.36.6