package org.opendaylight.controller.config.yang.bgpcep.data.change.counter;
import org.opendaylight.controller.config.api.JmxAttributeValidationException;
-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.DataTreeIdentifier;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.protocol.data.change.counter.TopologyDataChangeCounter;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
final TopologyDataChangeCounter counter = new TopologyDataChangeCounter(getDataProviderDependency(), getCounterId());
final InstanceIdentifier<Topology> topoIId = InstanceIdentifier.builder(NetworkTopology.class)
.child(Topology.class, new TopologyKey(new TopologyId(getTopologyName()))).build();
- final ListenerRegistration<DataChangeListener> registration = getDataProviderDependency().registerDataChangeListener(
- LogicalDatastoreType.OPERATIONAL, topoIId, counter, DataBroker.DataChangeScope.SUBTREE);
+ final ListenerRegistration<TopologyDataChangeCounter> registration = getDataProviderDependency().registerDataTreeChangeListener(
+ new DataTreeIdentifier<Topology>(LogicalDatastoreType.OPERATIONAL, topoIId), counter);
return new DataChangeCounterCloseable(counter, registration);
}
private static final class DataChangeCounterCloseable implements AutoCloseable {
private final TopologyDataChangeCounter inner;
- private final ListenerRegistration<DataChangeListener> registration;
+ private final ListenerRegistration<TopologyDataChangeCounter> registration;
public DataChangeCounterCloseable(final TopologyDataChangeCounter inner,
- final ListenerRegistration<DataChangeListener> registration) {
+ final ListenerRegistration<TopologyDataChangeCounter> registration) {
this.inner = inner;
this.registration = registration;
}
package org.opendaylight.protocol.data.change.counter;
+import java.util.Collection;
import java.util.concurrent.atomic.AtomicLong;
import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
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.DataTreeChangeListener;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
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.AsyncTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.TransactionChain;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.data.change.counter.rev160315.data.change.counter.Counter;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.data.change.counter.rev160315.data.change.counter.CounterBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.data.change.counter.rev160315.data.change.counter.CounterKey;
-import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class TopologyDataChangeCounter implements DataChangeListener, TransactionChainListener {
+public class TopologyDataChangeCounter implements DataTreeChangeListener<Topology>, TransactionChainListener {
private static final Logger LOG = LoggerFactory.getLogger(TopologyDataChangeCounter.class);
}
@Override
- public void onDataChanged(final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
+ public void onDataTreeChanged(final Collection<DataTreeModification<Topology>> changes) {
putCount(this.count.incrementAndGet());
LOG.debug("Data change #{} for counter {}", this.count.get(), this.counterId);
}
import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
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.DataTreeChangeListener;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
private static final String NEW_TOPOLOGY_NAME = "new-test";
@Mock
- private CloseableDataBroker dataBorker;
+ private CloseableDataBroker dataBroker;
@Mock
private BindingTransactionChain chain;
@Mock
private WriteTransaction wTx;
@Mock
- private ListenerRegistration<DataChangeListener> registration;
+ private ListenerRegistration<DataTreeChangeListener<?>> registration;
@Before
public void setUp() throws Exception {
Mockito.doNothing().when(this.registration).close();
Mockito.doReturn(null).when(this.wTx).submit();
Mockito.doNothing().when(this.wTx).put(Mockito.any(LogicalDatastoreType.class), Mockito.<InstanceIdentifier<DataChangeCounter>>any(), Mockito.any(DataChangeCounter.class));
- Mockito.doReturn(this.registration).when(this.dataBorker).registerDataChangeListener(Mockito.any(LogicalDatastoreType.class), Mockito.<InstanceIdentifier<?>>any(), Mockito.any(DataChangeListener.class), Mockito.any(DataBroker.DataChangeScope.class));
+ Mockito.doReturn(this.registration).when(this.dataBroker).registerDataTreeChangeListener(Mockito.any(DataTreeIdentifier.class), Mockito.any(DataTreeChangeListener.class));
Mockito.doNothing().when(this.wTx).delete(Mockito.any(LogicalDatastoreType.class), Mockito.<InstanceIdentifier<?>>any());
- Mockito.doReturn(this.chain).when(this.dataBorker).createTransactionChain(Mockito.any(TransactionChainListener.class));
+ Mockito.doReturn(this.chain).when(this.dataBroker).createTransactionChain(Mockito.any(TransactionChainListener.class));
Mockito.doReturn(this.wTx).when(this.chain).newWriteOnlyTransaction();
- Mockito.doReturn(this.wTx).when(this.dataBorker).newWriteOnlyTransaction();
+ Mockito.doReturn(this.wTx).when(this.dataBroker).newWriteOnlyTransaction();
Mockito.doNothing().when(this.chain).close();
- Mockito.doNothing().when(this.dataBorker).close();
+ Mockito.doNothing().when(this.dataBroker).close();
super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(this.mockedContext, new DataChangeCounterImplModuleFactory(), new MockDataBrokerModuleFct()));
}
@Override
public AutoCloseable getInstance() {
- return DataChangeCounterImplModuleTest.this.dataBorker;
+ return DataChangeCounterImplModuleTest.this.dataBroker;
}
@Override
assertTrue(count.isPresent());
assertEquals(0, count.get().longValue());
- counter.onDataChanged(null);
+ counter.onDataTreeChanged(null);
final Optional<Long> countAfterDataChange = getCount(COUNTER_ID1);
assertTrue(countAfterDataChange.isPresent());
assertEquals(1, countAfterDataChange.get().longValue());
assertTrue(count2.isPresent());
assertEquals(0, count2.get().longValue());
- counter1.onDataChanged(null);
+ counter1.onDataTreeChanged(null);
final Optional<Long> countAfterDataChange1 = getCount(COUNTER_ID1);
assertTrue(countAfterDataChange1.isPresent());
assertEquals(1, countAfterDataChange1.get().longValue());
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.JdkFutureAdapters;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import java.util.Map;
import java.util.Set;
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.DataTreeModification;
import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
-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.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.nt.l3.unicast.igp.topology.rev131021.igp.termination.point.attributes.igp.termination.point.attributes.termination.point.type.IpBuilder;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public final class NodeChangedListener implements DataChangeListener {
+public final class NodeChangedListener implements DataTreeChangeListener<Node> {
private static final Logger LOG = LoggerFactory.getLogger(NodeChangedListener.class);
private final InstanceIdentifier<Topology> target;
private final DataBroker dataProvider;
}
@Override
- public void onDataChanged(final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
+ public void onDataTreeChanged(final Collection<DataTreeModification<Node>> changes) {
final ReadWriteTransaction trans = this.dataProvider.newReadWriteTransaction();
final Set<InstanceIdentifier<ReportedLsp>> lsps = new HashSet<>();
final Set<InstanceIdentifier<Node>> nodes = new HashSet<>();
- // Categorize reported identifiers
- for (final InstanceIdentifier<?> i : change.getRemovedPaths()) {
- categorizeIdentifier(i, lsps, nodes);
- }
- for (final InstanceIdentifier<?> i : change.getUpdatedData().keySet()) {
- categorizeIdentifier(i, lsps, nodes);
- }
- for (final InstanceIdentifier<?> i : change.getCreatedData().keySet()) {
- categorizeIdentifier(i, lsps, nodes);
- }
+ final Map<InstanceIdentifier<?>, DataObject> original = new HashMap<>();
+ final Map<InstanceIdentifier<?>, DataObject> updated = new HashMap<>();
+ final Map<InstanceIdentifier<?>, DataObject> created = new HashMap<>();
- // Get the subtrees
- final Map<InstanceIdentifier<?>, ? extends DataObject> o = change.getOriginalData();
- final Map<InstanceIdentifier<?>, DataObject> u = change.getUpdatedData();
- final Map<InstanceIdentifier<?>, DataObject> c = change.getCreatedData();
+ for (final DataTreeModification<?> change : changes) {
+ final InstanceIdentifier<?> iid = change.getRootPath().getRootIdentifier();
+ final DataObjectModification<?> rootNode = change.getRootNode();
+ handleChangedNode(rootNode, iid, lsps, nodes, original, updated, created);
+ }
// Now walk all nodes, check for removals/additions and cascade them to LSPs
- for (final InstanceIdentifier<Node> i : nodes) {
- enumerateLsps(i, (Node) o.get(i), lsps);
- enumerateLsps(i, (Node) u.get(i), lsps);
- enumerateLsps(i, (Node) c.get(i), lsps);
+ for (final InstanceIdentifier<Node> iid : nodes) {
+ enumerateLsps(iid, (Node) original.get(iid), lsps);
+ enumerateLsps(iid, (Node) updated.get(iid), lsps);
+ enumerateLsps(iid, (Node) created.get(iid), lsps);
}
// We now have list of all affected LSPs. Walk them create/remove them
- updateTransaction(trans, lsps, o, u, c);
+ updateTransaction(trans, lsps, original, updated, created);
Futures.addCallback(JdkFutureAdapters.listenInPoolThread(trans.submit()), new FutureCallback<Void>() {
@Override
});
}
+ private void handleChangedNode(final DataObjectModification<?> changedNode, final InstanceIdentifier<?> iid,
+ final Set<InstanceIdentifier<ReportedLsp>> lsps, final Set<InstanceIdentifier<Node>> nodes,
+ final Map<InstanceIdentifier<?>, DataObject> original, final Map<InstanceIdentifier<?>, DataObject> updated,
+ final Map<InstanceIdentifier<?>, DataObject> created) {
+
+ // Categorize reported identifiers
+ categorizeIdentifier(iid, lsps, nodes);
+
+ // Get the subtrees
+ switch (changedNode.getModificationType()) {
+ case DELETE:
+ original.put(iid, changedNode.getDataBefore());
+ break;
+ case SUBTREE_MODIFIED:
+ original.put(iid, changedNode.getDataBefore());
+ updated.put(iid, changedNode.getDataAfter());
+ break;
+ case WRITE:
+ created.put(iid, changedNode.getDataAfter());
+ break;
+ default:
+ throw new IllegalArgumentException("Unhandled modification type " + changedNode.getModificationType());
+ }
+
+ for (DataObjectModification<? extends DataObject> child : changedNode.getModifiedChildren()) {
+ final List<PathArgument> pathArguments = new ArrayList<>();
+ for (PathArgument pathArgument : iid.getPathArguments()) {
+ pathArguments.add(pathArgument);
+ }
+ pathArguments.add(child.getIdentifier());
+ final InstanceIdentifier<?> childIID = InstanceIdentifier.create(pathArguments);
+ handleChangedNode(child, childIID, lsps, nodes, original, updated, created);
+ }
+ }
+
private void updateTransaction(final ReadWriteTransaction trans, final Set<InstanceIdentifier<ReportedLsp>> lsps,
final Map<InstanceIdentifier<?>, ? extends DataObject> old, final Map<InstanceIdentifier<?>, DataObject> updated,
final Map<InstanceIdentifier<?>, DataObject> created) {
import org.opendaylight.bgpcep.topology.DefaultTopologyReference;
import org.opendaylight.bgpcep.topology.TopologyReference;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
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.TopologyId;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
public final class PCEPTunnelTopologyProvider implements AutoCloseable {
- private final ListenerRegistration<DataChangeListener> reg;
+ private final ListenerRegistration<NodeChangedListener> reg;
private final TopologyReference ref;
- private PCEPTunnelTopologyProvider(final InstanceIdentifier<Topology> dst, final ListenerRegistration<DataChangeListener> reg) {
+ private PCEPTunnelTopologyProvider(final InstanceIdentifier<Topology> dst, final ListenerRegistration<NodeChangedListener> reg) {
this.ref = new DefaultTopologyReference(dst);
this.reg = Preconditions.checkNotNull(reg);
}
final InstanceIdentifier<Topology> sourceTopology, final TopologyId targetTopology) {
final InstanceIdentifier<Topology> dst = InstanceIdentifier.builder(NetworkTopology.class).child(Topology.class,
new TopologyKey(targetTopology)).build();
- final NodeChangedListener ncl = new NodeChangedListener(dataProvider, sourceTopology.firstKeyOf(Topology.class, TopologyKey.class).getTopologyId(), dst);
+ final NodeChangedListener ncl = new NodeChangedListener(dataProvider, sourceTopology.firstKeyOf(Topology.class).getTopologyId(), dst);
final InstanceIdentifier<Node> src = sourceTopology.child(Node.class);
- final ListenerRegistration<DataChangeListener> reg = dataProvider.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL, src, ncl, DataChangeScope.SUBTREE);
+ final ListenerRegistration<NodeChangedListener> reg = dataProvider.registerDataTreeChangeListener(new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL, src), ncl);
return new PCEPTunnelTopologyProvider(dst, reg);
}
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
-import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
import org.opendaylight.controller.md.sal.binding.api.ReadTransaction;
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.binding.test.AbstractDataBrokerTest;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
private static final InstanceIdentifier<Topology> PCEP_TOPO_IID = InstanceIdentifier.builder(NetworkTopology.class).child(Topology.class, new TopologyKey(PCEP_TOPOLOGY_ID)).build();
private static final InstanceIdentifier<Topology> TUNNEL_TOPO_IID = InstanceIdentifier.builder(NetworkTopology.class).child(Topology.class, new TopologyKey(TUNNEL_TOPOLOGY_ID)).build();
- private ListenerRegistration<DataChangeListener> listenerRegistration;
+ private ListenerRegistration<NodeChangedListener> listenerRegistration;
@Before
public void setUp() throws TransactionCommitFailedException {
wTx.put(LogicalDatastoreType.OPERATIONAL, TUNNEL_TOPO_IID, new TopologyBuilder().setKey(new TopologyKey(TUNNEL_TOPOLOGY_ID)).setTopologyId(TUNNEL_TOPOLOGY_ID).build(), true);
wTx.submit().checkedGet();
final NodeChangedListener nodeListener = new NodeChangedListener(getDataBroker(), PCEP_TOPOLOGY_ID, TUNNEL_TOPO_IID);
- this.listenerRegistration = getDataBroker().registerDataChangeListener(LogicalDatastoreType.OPERATIONAL, PCEP_TOPO_IID.child(Node.class), nodeListener, DataChangeScope.SUBTREE);
+ this.listenerRegistration = getDataBroker().registerDataTreeChangeListener(new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL, PCEP_TOPO_IID.child(Node.class)), nodeListener);
}
@Test