<artifactId>mockito-all</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<scm>
<connection>scm:git:ssh://git.opendaylight.org:29418/openflowplugin.git</connection>
import java.util.concurrent.Callable;
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.ReadWriteTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.openflowplugin.common.wait.SimpleTaskRetryLooper;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public abstract class DataChangeListenerImpl implements DataChangeListener, AutoCloseable {
+public abstract class DataChangeListenerImpl<T extends DataObject> implements DataTreeChangeListener<T>, AutoCloseable {
private static final Logger LOG = LoggerFactory.getLogger(DataChangeListenerImpl.class);
private static final long STARTUP_LOOP_TICK = 500L;
private static final int STARTUP_LOOP_MAX_RETRIES = 8;
- protected final ListenerRegistration<DataChangeListener> dataChangeListenerRegistration;
+ protected final ListenerRegistration<DataTreeChangeListener> dataChangeListenerRegistration;
protected OperationProcessor operationProcessor;
/**
*/
protected static final InstanceIdentifier<Topology> II_TO_TOPOLOGY =
InstanceIdentifier
- .builder(NetworkTopology.class)
- .child(Topology.class, new TopologyKey(new TopologyId(FlowCapableTopologyProvider.TOPOLOGY_ID)))
- .build();
+ .create(NetworkTopology.class)
+ .child(Topology.class, new TopologyKey(new TopologyId(FlowCapableTopologyProvider.TOPOLOGY_ID)));
-
- /**
- *
- */
- public DataChangeListenerImpl(final OperationProcessor operationProcessor, final DataBroker dataBroker,
- final InstanceIdentifier<?> ii) {
- SimpleTaskRetryLooper looper = new SimpleTaskRetryLooper(STARTUP_LOOP_TICK, STARTUP_LOOP_MAX_RETRIES);
+ public DataChangeListenerImpl(final OperationProcessor operationProcessor,
+ final DataBroker dataBroker,
+ final InstanceIdentifier<T> ii) {
+ final DataTreeIdentifier<T> identifier = new DataTreeIdentifier(LogicalDatastoreType.OPERATIONAL, ii);
+ final SimpleTaskRetryLooper looper = new SimpleTaskRetryLooper(STARTUP_LOOP_TICK, STARTUP_LOOP_MAX_RETRIES);
try {
- dataChangeListenerRegistration = looper.loopUntilNoException(new Callable<ListenerRegistration<DataChangeListener>>() {
+ dataChangeListenerRegistration = looper.loopUntilNoException(new Callable<ListenerRegistration<DataTreeChangeListener>>() {
@Override
- public ListenerRegistration<DataChangeListener> call() throws Exception {
- return dataBroker.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL, ii,
- DataChangeListenerImpl.this, AsyncDataBroker.DataChangeScope.BASE);
-
+ public ListenerRegistration<DataTreeChangeListener> call() throws Exception {
+ return dataBroker.registerDataTreeChangeListener(identifier, DataChangeListenerImpl.this);
}
});
} catch (Exception e) {
- LOG.warn("data listener registration failed: {}", e.getMessage());
- LOG.debug("data listener registration failed.. ", e);
+ LOG.error("Data listener registration failed!");
throw new IllegalStateException("TopologyManager startup fail! TM bundle needs restart.", e);
}
-
this.operationProcessor = operationProcessor;
}
dataChangeListenerRegistration.close();
}
- protected <T extends DataObject> void sendToTransactionChain(final T node,
- final InstanceIdentifier<T> iiToTopologyNode) {
+ protected <T extends DataObject> void sendToTransactionChain(final T node, final InstanceIdentifier<T> iiToTopologyNode) {
operationProcessor.enqueueOperation(new TopologyOperation() {
-
@Override
public void applyOperation(ReadWriteTransaction transaction) {
transaction.merge(LogicalDatastoreType.OPERATIONAL, iiToTopologyNode, node, true);
nodeKeyInTopology).build();
}
- protected NodeId provideTopologyNodeId(InstanceIdentifier<?> iiToNodeInInventory) {
+ protected NodeId provideTopologyNodeId(InstanceIdentifier<T> iiToNodeInInventory) {
final NodeKey inventoryNodeKey = iiToNodeInInventory.firstKeyOf(Node.class, NodeKey.class);
if (inventoryNodeKey != null) {
return new NodeId(inventoryNodeKey.getId().getValue());
*/
package org.opendaylight.openflowplugin.applications.topology.manager;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
+import java.util.Collection;
+import javax.annotation.Nonnull;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+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.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.topology.inventory.rev131030.InventoryNodeBuilder;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
-import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class NodeChangeListenerImpl extends DataChangeListenerImpl {
+public class NodeChangeListenerImpl extends DataChangeListenerImpl<FlowCapableNode> {
private static final Logger LOG = LoggerFactory.getLogger(NodeChangeListenerImpl.class);
public NodeChangeListenerImpl(final DataBroker dataBroker, final OperationProcessor operationProcessor) {
- // TODO: listener on FlowCapableNode. what if node id in Node.class is changed (it won't be caught by this
- // listener)
+ // TODO: listener on FlowCapableNode. what if node id in Node.class is changed (it won't be caught by this listener)
super(operationProcessor, dataBroker, InstanceIdentifier.builder(Nodes.class).child(Node.class)
.augmentation(FlowCapableNode.class).build());
}
@Override
- public void onDataChanged(final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
- processAddedNode(change.getCreatedData());
- // processUpdatedNode(change.getUpdatedData());
- processRemovedNode(change.getRemovedPaths());
- }
-
- /**
- * @param removedNodes
- */
- private void processRemovedNode(final Set<InstanceIdentifier<?>> removedNodes) {
- for (InstanceIdentifier<?> removedNode : removedNodes) {
- final NodeId nodeId = provideTopologyNodeId(removedNode);
- final InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node> iiToTopologyRemovedNode = provideIIToTopologyNode(nodeId);
- if (iiToTopologyRemovedNode != null) {
- operationProcessor.enqueueOperation(new TopologyOperation() {
-
- @Override
- public void applyOperation(final ReadWriteTransaction transaction) {
- transaction.delete(LogicalDatastoreType.OPERATIONAL, iiToTopologyRemovedNode);
- TopologyManagerUtil.removeAffectedLinks(nodeId, transaction, II_TO_TOPOLOGY);
- }
- });
- } else {
- LOG.debug("Instance identifier to inventory wasn't translated to topology while deleting node.");
+ public void onDataTreeChanged(@Nonnull final Collection<DataTreeModification<FlowCapableNode>> modifications) {
+ for (DataTreeModification modification : modifications) {
+ switch (modification.getRootNode().getModificationType()) {
+ case WRITE:
+ processAddedNode(modification);
+ break;
+ case SUBTREE_MODIFIED:
+ // NOOP
+ break;
+ case DELETE:
+ processRemovedNode(modification);
+ break;
+ default:
+ throw new IllegalArgumentException("Unhandled modification type: {}" +
+ modification.getRootNode().getModificationType());
}
}
}
-// /**
-// * @param updatedData
-// */
-// private void processUpdatedNode(Map<InstanceIdentifier<?>, DataObject> updatedData) {
-// //TODO: only node id is used from incoming data object.
-// //if it is changed what should happen? Listener is on FlowCapableNode so change
-// //of node id (only data which are used) isn't caught.
-// }
-
- /**
- * @param addedDatas
- */
- private void processAddedNode(final Map<InstanceIdentifier<?>, DataObject> addedDatas) {
- for (Entry<InstanceIdentifier<?>, DataObject> addedData : addedDatas.entrySet()) {
- createData(addedData.getKey());
+ private void processRemovedNode(final DataTreeModification<FlowCapableNode> modification) {
+ final InstanceIdentifier<FlowCapableNode> iiToNodeInInventory = modification.getRootPath().getRootIdentifier();
+ final NodeId nodeId = provideTopologyNodeId(iiToNodeInInventory);
+ final InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node> iiToTopologyRemovedNode = provideIIToTopologyNode(nodeId);
+ if (iiToTopologyRemovedNode != null) {
+ operationProcessor.enqueueOperation(new TopologyOperation() {
+ @Override
+ public void applyOperation(final ReadWriteTransaction transaction) {
+ transaction.delete(LogicalDatastoreType.OPERATIONAL, iiToTopologyRemovedNode);
+ TopologyManagerUtil.removeAffectedLinks(nodeId, transaction, II_TO_TOPOLOGY);
+ }
+ });
+ } else {
+ LOG.debug("Instance identifier to inventory wasn't translated to topology while deleting node.");
}
}
- protected void createData(final InstanceIdentifier<?> iiToNodeInInventory) {
+ private void processAddedNode(final DataTreeModification<FlowCapableNode> modification) {
+ final InstanceIdentifier<FlowCapableNode> iiToNodeInInventory = modification.getRootPath().getRootIdentifier();
final NodeId nodeIdInTopology = provideTopologyNodeId(iiToNodeInInventory);
if (nodeIdInTopology != null) {
final InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node> iiToTopologyNode = provideIIToTopologyNode(nodeIdInTopology);
}
}
- /**
- * @param nodeIdInTopology
- * @param iiToNodeInInventory
- * @return Node
- */
- private static org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node prepareTopologyNode(final NodeId nodeIdInTopology, final InstanceIdentifier<?> iiToNodeInInventory) {
+ private static org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node
+ prepareTopologyNode(final NodeId nodeIdInTopology, final InstanceIdentifier<FlowCapableNode> iiToNodeInInventory) {
final InventoryNode inventoryNode = new InventoryNodeBuilder()
- .setInventoryNodeRef(new NodeRef(iiToNodeInInventory.firstIdentifierOf(Node.class)))
- .build();
+ .setInventoryNodeRef(new NodeRef(iiToNodeInInventory.firstIdentifierOf(Node.class)))
+ .build();
final NodeBuilder topologyNodeBuilder = new NodeBuilder();
topologyNodeBuilder.setNodeId(nodeIdInTopology);
return topologyNodeBuilder.build();
}
+
}
\ No newline at end of file
package org.opendaylight.openflowplugin.applications.topology.manager;
import com.google.common.base.Optional;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
+import java.util.Collection;
+import javax.annotation.Nonnull;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+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.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
-import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class TerminationPointChangeListenerImpl extends DataChangeListenerImpl {
+public class TerminationPointChangeListenerImpl extends DataChangeListenerImpl<FlowCapableNodeConnector> {
private static final Logger LOG = LoggerFactory.getLogger(TerminationPointChangeListenerImpl.class);
public TerminationPointChangeListenerImpl(final DataBroker dataBroker, final OperationProcessor operationProcessor) {
}
@Override
- public void onDataChanged(final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
- processAddedTerminationPoints(change.getCreatedData());
- processUpdatedTerminationPoints(change.getUpdatedData());
- processRemovedTerminationPoints(change.getRemovedPaths());
+ public void onDataTreeChanged(@Nonnull Collection<DataTreeModification<FlowCapableNodeConnector>> modifications) {
+ for (DataTreeModification<FlowCapableNodeConnector> modification : modifications) {
+ switch (modification.getRootNode().getModificationType()) {
+ case WRITE:
+ processAddedTerminationPoints(modification);
+ break;
+ case SUBTREE_MODIFIED:
+ processUpdatedTerminationPoints(modification);
+ break;
+ case DELETE:
+ processRemovedTerminationPoints(modification);
+ break;
+ default:
+ throw new IllegalArgumentException("Unhandled modification type: {}" +
+ modification.getRootNode().getModificationType());
+ }
+ }
}
- /**
- * @param removedPaths
- */
- private void processRemovedTerminationPoints(final Set<InstanceIdentifier<?>> removedNodes) {
- for (final InstanceIdentifier<?> removedNode : removedNodes) {
- final TpId terminationPointId = provideTopologyTerminationPointId(removedNode);
- final InstanceIdentifier<TerminationPoint> iiToTopologyTerminationPoint = provideIIToTopologyTerminationPoint(
- terminationPointId, removedNode);
-
- if (iiToTopologyTerminationPoint != null) {
- final InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node> node = iiToTopologyTerminationPoint.firstIdentifierOf(org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node.class);
- operationProcessor.enqueueOperation(new TopologyOperation() {
-
- @Override
- public void applyOperation(final ReadWriteTransaction transaction) {
- Optional<org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node> nodeOptional = Optional.absent();
- try {
- nodeOptional = transaction.read(LogicalDatastoreType.OPERATIONAL, node).checkedGet();
- } catch (ReadFailedException e) {
- LOG.warn("Error occured when trying to read NodeConnector: {}", e.getMessage());
- LOG.debug("Error occured when trying to read NodeConnector.. ", e);
- }
- if (nodeOptional.isPresent()) {
- TopologyManagerUtil.removeAffectedLinks(terminationPointId, transaction, II_TO_TOPOLOGY);
- transaction.delete(LogicalDatastoreType.OPERATIONAL, iiToTopologyTerminationPoint);
- }
+ private void processRemovedTerminationPoints(final DataTreeModification<FlowCapableNodeConnector> modification) {
+ final InstanceIdentifier<FlowCapableNodeConnector> removedNode = modification.getRootPath().getRootIdentifier();
+ final TpId terminationPointId = provideTopologyTerminationPointId(removedNode);
+ final InstanceIdentifier<TerminationPoint> iiToTopologyTerminationPoint = provideIIToTopologyTerminationPoint(
+ terminationPointId, removedNode);
+
+ if (iiToTopologyTerminationPoint != null) {
+ final InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node> node = iiToTopologyTerminationPoint.firstIdentifierOf(org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node.class);
+ operationProcessor.enqueueOperation(new TopologyOperation() {
+ @Override
+ public void applyOperation(final ReadWriteTransaction transaction) {
+ Optional<org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node> nodeOptional = Optional.absent();
+ try {
+ nodeOptional = transaction.read(LogicalDatastoreType.OPERATIONAL, node).checkedGet();
+ } catch (ReadFailedException e) {
+ LOG.warn("Error occured when trying to read NodeConnector: {}", e.getMessage());
+ LOG.debug("Error occured when trying to read NodeConnector.. ", e);
}
- });
-
- } else {
- LOG.debug("Instance identifier to inventory wasn't translated to topology while deleting termination point.");
- }
+ if (nodeOptional.isPresent()) {
+ TopologyManagerUtil.removeAffectedLinks(terminationPointId, transaction, II_TO_TOPOLOGY);
+ transaction.delete(LogicalDatastoreType.OPERATIONAL, iiToTopologyTerminationPoint);
+ }
+ }
+ });
+ } else {
+ LOG.debug("Instance identifier to inventory wasn't translated to topology while deleting termination point.");
}
}
- /**
- * @param updatedData
- */
- private void processUpdatedTerminationPoints(final Map<InstanceIdentifier<?>, DataObject> updatedData) {
+ private void processUpdatedTerminationPoints(final DataTreeModification<FlowCapableNodeConnector> modification) {
// TODO Auto-generated method stub
}
- private void processAddedTerminationPoints(final Map<InstanceIdentifier<?>, DataObject> addedDatas) {
- for (Entry<InstanceIdentifier<?>, DataObject> addedData : addedDatas.entrySet()) {
- createData(addedData.getKey(), addedData.getValue());
- }
- }
-
- protected void createData(final InstanceIdentifier<?> iiToNodeInInventory, final DataObject data) {
+ private void processAddedTerminationPoints(final DataTreeModification<FlowCapableNodeConnector> modification) {
+ final InstanceIdentifier<FlowCapableNodeConnector> iiToNodeInInventory = modification.getRootPath().getRootIdentifier();
TpId terminationPointIdInTopology = provideTopologyTerminationPointId(iiToNodeInInventory);
if (terminationPointIdInTopology != null) {
InstanceIdentifier<TerminationPoint> iiToTopologyTerminationPoint = provideIIToTopologyTerminationPoint(
terminationPointIdInTopology, iiToNodeInInventory);
TerminationPoint point = prepareTopologyTerminationPoint(terminationPointIdInTopology, iiToNodeInInventory);
sendToTransactionChain(point, iiToTopologyTerminationPoint);
- if (data instanceof FlowCapableNodeConnector) {
- removeLinks((FlowCapableNodeConnector) data, point);
- }
-
+ removeLinks(modification.getRootNode().getDataAfter(), point);
} else {
LOG.debug("Inventory node connector key is null. Data can't be written to topology termination point");
}
}
- /**
- * @param data
- */
private void removeLinks(final FlowCapableNodeConnector flowCapNodeConnector, final TerminationPoint point) {
operationProcessor.enqueueOperation(new TopologyOperation() {
-
@Override
public void applyOperation(final ReadWriteTransaction transaction) {
if ((flowCapNodeConnector.getState() != null && flowCapNodeConnector.getState().isLinkDown())
}
private static TerminationPoint prepareTopologyTerminationPoint(final TpId terminationPointIdInTopology,
- final InstanceIdentifier<?> iiToNodeInInventory) {
+ final InstanceIdentifier<FlowCapableNodeConnector> iiToNodeInInventory) {
final InventoryNodeConnector inventoryNodeConnector = new InventoryNodeConnectorBuilder()
- .setInventoryNodeConnectorRef(
- new NodeConnectorRef(iiToNodeInInventory.firstIdentifierOf(NodeConnector.class))).build();
-
+ .setInventoryNodeConnectorRef(new NodeConnectorRef(iiToNodeInInventory.firstIdentifierOf(NodeConnector.class))).build();
final TerminationPointBuilder terminationPointBuilder = new TerminationPointBuilder();
terminationPointBuilder.setTpId(terminationPointIdInTopology);
terminationPointBuilder.addAugmentation(InventoryNodeConnector.class, inventoryNodeConnector);
return terminationPointBuilder.build();
}
- /**
- * @param terminationPointIdInTopology
- * @return
- */
private InstanceIdentifier<TerminationPoint> provideIIToTopologyTerminationPoint(final TpId terminationPointIdInTopology,
- final InstanceIdentifier<?> iiToNodeInInventory) {
+ final InstanceIdentifier<FlowCapableNodeConnector> iiToNodeInInventory) {
NodeId nodeIdInTopology = provideTopologyNodeId(iiToNodeInInventory);
if (terminationPointIdInTopology != null && nodeIdInTopology != null) {
InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node> iiToTopologyNode = provideIIToTopologyNode(nodeIdInTopology);
}
}
- /**
- * @param iiToNodeInInventory
- * @return
- */
- private static TpId provideTopologyTerminationPointId(final InstanceIdentifier<?> iiToNodeInInventory) {
+ private static TpId provideTopologyTerminationPointId(final InstanceIdentifier<FlowCapableNodeConnector> iiToNodeInInventory) {
NodeConnectorKey inventoryNodeConnectorKey = iiToNodeInInventory.firstKeyOf(NodeConnector.class,
NodeConnectorKey.class);
if (inventoryNodeConnectorKey != null) {
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
-import java.util.Collections;
-import java.util.Map;
-import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.junit.After;
import org.mockito.MockitoAnnotations;
import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification.ModificationType;
+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.controller.md.sal.common.api.data.TransactionChainListener;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnectorBuilder;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-/**
- * @author joe
- *
- */
public abstract class DataChangeListenerBase {
@Mock
@Mock
protected BindingTransactionChain mockTxChain;
- @Mock
- protected AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> mockedDataChangeListener;
-
private OperationProcessor processor;
protected InstanceIdentifier<Topology> topologyIID;
executor.shutdownNow();
}
- protected void mockDataChangeListener(Map<InstanceIdentifier<?>,DataObject> createdData, Map<InstanceIdentifier<?>, DataObject> updatedData, Set<?> removedPaths) {
- doReturn(createdData == null ? Collections.emptyMap() : createdData).when(mockedDataChangeListener).getCreatedData();
- doReturn(updatedData == null ? Collections.emptyMap() : updatedData).when(mockedDataChangeListener).getUpdatedData();
- doReturn(removedPaths == null ? Collections.emptySet() : removedPaths).when(mockedDataChangeListener).getRemovedPaths();
- }
-
protected FlowCapableNodeConnector provideFlowCapableNodeConnector(final boolean isLinkDown, final boolean isPortDown) {
FlowCapableNodeConnectorBuilder builder = new FlowCapableNodeConnectorBuilder();
builder.setState(new StateBuilder().setLinkDown(isLinkDown).build());
builder.setConfiguration(new PortConfig(true, true, true, isPortDown));
return builder.build();
}
+
+ protected <T extends DataObject> DataTreeModification setupDataTreeChange(final ModificationType type,
+ final InstanceIdentifier<T> ii) {
+ final DataTreeModification dataTreeModification = mock(DataTreeModification.class);
+ final DataTreeIdentifier identifier = new DataTreeIdentifier(LogicalDatastoreType.OPERATIONAL, ii);
+ when(dataTreeModification.getRootNode()).thenReturn(mock(DataObjectModification.class));
+ when(dataTreeModification.getRootNode().getModificationType()).thenReturn(type);
+ when(dataTreeModification.getRootPath()).thenReturn(identifier);
+ when(dataTreeModification.getRootNode().getDataAfter()).thenReturn(mock(FlowCapableNodeConnector.class));
+ return dataTreeModification;
+ }
+
}
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
+import static org.opendaylight.controller.md.sal.binding.api.DataObjectModification.ModificationType.DELETE;
+import static org.opendaylight.controller.md.sal.binding.api.DataObjectModification.ModificationType.WRITE;
import static org.opendaylight.openflowplugin.applications.topology.manager.TestUtils.assertDeletedIDs;
import static org.opendaylight.openflowplugin.applications.topology.manager.TestUtils.newDestNode;
import static org.opendaylight.openflowplugin.applications.topology.manager.TestUtils.newInvNodeKey;
import java.util.concurrent.CountDownLatch;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
+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.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
-import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-/**
- * @author joe
- *
- */
public class NodeChangeListenerImplTest extends DataChangeListenerBase {
@SuppressWarnings({ "rawtypes" })
@Test
doReturn(mockTx1).when(mockTxChain).newReadWriteTransaction();
- mockDataChangeListener(null, null, Collections.singleton(invNodeID));
- nodeChangeListener.onDataChanged(mockedDataChangeListener);
+ DataTreeModification dataTreeModification = setupDataTreeChange(DELETE, invNodeID);
+ nodeChangeListener.onDataTreeChanged(Collections.singleton(dataTreeModification));
waitForSubmit(submitLatch1);
doReturn(mockTx).when(mockTxChain).newReadWriteTransaction();
- mockDataChangeListener(null,null,Collections.singleton(invNodeID));
- nodeChangeListener.onDataChanged(mockedDataChangeListener);
+ DataTreeModification dataTreeModification = setupDataTreeChange(DELETE, invNodeID);
+ nodeChangeListener.onDataTreeChanged(Collections.singleton(dataTreeModification));
waitForSubmit(submitLatch);
CountDownLatch submitLatch = setupStubbedSubmit(mockTx);
doReturn(mockTx).when(mockTxChain).newReadWriteTransaction();
- mockDataChangeListener(Collections.<InstanceIdentifier<?>, DataObject> singletonMap(
- invNodeID, null), null, null);
- nodeChangeListener.onDataChanged(mockedDataChangeListener);
+ DataTreeModification dataTreeModification = setupDataTreeChange(WRITE, invNodeID);
+ nodeChangeListener.onDataTreeChanged(Collections.singleton(dataTreeModification));
waitForSubmit(submitLatch);
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.opendaylight.controller.md.sal.binding.api.DataObjectModification.ModificationType.DELETE;
+import static org.opendaylight.controller.md.sal.binding.api.DataObjectModification.ModificationType.WRITE;
import static org.opendaylight.openflowplugin.applications.topology.manager.TestUtils.assertDeletedIDs;
import static org.opendaylight.openflowplugin.applications.topology.manager.TestUtils.newDestTp;
import static org.opendaylight.openflowplugin.applications.topology.manager.TestUtils.newInvNodeConnKey;
import java.util.concurrent.CountDownLatch;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
+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.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
-import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-/**
- * @author joe
- *
- */
public class TerminationPointChangeListenerImplTest extends DataChangeListenerBase{
@SuppressWarnings("rawtypes")
@Test
doReturn(mockTx1).when(mockTxChain).newReadWriteTransaction();
- mockDataChangeListener(null, null, Collections.singleton(invNodeConnID));
- terminationPointListener.onDataChanged(mockedDataChangeListener);
+ DataTreeModification dataTreeModification = setupDataTreeChange(DELETE, invNodeConnID);
+ terminationPointListener.onDataTreeChanged(Collections.singleton(dataTreeModification));
waitForSubmit(submitLatch1);
doReturn(mockTx).when(mockTxChain).newReadWriteTransaction();
- mockDataChangeListener(null, null, Collections.singleton(invNodeConnID));
- terminationPointListener.onDataChanged(mockedDataChangeListener);
+ DataTreeModification dataTreeModification = setupDataTreeChange(DELETE, invNodeConnID);
+ terminationPointListener.onDataTreeChanged(Collections.singleton(dataTreeModification));
waitForSubmit(submitLatch);
CountDownLatch submitLatch = setupStubbedSubmit(mockTx);
doReturn(mockTx).when(mockTxChain).newReadWriteTransaction();
- mockDataChangeListener(Collections.<InstanceIdentifier<?>, DataObject> singletonMap(
- invNodeConnID, null), null, null);
- terminationPointListener.onDataChanged(mockedDataChangeListener);
+ DataTreeModification dataTreeModification = setupDataTreeChange(WRITE, invNodeConnID);
+ terminationPointListener.onDataTreeChanged(Collections.singleton(dataTreeModification));
waitForSubmit(submitLatch);
doReturn(mockTx).when(mockTxChain).newReadWriteTransaction();
- mockDataChangeListener(Collections.<InstanceIdentifier<?>, DataObject> singletonMap(
- invNodeConnID, provideFlowCapableNodeConnector(true, false)), null, null);
- terminationPointListener.onDataChanged(mockedDataChangeListener);
+ DataTreeModification dataTreeModification = setupDataTreeChange(WRITE, invNodeConnID);
+ when(dataTreeModification.getRootNode().getDataAfter()).thenReturn(provideFlowCapableNodeConnector(true, false));
+ terminationPointListener.onDataTreeChanged(Collections.singleton(dataTreeModification));
waitForDeletes(1, deleteLatch);
doReturn(mockTx).when(mockTxChain).newReadWriteTransaction();
- mockDataChangeListener(Collections.<InstanceIdentifier<?>, DataObject> singletonMap(
- invNodeConnID, provideFlowCapableNodeConnector(false, true)), null, null);
- terminationPointListener.onDataChanged(mockedDataChangeListener);
+ DataTreeModification dataTreeModification = setupDataTreeChange(WRITE, invNodeConnID);
+ when(dataTreeModification.getRootNode().getDataAfter()).thenReturn(provideFlowCapableNodeConnector(false, true));
+ terminationPointListener.onDataTreeChanged(Collections.singleton(dataTreeModification));
waitForDeletes(1, deleteLatch);
}
}
- static void setReadFutureAsync(final Topology topology,
- final SettableFuture<Optional<Topology>> readFuture) {
+ static void setReadFutureAsync(final Topology topology, final SettableFuture<Optional<Topology>> readFuture) {
new Thread() {
@Override
public void run() {
- Uninterruptibles.sleepUninterruptibly(50, TimeUnit.MILLISECONDS);
+ Uninterruptibles.sleepUninterruptibly(5, TimeUnit.SECONDS);
readFuture.set(Optional.of(topology));
}
-
}.start();
}
static void waitForSubmit(CountDownLatch latch) {
- assertEquals("Transaction submitted", true,
- Uninterruptibles.awaitUninterruptibly(latch, 5, TimeUnit.SECONDS));
+ assertEquals("Transaction submitted", true, Uninterruptibles.awaitUninterruptibly(latch, 5, TimeUnit.SECONDS));
}
static void waitForDeletes(int expDeleteCalls, final CountDownLatch latch) {
boolean done = Uninterruptibles.awaitUninterruptibly(latch, 5, TimeUnit.SECONDS);
if(!done) {
- fail("Expected " + expDeleteCalls + " delete calls. Actual: " +
- (expDeleteCalls - latch.getCount()));
+ fail("Expected " + expDeleteCalls + " delete calls. Actual: " + (expDeleteCalls - latch.getCount()));
}
}
final CountDownLatch latch = new CountDownLatch(1);
doAnswer(new Answer<CheckedFuture<Void, TransactionCommitFailedException>>() {
@Override
- public CheckedFuture<Void, TransactionCommitFailedException> answer(
- InvocationOnMock invocation) {
+ public CheckedFuture<Void, TransactionCommitFailedException> answer(InvocationOnMock invocation) {
latch.countDown();
return Futures.immediateCheckedFuture(null);
}
}
@SuppressWarnings("rawtypes")
- static void setupStubbedDeletes(ReadWriteTransaction mockTx,
- ArgumentCaptor<InstanceIdentifier> deletedLinkIDs, final CountDownLatch latch) {
+ static void setupStubbedDeletes(ReadWriteTransaction mockTx, ArgumentCaptor<InstanceIdentifier> deletedLinkIDs,
+ final CountDownLatch latch) {
doAnswer(new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocation) {
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (c) 2016 Cisco 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
+ -->
+
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
+
+ <appender name="console" class="org.apache.log4j.ConsoleAppender">
+ <layout class="org.apache.log4j.PatternLayout">
+ <param name="ConversionPattern" value="%-6p %d{HH:mm:ss.SSS} [%10.10t] %30.30c %x - %m%n" />
+ </layout>
+ <!-- <param name="Threshold" value="DEBUG" /> -->
+ </appender>
+
+ <logger name="org.opendaylight.openflowplugin" additivity="false">
+ <level value="DEBUG" />
+ <appender-ref ref="console" />
+ </logger>
+
+ <logger name="org.opendaylight.openflowplugin.impl" additivity="false">
+ <level value="DEBUG" />
+ <appender-ref ref="console" />
+ </logger>
+
+ <logger name="org.opendaylight.openflowplugin.impl.connection" additivity="false">
+ <level value="TRACE" />
+ <appender-ref ref="console" />
+ </logger>
+
+ <logger name="org.opendaylight.openflowplugin.impl.device" additivity="false">
+ <level value="TRACE" />
+ <appender-ref ref="console" />
+ </logger>
+
+ <logger name="org.opendaylight.openflowplugin.openflow.md.core.HandshakeManagerImpl" additivity="false">
+ <level value="TRACE" />
+ <appender-ref ref="console" />
+ </logger>
+
+ <root>
+ <priority value="INFO" />
+ <appender-ref ref="console" />
+ </root>
+</log4j:configuration>