From: Tom Pantelis Date: Fri, 1 Sep 2017 15:48:12 +0000 (-0400) Subject: DataChangeListener cleanup X-Git-Tag: release/oxygen~112 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=30535bcc4c2770cb8500469fe40bdfb37d8ade4d DataChangeListener cleanup - Removed the DCL example from the car model - Converted messagebus-impl DCL to DCTL Change-Id: I14436f1f80642ce0d35b71be8e1ae4dae658e2a2 Signed-off-by: Tom Pantelis --- diff --git a/opendaylight/md-sal/messagebus-impl/src/main/java/org/opendaylight/controller/messagebus/app/impl/EventSourceTopic.java b/opendaylight/md-sal/messagebus-impl/src/main/java/org/opendaylight/controller/messagebus/app/impl/EventSourceTopic.java index d6132beb8c..ea04d99951 100644 --- a/opendaylight/md-sal/messagebus-impl/src/main/java/org/opendaylight/controller/messagebus/app/impl/EventSourceTopic.java +++ b/opendaylight/md-sal/messagebus-impl/src/main/java/org/opendaylight/controller/messagebus/app/impl/EventSourceTopic.java @@ -13,16 +13,17 @@ import com.google.common.base.Preconditions; import com.google.common.util.concurrent.CheckedFuture; import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; +import java.util.Collection; import java.util.List; -import java.util.Map; import java.util.UUID; import java.util.concurrent.CopyOnWriteArraySet; import java.util.concurrent.ExecutionException; import java.util.regex.Pattern; -import org.opendaylight.controller.md.sal.binding.api.DataBroker; -import org.opendaylight.controller.md.sal.binding.api.DataChangeListener; +import org.opendaylight.controller.md.sal.binding.api.DataObjectModification; +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.binding.api.ReadOnlyTransaction; -import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException; import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.messagebus.eventaggregator.rev141202.NotificationPattern; @@ -37,19 +38,18 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef 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.Node; import org.opendaylight.yangtools.concepts.ListenerRegistration; -import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.common.RpcError; import org.opendaylight.yangtools.yang.common.RpcResult; import org.slf4j.LoggerFactory; -public class EventSourceTopic implements DataChangeListener, AutoCloseable { +public class EventSourceTopic implements DataTreeChangeListener, AutoCloseable { private static final org.slf4j.Logger LOG = LoggerFactory.getLogger(EventSourceTopic.class); private final NotificationPattern notificationPattern; private final EventSourceService sourceService; private final Pattern nodeIdPattern; private final TopicId topicId; - private ListenerRegistration listenerRegistration; + private ListenerRegistration listenerRegistration; private final CopyOnWriteArraySet> joinedEventSources = new CopyOnWriteArraySet<>(); public static EventSourceTopic create(final NotificationPattern notificationPattern, final String nodeIdRegexPattern, final EventSourceTopology eventSourceTopology){ @@ -73,25 +73,19 @@ public class EventSourceTopic implements DataChangeListener, AutoCloseable { } @Override - public void onDataChanged(final AsyncDataChangeEvent, DataObject> event) { - - for (final Map.Entry, DataObject> createdEntry : event.getCreatedData().entrySet()) { - if (createdEntry.getValue() instanceof Node) { - final Node node = (Node) createdEntry.getValue(); - LOG.debug("Create node..."); - if (getNodeIdRegexPattern().matcher(node.getNodeId().getValue()).matches()) { - LOG.debug("Matched..."); - notifyNode(EventSourceTopology.EVENT_SOURCE_TOPOLOGY_PATH.child(Node.class, node.getKey())); - } - } - } - - for (final Map.Entry, DataObject> changeEntry : event.getUpdatedData().entrySet()) { - if (changeEntry.getValue() instanceof Node) { - final Node node = (Node) changeEntry.getValue(); - if (getNodeIdRegexPattern().matcher(node.getNodeId().getValue()).matches()) { - notifyNode(changeEntry.getKey()); - } + public void onDataTreeChanged(Collection> changes) { + for (DataTreeModification change: changes) { + final DataObjectModification rootNode = change.getRootNode(); + switch (rootNode.getModificationType()) { + case WRITE: + case SUBTREE_MODIFIED: + final Node node = rootNode.getDataAfter(); + if (getNodeIdRegexPattern().matcher(node.getNodeId().getValue()).matches()) { + notifyNode(change.getRootPath().getRootIdentifier()); + } + break; + default: + break; } } } @@ -173,11 +167,10 @@ public class EventSourceTopic implements DataChangeListener, AutoCloseable { private void registerListner(final EventSourceTopology eventSourceTopology) { this.listenerRegistration = - eventSourceTopology.getDataBroker().registerDataChangeListener( + eventSourceTopology.getDataBroker().registerDataTreeChangeListener(new DataTreeIdentifier<>( LogicalDatastoreType.OPERATIONAL, - EventSourceTopology.EVENT_SOURCE_TOPOLOGY_PATH, - this, - DataBroker.DataChangeScope.SUBTREE); + EventSourceTopology.EVENT_SOURCE_TOPOLOGY_PATH.child(Node.class)), + this); } @Override diff --git a/opendaylight/md-sal/messagebus-impl/src/test/java/org/opendaylight/controller/messagebus/app/impl/EventSourceTopicTest.java b/opendaylight/md-sal/messagebus-impl/src/test/java/org/opendaylight/controller/messagebus/app/impl/EventSourceTopicTest.java index 0c32cb51e3..8374d395a0 100644 --- a/opendaylight/md-sal/messagebus-impl/src/test/java/org/opendaylight/controller/messagebus/app/impl/EventSourceTopicTest.java +++ b/opendaylight/md-sal/messagebus-impl/src/test/java/org/opendaylight/controller/messagebus/app/impl/EventSourceTopicTest.java @@ -16,16 +16,17 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; -import java.util.HashMap; -import java.util.Map; - +import com.google.common.util.concurrent.CheckedFuture; +import java.util.Collections; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.binding.api.DataObjectModification; +import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier; +import org.opendaylight.controller.md.sal.binding.api.DataTreeModification; import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction; import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; -import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.messagebus.eventaggregator.rev141202.NotificationPattern; import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.messagebus.eventsource.rev141202.EventSourceService; @@ -36,13 +37,9 @@ import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology. import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import com.google.common.util.concurrent.CheckedFuture; - public class EventSourceTopicTest { EventSourceTopic eventSourceTopic; - Node dataObjectNodeMock; - NodeId nodeIdMock; DataBroker dataBrokerMock; EventSourceService eventSourceServiceMock; EventSourceTopology eventSourceTopologyMock; @@ -83,26 +80,28 @@ public class EventSourceTopicTest { assertNotNull("Topic has not been created correctly.", eventSourceTopic.getTopicId()); } + @SuppressWarnings("unchecked") @Test - public void onDataChangedTest() { - AsyncDataChangeEvent asyncDataChangeEventMock = mock(AsyncDataChangeEvent.class); - onDataChangedTestHelper(asyncDataChangeEventMock); - eventSourceTopic.onDataChanged(asyncDataChangeEventMock); - verify(dataObjectNodeMock, times(2)).getNodeId(); - verify(nodeIdMock, times(2)).getValue(); - } - - private void onDataChangedTestHelper(AsyncDataChangeEvent asyncDataChangeEventMock){ - Map, DataObject> map = new HashMap<>(); - InstanceIdentifier instanceIdentifierMock = mock(InstanceIdentifier.class); - dataObjectNodeMock = mock(Node.class); + public void onDataTreeChangedTest() { + InstanceIdentifier instanceIdentifierMock = mock(InstanceIdentifier.class); + DataTreeModification mockDataTreeModification = mock(DataTreeModification.class); + DataObjectModification mockModification = mock(DataObjectModification.class); + doReturn(mockModification).when(mockDataTreeModification).getRootNode(); + doReturn(new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL, instanceIdentifierMock)) + .when(mockDataTreeModification).getRootPath(); + doReturn(DataObjectModification.ModificationType.WRITE).when(mockModification).getModificationType(); + + Node dataObjectNodeMock = mock(Node.class); doReturn(getNodeKey("testNodeId01")).when(dataObjectNodeMock).getKey(); - map.put(instanceIdentifierMock, dataObjectNodeMock); - doReturn(map).when(asyncDataChangeEventMock).getUpdatedData(); - doReturn(map).when(asyncDataChangeEventMock).getCreatedData(); - nodeIdMock = mock(NodeId.class); + NodeId nodeIdMock = mock(NodeId.class); doReturn(nodeIdMock).when(dataObjectNodeMock).getNodeId(); doReturn("nodeIdPattern1").when(nodeIdMock).getValue(); + + doReturn(dataObjectNodeMock).when(mockModification).getDataAfter(); + + eventSourceTopic.onDataTreeChanged(Collections.singletonList(mockDataTreeModification)); + verify(dataObjectNodeMock).getNodeId(); + verify(nodeIdMock).getValue(); } @Test @@ -115,4 +114,4 @@ public class EventSourceTopicTest { public NodeKey getNodeKey(String nodeId){ return new NodeKey(new NodeId(nodeId)); } -} \ No newline at end of file +} diff --git a/opendaylight/md-sal/messagebus-impl/src/test/java/org/opendaylight/controller/messagebus/app/impl/EventSourceTopologyTest.java b/opendaylight/md-sal/messagebus-impl/src/test/java/org/opendaylight/controller/messagebus/app/impl/EventSourceTopologyTest.java index 68f2a43dd8..8776c996f9 100644 --- a/opendaylight/md-sal/messagebus-impl/src/test/java/org/opendaylight/controller/messagebus/app/impl/EventSourceTopologyTest.java +++ b/opendaylight/md-sal/messagebus-impl/src/test/java/org/opendaylight/controller/messagebus/app/impl/EventSourceTopologyTest.java @@ -16,14 +16,16 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import com.google.common.base.Optional; +import com.google.common.util.concurrent.CheckedFuture; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; import java.util.Map; - import org.junit.Before; import org.junit.Test; import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier; import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction; import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; @@ -49,16 +51,13 @@ import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; -import com.google.common.base.Optional; -import com.google.common.util.concurrent.CheckedFuture; - public class EventSourceTopologyTest { EventSourceTopology eventSourceTopology; DataBroker dataBrokerMock; RpcProviderRegistry rpcProviderRegistryMock; CreateTopicInput createTopicInputMock; - ListenerRegistration listenerRegistrationMock; + ListenerRegistration listenerRegistrationMock; NodeKey nodeKey; RpcRegistration aggregatorRpcReg; @@ -116,10 +115,8 @@ public class EventSourceTopologyTest { doReturn(pattern).when(createTopicInputMock).getNodeIdPattern(); listenerRegistrationMock = mock(ListenerRegistration.class); - doReturn(listenerRegistrationMock).when(dataBrokerMock).registerDataChangeListener(eq(LogicalDatastoreType.OPERATIONAL), - any(InstanceIdentifier.class), - any(EventSourceTopic.class), - eq(DataBroker.DataChangeScope.SUBTREE)); + doReturn(listenerRegistrationMock).when(dataBrokerMock).registerDataTreeChangeListener( + any(DataTreeIdentifier.class), any(EventSourceTopic.class)); ReadOnlyTransaction readOnlyTransactionMock = mock(ReadOnlyTransaction.class); doReturn(readOnlyTransactionMock).when(dataBrokerMock).newReadOnlyTransaction(); @@ -180,7 +177,7 @@ public class EventSourceTopologyTest { Map> localMap = getRoutedRpcRegistrations(); NodeKey nodeKeyMock = mock(NodeKey.class); doReturn(nodeKeyMock).when(eventSourceMock).getSourceNodeKey(); - BindingAwareBroker.RoutedRpcRegistration routedRpcRegistrationMock = (BindingAwareBroker.RoutedRpcRegistration) mock(BindingAwareBroker.RoutedRpcRegistration.class); + BindingAwareBroker.RoutedRpcRegistration routedRpcRegistrationMock = mock(BindingAwareBroker.RoutedRpcRegistration.class); localMap.put(nodeKeyMock, routedRpcRegistrationMock); eventSourceTopology.unRegister(eventSourceMock); verify(routedRpcRegistrationMock, times(1)).close(); @@ -213,4 +210,4 @@ public class EventSourceTopologyTest { return (Map) nesField.get(eventSourceTopology); } -} \ No newline at end of file +} diff --git a/opendaylight/md-sal/samples/clustering-test-app/model/src/main/yang/car.yang b/opendaylight/md-sal/samples/clustering-test-app/model/src/main/yang/car.yang index 50df56f78c..e07a88dd62 100644 --- a/opendaylight/md-sal/samples/clustering-test-app/model/src/main/yang/car.yang +++ b/opendaylight/md-sal/samples/clustering-test-app/model/src/main/yang/car.yang @@ -111,15 +111,6 @@ module car { } } - rpc register-logging-dcl { - description "Registers a basic logging DCL on the cars container. This is useful - for analyzing effects of DCL on a long, flat list."; - } - - rpc unregister-logging-dcls { - description "Unregisters the logging DCL(s) for the cars container."; - } - rpc register-logging-dtcl { description "Registers a basic logging DTCL on the cars container. This is useful for analyzing the effects of DTCL on a long, flat list."; diff --git a/opendaylight/md-sal/samples/clustering-test-app/provider/src/main/java/org/opendaylight/controller/clustering/it/provider/CarDataChangeListener.java b/opendaylight/md-sal/samples/clustering-test-app/provider/src/main/java/org/opendaylight/controller/clustering/it/provider/CarDataChangeListener.java deleted file mode 100644 index 22def4c3b7..0000000000 --- a/opendaylight/md-sal/samples/clustering-test-app/provider/src/main/java/org/opendaylight/controller/clustering/it/provider/CarDataChangeListener.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2016 Brocade Communications Systems, Inc. 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.controller.clustering.it.provider; - -import java.util.Collections; -import java.util.Map; -import java.util.Set; -import org.opendaylight.controller.md.sal.binding.api.DataChangeListener; -import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Provides a basic DCL implementation for performance testing reasons. Emits a summary - * of the changes that occurred. - * - * @author Ryan Goulding (ryandgoulding@gmail.com) - */ -public class CarDataChangeListener implements DataChangeListener { - private static final Logger LOG = LoggerFactory.getLogger(CarDataChangeListener.class); - - @Override - public void onDataChanged(final AsyncDataChangeEvent, DataObject> change) { - if (LOG.isTraceEnabled()) { - LOG.trace("onDataChanged invoked"); - outputChanges(change); - } - } - - private static void outputChanges(final AsyncDataChangeEvent, DataObject> change) { - final Map, DataObject> originalData = change.getOriginalData() != null ? - change.getOriginalData(): Collections., DataObject>emptyMap(); - final Map, DataObject> updatedData = change.getUpdatedData() != null ? - change.getUpdatedData(): Collections., DataObject>emptyMap(); - final Map, DataObject> createdData = change.getCreatedData() != null ? - change.getCreatedData(): Collections., DataObject>emptyMap(); - final Set> removedPaths = change.getRemovedPaths() != null ? - change.getRemovedPaths(): Collections.>emptySet(); - LOG.trace("AsyncDataChangeEvent - originalData={} updatedData={} createdData={} removedPaths={}", - originalData, updatedData, createdData, removedPaths); - } -} diff --git a/opendaylight/md-sal/samples/clustering-test-app/provider/src/main/java/org/opendaylight/controller/clustering/it/provider/CarProvider.java b/opendaylight/md-sal/samples/clustering-test-app/provider/src/main/java/org/opendaylight/controller/clustering/it/provider/CarProvider.java index ea9f7b1d76..803d3b7652 100644 --- a/opendaylight/md-sal/samples/clustering-test-app/provider/src/main/java/org/opendaylight/controller/clustering/it/provider/CarProvider.java +++ b/opendaylight/md-sal/samples/clustering-test-app/provider/src/main/java/org/opendaylight/controller/clustering/it/provider/CarProvider.java @@ -27,7 +27,6 @@ import org.opendaylight.controller.md.sal.common.api.clustering.Entity; import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipChange; import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListener; import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService; -import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker; @@ -244,20 +243,6 @@ public class CarProvider implements CarService { } } - @Override - public Future> registerLoggingDcl() { - LOG_CAR_PROVIDER.info("Registering a new CarDataChangeListener"); - final ListenerRegistration carsDclRegistration = dataProvider.registerDataChangeListener( - LogicalDatastoreType.CONFIGURATION, CARS_IID, new CarDataChangeListener(), - AsyncDataBroker.DataChangeScope.SUBTREE); - - if (carsDclRegistration != null) { - carsDclRegistrations.add(carsDclRegistration); - return RpcResultBuilder.success().buildFuture(); - } - return RpcResultBuilder.failed().buildFuture(); - } - @Override public Future> registerLoggingDtcl() { LOG_CAR_PROVIDER.info("Registering a new CarDataTreeChangeListener"); @@ -271,21 +256,6 @@ public class CarProvider implements CarService { return RpcResultBuilder.failed().buildFuture(); } - @Override - public Future> unregisterLoggingDcls() { - LOG_CAR_PROVIDER.info("Unregistering the CarDataChangeListener(s)"); - synchronized (carsDclRegistrations) { - int numListeners = 0; - for (ListenerRegistration carsDclRegistration : carsDclRegistrations) { - carsDclRegistration.close(); - numListeners++; - } - carsDclRegistrations.clear(); - LOG_CAR_PROVIDER.info("Unregistered {} CarDataChangeListener(s)", numListeners); - } - return RpcResultBuilder.success().buildFuture(); - } - @Override public Future> unregisterLoggingDtcls() { LOG_CAR_PROVIDER.info("Unregistering the CarDataTreeChangeListener(s)");