import java.util.Collection;
import java.util.Date;
import java.util.List;
+import java.util.Objects;
import javax.annotation.Nonnull;
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.DataTreeModification;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.openflowplugin.applications.frsync.SyncReactor;
*/
protected Optional<ListenableFuture<Boolean>> processNodeModification(
final DataTreeModification<Node> modification) {
+ Optional<ListenableFuture<Boolean>> result;
final NodeId nodeId = ModificationUtil.nodeId(modification);
- updateCache(modification);
+ final DataObjectModification<Node> nodeModification = modification.getRootNode();
- final boolean isAdd = isAdd(modification) || isAddLogical(modification);
+ if (isDelete(nodeModification) || isDeleteLogical(nodeModification)) {
+ operationalSnapshot.updateCache(nodeId, Optional.absent());
+ deviceMastershipManager.onDeviceDisconnected(nodeId);
+ result = skipModification(modification);
+ } else {
+ operationalSnapshot.updateCache(nodeId, Optional.fromNullable(ModificationUtil.flowCapableNodeAfter(modification)));
- if (isAdd) {
- deviceMastershipManager.onDeviceConnected(nodeId);
- }
+ final boolean isAdd = isAdd(nodeModification) || isAddLogical(nodeModification);
- // if node is registered for reconcile we need consistent data from operational DS (skip partial collections)
- // but we can accept first modification since all statistics are intentionally collected in one step on startup
- if (reconciliationRegistry.isRegistered(nodeId) && (isAdd || isConsistentForReconcile(modification))) {
- return reconciliation(modification);
- } else {
- return skipModification(modification);
- }
- }
+ if (isAdd) {
+ deviceMastershipManager.onDeviceConnected(nodeId);
+ }
- /**
- * Remove if delete. Update only if FlowCapableNode Augmentation modified.
- * Unregister for device mastership.
- * @param modification Datastore modification
- */
- private void updateCache(final DataTreeModification<Node> modification) {
- NodeId nodeId = ModificationUtil.nodeId(modification);
- if (isDelete(modification) || isDeleteLogical(modification)) {
- operationalSnapshot.updateCache(nodeId, Optional.absent());
- deviceMastershipManager.onDeviceDisconnected(nodeId);
- return;
+ // if node is registered for reconcile we need consistent data from operational DS (skip partial collections)
+ // but we can accept first modification since all statistics are intentionally collected in one step on startup
+ if (reconciliationRegistry.isRegistered(nodeId) && (isAdd || isConsistentForReconcile(modification))) {
+ result = reconciliation(modification);
+ } else {
+ result = skipModification(modification);
+ }
}
- operationalSnapshot.updateCache(nodeId, Optional.fromNullable(ModificationUtil.flowCapableNodeAfter(modification)));
+ return result;
}
private Optional<ListenableFuture<Boolean>> skipModification(final DataTreeModification<Node> modification) {
return Optional.absent();
}
- private boolean isDelete(final DataTreeModification<Node> modification) {
- return ModificationType.DELETE == modification.getRootNode().getModificationType();
+ private boolean isDelete(final DataObjectModification<Node> nodeModification) {
+ return Objects.nonNull(nodeModification.getDataBefore()) && Objects.isNull(nodeModification.getDataAfter());
}
/**
* All connectors disappeared from operational store (logical delete).
*/
- private boolean isDeleteLogical(final DataTreeModification<Node> modification) {
- final DataObjectModification<Node> rootNode = modification.getRootNode();
- return !safeConnectorsEmpty(rootNode.getDataBefore()) && safeConnectorsEmpty(rootNode.getDataAfter());
+ private boolean isDeleteLogical(final DataObjectModification<Node> nodeModification) {
+ return !safeConnectorsEmpty(nodeModification.getDataBefore()) && safeConnectorsEmpty(nodeModification.getDataAfter());
}
- private boolean isAdd(final DataTreeModification<Node> modification) {
- final DataObjectModification<Node> rootNode = modification.getRootNode();
- return rootNode.getDataBefore() == null && rootNode.getDataAfter() != null;
+ private boolean isAdd(final DataObjectModification<Node> nodeModification) {
+ return Objects.isNull(nodeModification.getDataBefore()) && Objects.nonNull(nodeModification.getDataAfter());
}
/**
* All connectors appeared in operational store (logical add).
*/
- private boolean isAddLogical(final DataTreeModification<Node> modification) {
- final DataObjectModification<Node> rootNode = modification.getRootNode();
- return safeConnectorsEmpty(rootNode.getDataBefore()) && !safeConnectorsEmpty(rootNode.getDataAfter());
+ private boolean isAddLogical(final DataObjectModification<Node> nodeModification) {
+ return safeConnectorsEmpty(nodeModification.getDataBefore()) && !safeConnectorsEmpty(nodeModification.getDataAfter());
}
/**
import org.mockito.runners.MockitoJUnitRunner;
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.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.binding.api.ReadOnlyTransaction;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.snapshot.gathering.status.grouping.SnapshotGatheringStatusEnd;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
private ReconciliationRegistry reconciliationRegistry;
@Mock
private DeviceMastershipManager deviceMastershipManager;
+ @Mock
+ private List nodeConnector;
+ @Mock
+ private Node operationalNodeEmpty;
@Before
public void setUp() throws Exception {
public void testOnDataTreeChangedDeletePhysical() throws Exception {
Mockito.when(operationalModification.getDataBefore()).thenReturn(operationalNode);
Mockito.when(operationalModification.getDataAfter()).thenReturn(null);
- Mockito.when(dataTreeModification.getRootNode().getModificationType()).thenReturn(ModificationType.DELETE);
- Mockito.when(reconciliationRegistry.isRegistered(NODE_ID)).thenReturn(false);
nodeListenerOperational.onDataTreeChanged(Collections.singleton(dataTreeModification));
@Test
public void testOnDataTreeChangedDeleteLogical() {
Mockito.when(operationalModification.getDataBefore()).thenReturn(operationalNode);
- List<NodeConnector> nodeConnectorList = Mockito.mock(List.class);
- Mockito.when(operationalNode.getNodeConnector()).thenReturn(nodeConnectorList);
- Mockito.when(reconciliationRegistry.isRegistered(NODE_ID)).thenReturn(false);
+ Mockito.when(operationalNode.getNodeConnector()).thenReturn(nodeConnector);
+ Mockito.when(operationalNodeEmpty.getId()).thenReturn(NODE_ID);
+ Mockito.when(operationalModification.getDataAfter()).thenReturn(operationalNodeEmpty);
+ Mockito.when(operationalNodeEmpty.getNodeConnector()).thenReturn(null);
nodeListenerOperational.onDataTreeChanged(Collections.singleton(dataTreeModification));