Merge "Device state"
authormichal rehak <mirehak@cisco.com>
Tue, 21 Jun 2016 09:01:55 +0000 (09:01 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Tue, 21 Jun 2016 09:01:55 +0000 (09:01 +0000)
18 files changed:
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/DeviceManager.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/DeviceState.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/DeviceSynchronizeListener.java [new file with mode: 0644]
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/DeviceValidListener.java [new file with mode: 0644]
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/statistics/StatisticsContext.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/LifecycleConductorImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/DeviceContextImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/DeviceManagerImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/DeviceStateImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/AbstractMultipartOnTheFlyService.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/MultipartRequestOnTheFlyCallback.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsContextImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsGatheringUtils.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsManagerImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/util/DeviceInitializationUtils.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/device/DeviceStateImplTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/services/MultipartRequestOnTheFlyCallbackTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsGatheringUtilsTest.java

index 83c87ecb4606ed6f94d7f61e2270cf01d0275e68..30babc3f7d5a3bc85250b2ae83d85896f2b7d181 100644 (file)
@@ -42,12 +42,37 @@ public interface DeviceManager extends DeviceConnectedHandler, DeviceDisconnecte
      * Parameters are used as marker to be sure it is change to SLAVE from MASTER or from
      * MASTER to SLAVE and the last parameter "cleanDataStore" is used for validation only.
      *
-     * @param deviceInfo
+     * @param deviceInfo which device
      * @param role - NewRole expect to be {@link OfpRole#BECOMESLAVE} or {@link OfpRole#BECOMEMASTER}
      * @return RoleChangeTxChainManager future for activation/deactivation
      */
     ListenableFuture<Void> onClusterRoleChange(final DeviceInfo deviceInfo, final OfpRole role);
 
+    /**
+     * Register device synchronize listeners
+     * @param deviceSynchronizeListener are notified if device is synchronized or not
+     */
+    void registerDeviceSynchronizeListeners(final DeviceSynchronizeListener deviceSynchronizeListener);
+
+    /**
+     * Notify all registered listeners about synchronized status
+     * @param deviceInfo which device
+     * @param deviceSynchronized true if device is synchronized
+     */
+    void notifyDeviceSynchronizeListeners(final DeviceInfo deviceInfo, final boolean deviceSynchronized);
+
+    /**
+     * Register device valid listeners
+     * @param deviceValidListener are notified if device is valid or not
+     */
+    void registerDeviceValidListeners(final DeviceValidListener deviceValidListener);
+
+    /**
+     * Notify all registered listeners about valid status
+     * @param deviceInfo which device
+     * @param deviceValid true if device is valid
+     */
+    void notifyDeviceValidListeners(final DeviceInfo deviceInfo, final boolean deviceValid);
 
 }
 
index 118ec6684b65bd4cd7950a174643728e37c7f9b3..0ca7e2df60eb99d58c089dde12e859b1ff83e81d 100644 (file)
@@ -8,27 +8,16 @@
 
 package org.opendaylight.openflowplugin.api.openflow.device;
 
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
-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.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutput;
-import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
-
 /**
  * Holder of device's structure
  */
-public interface DeviceState {
+public interface DeviceState extends DeviceSynchronizeListener, DeviceValidListener {
 
     /**
      * @return true if this session is valid
      */
     boolean isValid();
 
-    /**
-     * @param valid the valid to set
-     */
-    void setValid(boolean valid);
-
     /**
      * Return true if we have relevant meter information
      * from device
@@ -98,8 +87,6 @@ public interface DeviceState {
 
     void setQueueStatisticsAvailable(boolean available);
 
-    void setDeviceSynchronized(boolean deviceSynchronized);
-
     boolean isStatisticsPollingEnabled();
 
     void setStatisticsPollingEnabledProp(boolean statPollEnabled);
diff --git a/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/DeviceSynchronizeListener.java b/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/DeviceSynchronizeListener.java
new file mode 100644 (file)
index 0000000..6c49c52
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2015 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
+ */
+package org.opendaylight.openflowplugin.api.openflow.device;
+
+/**
+ * API for device synchronized listeners
+ */
+public interface DeviceSynchronizeListener {
+
+    void deviceIsSynchronized(final DeviceInfo deviceInfo, final boolean isSynchronized);
+
+}
diff --git a/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/DeviceValidListener.java b/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/DeviceValidListener.java
new file mode 100644 (file)
index 0000000..55153a0
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2015 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
+ */
+package org.opendaylight.openflowplugin.api.openflow.device;
+
+/**
+ * API for device synchronized listeners
+ */
+public interface DeviceValidListener {
+
+    void deviceIsValid(final DeviceInfo deviceInfo, final boolean isValid);
+
+}
index ec598c98abbffd537121e26bc084d7511570c0dc..2635413d4bc4d73eb341eb5b75feef5436cc2243 100644 (file)
@@ -22,8 +22,18 @@ import java.util.Optional;
  */
 public interface StatisticsContext extends RequestContextStack, AutoCloseable, OFPContext {
 
+    /**
+     * Gather data from device
+     * @return true if gathering was successful
+     */
     ListenableFuture<Boolean> gatherDynamicData();
 
+    /**
+     * Initial data gathering
+     * @return true if gathering was successful
+     */
+    ListenableFuture<Boolean> initialGatherDynamicData();
+
     /**
      * Method has to be called from DeviceInitialization Method, otherwise
      * we are not able to poll anything. Statistics Context normally initialize
index d84e2c0a9010f2a6750f2d17af1e9d36b3654fa7..121100038ba8353ea27909ecdf757b5332ea5c35 100644 (file)
@@ -138,6 +138,7 @@ final class LifecycleConductorImpl implements LifecycleConductor, RoleChangeList
         LOG.debug("Close connection called for node {}", deviceInfo);
         final DeviceContext deviceContext = getDeviceContext(deviceInfo);
         if (null != deviceContext) {
+            deviceManager.notifyDeviceValidListeners(deviceInfo, false);
             deviceContext.shutdownConnection();
         }
     }
index 10cd0209ba3984029d12f7ba4d10c1b035840f5f..aed3f3c79ecaf3f510cffdabf7f39f69cf846cfa 100644 (file)
@@ -486,7 +486,6 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi
     @Override
     public synchronized void shutdownConnection() {
         LOG.debug("Shutdown method for node {}", deviceInfo.getNodeId());
-        deviceState.setValid(false);
         if (DEVICE_CONTEXT_STATE.TERMINATION.equals(deviceCtxState)) {
             LOG.debug("DeviceCtx for Node {} is in termination process.", deviceInfo.getNodeId());
             return;
@@ -517,7 +516,6 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi
 
     @Override
     public ListenableFuture<Void> shuttingDownDataStoreTransactions() {
-        deviceState.setValid(false);
         return transactionChainManager.shuttingDown();
     }
 
index 5431c41bb4dad4b261372f2c3577773e8bbbcee4..2a0ab747e29173761a19de70fb36740603f3b123 100644 (file)
@@ -17,8 +17,11 @@ import com.google.common.util.concurrent.FutureCallback;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
 import io.netty.util.TimerTask;
+
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Iterator;
+import java.util.List;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.ExecutionException;
@@ -38,6 +41,8 @@ import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceManager;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceSynchronizeListener;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceValidListener;
 import org.opendaylight.openflowplugin.api.openflow.device.TranslatorLibrary;
 import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceInitializationPhaseHandler;
 import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceTerminationPhaseHandler;
@@ -79,6 +84,8 @@ public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProvi
     private final int barrierCountLimit;
     private ExtensionConverterProvider extensionConverterProvider;
     private ScheduledThreadPoolExecutor spyPool;
+    private List<DeviceSynchronizeListener> deviceSynchronizedListeners;
+    private List<DeviceValidListener> deviceValidListeners;
 
     private final LifecycleConductor conductor;
 
@@ -107,6 +114,8 @@ public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProvi
 
         this.conductor = lifecycleConductor;
         spyPool = new ScheduledThreadPoolExecutor(1);
+        this.deviceSynchronizedListeners = new ArrayList<>();
+        this.deviceValidListeners = new ArrayList<>();
     }
 
 
@@ -157,7 +166,10 @@ public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProvi
                 connectionAdapter.registerOutboundQueueHandler(outboundQueueProvider, barrierCountLimit, barrierIntervalNanos);
         connectionContext.setOutboundQueueHandleRegistration(outboundQueueHandlerRegistration);
 
-        final DeviceState deviceState = new DeviceStateImpl();
+        final DeviceState deviceState = new DeviceStateImpl(deviceInfo);
+        this.registerDeviceSynchronizeListeners(deviceState);
+        this.registerDeviceValidListeners(deviceState);
+
         final DeviceContext deviceContext = new DeviceContextImpl(connectionContext,
                 deviceState,
                 dataBroker,
@@ -175,10 +187,12 @@ public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProvi
         final OpenflowProtocolListenerFullImpl messageListener = new OpenflowProtocolListenerFullImpl(
                 connectionAdapter, deviceContext);
         connectionAdapter.setMessageListener(messageListener);
-        deviceState.setValid(true);
+        notifyDeviceValidListeners(deviceInfo, true);
 
         deviceInitPhaseHandler.onDeviceContextLevelUp(connectionContext.getDeviceInfo());
 
+        notifyDeviceSynchronizeListeners(deviceInfo, true);
+
         return true;
     }
 
@@ -213,6 +227,7 @@ public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProvi
         for (final Iterator<DeviceContext> iterator = Iterators.consumingIterator(deviceContexts.values().iterator());
                 iterator.hasNext();) {
             final DeviceContext deviceCtx = iterator.next();
+            notifyDeviceValidListeners(deviceCtx.getDeviceInfo(), false);
             deviceCtx.shutdownConnection();
             deviceCtx.shuttingDownDataStoreTransactions();
         }
@@ -265,6 +280,7 @@ public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProvi
             /* Connection is not PrimaryConnection so try to remove from Auxiliary Connections */
             deviceCtx.removeAuxiliaryConnectionContext(connectionContext);
         } else {
+            notifyDeviceValidListeners(deviceInfo, false);
             /* Device is disconnected and so we need to close TxManager */
             final ListenableFuture<Void> future = deviceCtx.shuttingDownDataStoreTransactions();
             Futures.addCallback(future, new FutureCallback<Void>() {
@@ -312,6 +328,30 @@ public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProvi
         return ((DeviceContextImpl)deviceContext).getTransactionChainManager().deactivateTransactionManager();
     }
 
+    @Override
+    public void registerDeviceSynchronizeListeners(final DeviceSynchronizeListener deviceSynchronizeListener) {
+        this.deviceSynchronizedListeners.add(deviceSynchronizeListener);
+    }
+
+    @Override
+    public void notifyDeviceSynchronizeListeners(final DeviceInfo deviceInfo, final boolean deviceSynchronized) {
+        for (DeviceSynchronizeListener listener : deviceSynchronizedListeners) {
+            listener.deviceIsSynchronized(deviceInfo, deviceSynchronized);
+        }
+    }
+
+    @Override
+    public void registerDeviceValidListeners(final DeviceValidListener deviceValidListener) {
+        this.deviceValidListeners.add(deviceValidListener);
+    }
+
+    @Override
+    public void notifyDeviceValidListeners(final DeviceInfo deviceInfo, final boolean deviceValid) {
+        for (DeviceValidListener listener : deviceValidListeners) {
+            listener.deviceIsValid(deviceInfo, deviceValid);
+        }
+    }
+
     private ListenableFuture<Void> onDeviceTakeClusterLeadership(final DeviceInfo deviceInfo) {
         LOG.trace("onDeviceTakeClusterLeadership for node: {}", deviceInfo.getNodeId());
         /* validation */
@@ -323,7 +363,7 @@ public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProvi
         }
         DeviceContext deviceContext = conductor.getDeviceContext(deviceInfo);
         /* Prepare init info collecting */
-        deviceContext.getDeviceState().setDeviceSynchronized(false);
+        notifyDeviceSynchronizeListeners(deviceInfo, false);
         ((DeviceContextImpl)deviceContext).getTransactionChainManager().activateTransactionManager();
         /* Init Collecting NodeInfo */
         final ListenableFuture<Void> initCollectingDeviceInfo = DeviceInitializationUtils.initializeNodeInformation(
@@ -356,7 +396,7 @@ public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProvi
                     throw new IllegalStateException(errMsg);
                 }
                 LOG.debug("Get Initial Device {} information is successful", deviceInfo.getNodeId());
-                deviceContext.getDeviceState().setDeviceSynchronized(true);
+                notifyDeviceSynchronizeListeners(deviceInfo, true);
                 ((DeviceContextImpl)deviceContext).getTransactionChainManager().initialSubmitWriteTransaction();
                 deviceContext.getDeviceState().setStatisticsPollingEnabledProp(true);
                 return null;
index 5372cc0db9bd28583c2a7b85b3355400d2455b88..42162c8ab85e528d039cd3c0f07925d784793561 100644 (file)
@@ -8,18 +8,10 @@
 
 package org.opendaylight.openflowplugin.impl.device;
 
-import com.google.common.base.Preconditions;
-import javax.annotation.CheckForNull;
-import javax.annotation.Nonnull;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
-import org.opendaylight.openflowplugin.impl.util.DeviceStateUtil;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
-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.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FeaturesReply;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutputBuilder;
-import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
 
 /**
  * openflowplugin-impl
@@ -31,6 +23,7 @@ import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
  */
 class DeviceStateImpl implements DeviceState {
 
+    private final DeviceInfo deviceInfo;
     private boolean valid;
     private boolean meterIsAvailable;
     private boolean groupIsAvailable;
@@ -41,7 +34,8 @@ class DeviceStateImpl implements DeviceState {
     private boolean statPollEnabled;
     private boolean queueStatisticsAvailable;
 
-    DeviceStateImpl() {
+    public DeviceStateImpl(final DeviceInfo deviceInfo) {
+        this.deviceInfo = deviceInfo;
         statPollEnabled = false;
         deviceSynchronized = false;
     }
@@ -51,11 +45,6 @@ class DeviceStateImpl implements DeviceState {
         return valid;
     }
 
-    @Override
-    public void setValid(final boolean valid) {
-        this.valid = valid;
-    }
-
     @Override
     public boolean isMetersAvailable() {
         return meterIsAvailable;
@@ -122,11 +111,6 @@ class DeviceStateImpl implements DeviceState {
 
     }
 
-    @Override
-    public void setDeviceSynchronized(final boolean _deviceSynchronized) {
-        deviceSynchronized = _deviceSynchronized;
-    }
-
     @Override
     public boolean isStatisticsPollingEnabled() {
         return statPollEnabled;
@@ -136,4 +120,18 @@ class DeviceStateImpl implements DeviceState {
     public void setStatisticsPollingEnabledProp(final boolean statPollEnabled) {
         this.statPollEnabled = statPollEnabled;
     }
+
+    @Override
+    public void deviceIsSynchronized(final DeviceInfo deviceInfo, final boolean isSynchronized) {
+        if (this.deviceInfo.equals(deviceInfo)) {
+            this.deviceSynchronized = isSynchronized;
+        }
+    }
+
+    @Override
+    public void deviceIsValid(final DeviceInfo deviceInfo, final boolean isValid) {
+        if (this.deviceInfo.equals(deviceInfo)) {
+            this.valid = isValid;
+        }
+    }
 }
index 9f6747364ab838aaa7f006cf68cbd180733793ee..e20a48dd6ea89d99d372db6be3afc50b2bf115c7 100644 (file)
@@ -24,8 +24,8 @@ public abstract class AbstractMultipartOnTheFlyService<I> extends AbstractServic
     @Override
     protected final FutureCallback<OfHeader> createCallback(final RequestContext<List<MultipartReply>> context, final Class<?> requestType) {
         return new MultipartRequestOnTheFlyCallback(context, requestType,
-                getDeviceContext().getMessageSpy(), getEventIdentifier(), getDeviceContext().getDeviceInfo(),
-                getDeviceContext().getDeviceFlowRegistry(), getDeviceContext(), getDeviceContext().getDeviceState());
+                getMessageSpy(), getEventIdentifier(), getDeviceInfo(),
+                getDeviceContext().getDeviceFlowRegistry(), getTxFacade());
     }
 
 
index d3b34ce520efa9ae2faa4cfcb310812f56b0a91f..844811cbab439952fcd6bfdd68ce9952b940e1d8 100644 (file)
@@ -43,7 +43,6 @@ final class MultipartRequestOnTheFlyCallback extends AbstractRequestCallback<Lis
     private boolean finished = false;
     private final EventIdentifier doneEventIdentifier;
     private final TxFacade txFacade;
-    private final DeviceState deviceState;
 
 
     public MultipartRequestOnTheFlyCallback(final RequestContext<List<MultipartReply>> context,
@@ -52,14 +51,12 @@ final class MultipartRequestOnTheFlyCallback extends AbstractRequestCallback<Lis
                                             final EventIdentifier eventIdentifier,
                                             final DeviceInfo deviceInfo,
                                             final DeviceFlowRegistry registry,
-                                            final TxFacade txFacade,
-                                            final DeviceState deviceState) {
+                                            final TxFacade txFacade) {
         super(context, requestType, messageSpy, eventIdentifier);
 
         this.deviceInfo = deviceInfo;
         this.registry = registry;
         this.txFacade = txFacade;
-        this.deviceState = deviceState;
 
         //TODO: this is focused on flow stats only - need more general approach if used for more than flow stats
         doneEventIdentifier = new EventIdentifier(MultipartType.OFPMPFLOW.name(), deviceInfo.getNodeId().toString());
@@ -100,7 +97,7 @@ final class MultipartRequestOnTheFlyCallback extends AbstractRequestCallback<Lis
             //TODO: following part is focused on flow stats only - need more general approach if used for more than flow stats
             ListenableFuture<Void> future;
             if (virgin) {
-                future = StatisticsGatheringUtils.deleteAllKnownFlows(deviceInfo, registry, txFacade, deviceState);
+                future = StatisticsGatheringUtils.deleteAllKnownFlows(deviceInfo, registry, txFacade);
                 virgin = false;
             } else {
                 future = Futures.immediateFuture(null);
index 68d349ad704af44855535dca37bb63887ba55646..64d50ebb9439e52d92d83b4eec0fad99011f1800 100644 (file)
@@ -105,8 +105,18 @@ class StatisticsContextImpl implements StatisticsContext {
         }
     }
 
+
+    @Override
+    public ListenableFuture<Boolean> initialGatherDynamicData() {
+        return gatherDynamicData(true);
+    }
+
     @Override
-    public ListenableFuture<Boolean> gatherDynamicData() {
+    public ListenableFuture<Boolean> gatherDynamicData(){
+        return gatherDynamicData(false);
+    }
+
+    private ListenableFuture<Boolean> gatherDynamicData(final boolean initial) {
         if (shuttingDownStatisticsPolling) {
             LOG.debug("Statistics for device {} is not enabled.", deviceContext.getDeviceInfo().getNodeId());
             return Futures.immediateFuture(Boolean.TRUE);
@@ -122,7 +132,7 @@ class StatisticsContextImpl implements StatisticsContext {
             // write start timestamp to state snapshot container
             StatisticsGatheringUtils.markDeviceStateSnapshotStart(deviceContext);
 
-            statChainFuture(statIterator, settableStatResultFuture);
+            statChainFuture(statIterator, settableStatResultFuture, initial);
 
             // write end timestamp to state snapshot container
             Futures.addCallback(settableStatResultFuture, new FutureCallback<Boolean>() {
@@ -139,10 +149,10 @@ class StatisticsContextImpl implements StatisticsContext {
         }
     }
 
-    private ListenableFuture<Boolean> chooseStat(final MultipartType multipartType){
+    private ListenableFuture<Boolean> chooseStat(final MultipartType multipartType, final boolean initial){
         switch (multipartType) {
             case OFPMPFLOW:
-                return collectFlowStatistics(multipartType);
+                return collectFlowStatistics(multipartType, initial);
             case OFPMPTABLE:
                 return collectTableStatistics(multipartType);
             case OFPMPPORTSTATS:
@@ -208,7 +218,7 @@ class StatisticsContextImpl implements StatisticsContext {
         return Optional.ofNullable(pollTimeout);
     }
 
-    private void statChainFuture(final Iterator<MultipartType> iterator, final SettableFuture<Boolean> resultFuture) {
+    private void statChainFuture(final Iterator<MultipartType> iterator, final SettableFuture<Boolean> resultFuture, final boolean initial) {
         if (ConnectionContext.CONNECTION_STATE.RIP.equals(deviceContext.getPrimaryConnectionContext().getConnectionState())) {
             final String errMsg = String.format("Device connection is closed for Node : %s.",
                     deviceContext.getDeviceInfo().getNodeId());
@@ -225,11 +235,11 @@ class StatisticsContextImpl implements StatisticsContext {
         final MultipartType nextType = iterator.next();
         LOG.debug("Stats iterating to next type for node {} of type {}", deviceContext.getDeviceInfo().getNodeId(), nextType);
 
-        final ListenableFuture<Boolean> deviceStatisticsCollectionFuture = chooseStat(nextType);
+        final ListenableFuture<Boolean> deviceStatisticsCollectionFuture = chooseStat(nextType, initial);
         Futures.addCallback(deviceStatisticsCollectionFuture, new FutureCallback<Boolean>() {
             @Override
             public void onSuccess(final Boolean result) {
-                statChainFuture(iterator, resultFuture);
+                statChainFuture(iterator, resultFuture, initial);
             }
             @Override
             public void onFailure(@Nonnull final Throwable t) {
@@ -247,7 +257,7 @@ class StatisticsContextImpl implements StatisticsContext {
     @VisibleForTesting
     ListenableFuture<Boolean> deviceConnectionCheck() {
         if (!ConnectionContext.CONNECTION_STATE.WORKING.equals(deviceContext.getPrimaryConnectionContext().getConnectionState())) {
-            ListenableFuture<Boolean> resultingFuture = SettableFuture.create();
+            ListenableFuture<Boolean> resultingFuture;
             switch (deviceContext.getPrimaryConnectionContext().getConnectionState()) {
                 case RIP:
                     final String errMsg = String.format("Device connection doesn't exist anymore. Primary connection status : %s",
@@ -264,14 +274,14 @@ class StatisticsContextImpl implements StatisticsContext {
     }
 
     //TODO: Refactor twice sending deviceContext into gatheringStatistics
-    private ListenableFuture<Boolean> collectFlowStatistics(final MultipartType multipartType) {
+    private ListenableFuture<Boolean> collectFlowStatistics(final MultipartType multipartType, final boolean initial) {
         return devState.isFlowStatisticsAvailable() ? StatisticsGatheringUtils.gatherStatistics(
                 statisticsGatheringOnTheFlyService,
                 deviceContext.getDeviceInfo(),
                 /*MultipartType.OFPMPFLOW*/ multipartType,
                 deviceContext,
                 deviceContext,
-                devState) : emptyFuture;
+                initial) : emptyFuture;
     }
 
     private ListenableFuture<Boolean> collectTableStatistics(final MultipartType multipartType) {
@@ -281,7 +291,7 @@ class StatisticsContextImpl implements StatisticsContext {
                 /*MultipartType.OFPMPTABLE*/ multipartType,
                 deviceContext,
                 deviceContext,
-                devState) : emptyFuture;
+                false) : emptyFuture;
     }
 
     private ListenableFuture<Boolean> collectPortStatistics(final MultipartType multipartType) {
@@ -291,7 +301,7 @@ class StatisticsContextImpl implements StatisticsContext {
                 /*MultipartType.OFPMPPORTSTATS*/ multipartType,
                 deviceContext,
                 deviceContext,
-                devState) : emptyFuture;
+                false) : emptyFuture;
     }
 
     private ListenableFuture<Boolean> collectQueueStatistics(final MultipartType multipartType) {
@@ -301,7 +311,7 @@ class StatisticsContextImpl implements StatisticsContext {
                 /*MultipartType.OFPMPQUEUE*/ multipartType,
                 deviceContext,
                 deviceContext,
-                devState);
+                false);
     }
 
     private ListenableFuture<Boolean> collectGroupDescStatistics(final MultipartType multipartType) {
@@ -311,7 +321,7 @@ class StatisticsContextImpl implements StatisticsContext {
                 /*MultipartType.OFPMPGROUPDESC*/ multipartType,
                 deviceContext,
                 deviceContext,
-                devState) : emptyFuture;
+                false) : emptyFuture;
     }
 
     private ListenableFuture<Boolean> collectGroupStatistics(final MultipartType multipartType) {
@@ -321,7 +331,7 @@ class StatisticsContextImpl implements StatisticsContext {
                 /*MultipartType.OFPMPGROUP*/ multipartType,
                 deviceContext,
                 deviceContext,
-                devState) : emptyFuture;
+                false) : emptyFuture;
     }
 
     private ListenableFuture<Boolean> collectMeterConfigStatistics(final MultipartType multipartType) {
@@ -331,7 +341,7 @@ class StatisticsContextImpl implements StatisticsContext {
                 /*MultipartType.OFPMPMETERCONFIG*/ multipartType,
                 deviceContext,
                 deviceContext,
-                devState) : emptyFuture;
+                false) : emptyFuture;
     }
 
     private ListenableFuture<Boolean> collectMeterStatistics(final MultipartType multipartType) {
@@ -341,7 +351,7 @@ class StatisticsContextImpl implements StatisticsContext {
                 /*MultipartType.OFPMPMETER*/ multipartType,
                 deviceContext,
                 deviceContext,
-                devState) : emptyFuture;
+                false) : emptyFuture;
     }
 
     @VisibleForTesting
index f0e57ba0db4ac622c92300166a211497cfa58eb7..e24d5343a598a11909a708fbc9cbbbe2b867fe77 100644 (file)
@@ -133,7 +133,7 @@ public final class StatisticsGatheringUtils {
                                                       final MultipartType type,
                                                       final TxFacade txFacade,
                                                       final DeviceRegistry registry,
-                                                      final DeviceState deviceState) {
+                                                      final Boolean initial) {
         EventIdentifier wholeProcessEventIdentifier = null;
         if (MultipartType.OFPMPFLOW.equals(type)) {
             wholeProcessEventIdentifier = new EventIdentifier(type.toString(), deviceInfo.getNodeId().getValue());
@@ -143,7 +143,7 @@ public final class StatisticsGatheringUtils {
         final ListenableFuture<RpcResult<List<MultipartReply>>> statisticsDataInFuture =
                 JdkFutureAdapters.listenInPoolThread(statisticsGatheringService.getStatisticsOfType(
                         ofpQueuToRequestContextEventIdentifier, type));
-        return transformAndStoreStatisticsData(statisticsDataInFuture, deviceInfo, wholeProcessEventIdentifier, type, txFacade, registry, deviceState);
+        return transformAndStoreStatisticsData(statisticsDataInFuture, deviceInfo, wholeProcessEventIdentifier, type, txFacade, registry, initial);
     }
 
     private static ListenableFuture<Boolean> transformAndStoreStatisticsData(final ListenableFuture<RpcResult<List<MultipartReply>>> statisticsDataInFuture,
@@ -152,7 +152,7 @@ public final class StatisticsGatheringUtils {
                                                                              final MultipartType type,
                                                                              final TxFacade txFacade,
                                                                              final DeviceRegistry registry,
-                                                                             final DeviceState deviceState) {
+                                                                             final boolean initial) {
         return Futures.transform(statisticsDataInFuture, new AsyncFunction<RpcResult<List<MultipartReply>>, Boolean>() {
             @Nullable
             @Override
@@ -197,7 +197,7 @@ public final class StatisticsGatheringUtils {
                             } else if (multipartData instanceof FlowsStatisticsUpdate) {
                                 /* FlowStat Processing is realized by NettyThread only by initPhase, otherwise it is realized
                                  * by MD-SAL thread */
-                                return processFlowStatistics((Iterable<FlowsStatisticsUpdate>) allMultipartData, deviceInfo, txFacade, registry.getDeviceFlowRegistry(), deviceState, eventIdentifier);
+                                return processFlowStatistics((Iterable<FlowsStatisticsUpdate>) allMultipartData, deviceInfo, txFacade, registry.getDeviceFlowRegistry(), initial, eventIdentifier);
 
                             } else if (multipartData instanceof GroupDescStatsUpdated) {
                                 processGroupDescStats((Iterable<GroupDescStatsUpdated>) allMultipartData, deviceInfo, txFacade, registry.getDeviceGroupRegistry());
@@ -253,11 +253,11 @@ public final class StatisticsGatheringUtils {
                                                                    final DeviceInfo deviceInfo,
                                                                    final TxFacade txFacade,
                                                                    final DeviceFlowRegistry flowRegistry,
-                                                                   final DeviceState deviceState,
+                                                                   final boolean initial,
                                                                    final EventIdentifier eventIdentifier) {
-        final ListenableFuture<Void> deleFuture = deleteAllKnownFlows(deviceInfo,
-                flowRegistry, txFacade, deviceState);
-        return Futures.transform(deleFuture, new Function<Void, Boolean>() {
+        final ListenableFuture<Void> deleteFuture = initial ? Futures.immediateFuture(null) : deleteAllKnownFlows(deviceInfo,
+                flowRegistry, txFacade);
+        return Futures.transform(deleteFuture, new Function<Void, Boolean>() {
 
             @Override
             public Boolean apply(final Void input) {
@@ -310,48 +310,42 @@ public final class StatisticsGatheringUtils {
 
     public static ListenableFuture<Void> deleteAllKnownFlows(final DeviceInfo deviceInfo,
                                                              final DeviceFlowRegistry registry,
-                                                             final TxFacade txFacade,
-                                                             final DeviceState deviceState) {
-        //TODO:Make check for phase from enum
-        /* DeviceState.deviceSynchronized is a marker for actual phase - false means initPhase, true means noInitPhase */
-        if (deviceState.deviceSynchronized()) {
-            final InstanceIdentifier<FlowCapableNode> flowCapableNodePath = assembleFlowCapableNodeInstanceIdentifier(deviceInfo);
-            final ReadOnlyTransaction readTx = txFacade.getReadTransaction();
-            final CheckedFuture<Optional<FlowCapableNode>, ReadFailedException> flowCapableNodeFuture = readTx.read(
-                    LogicalDatastoreType.OPERATIONAL, flowCapableNodePath);
-
-            /* we wish to close readTx for fallBack */
-            Futures.withFallback(flowCapableNodeFuture, new FutureFallback<Optional<FlowCapableNode>>() {
-
-                @Override
-                public ListenableFuture<Optional<FlowCapableNode>> create(final Throwable t) throws Exception {
-                    readTx.close();
-                    return Futures.immediateFailedFuture(t);
-                }
-            });
-            /*
-             * we have to read actual tables with all information before we set empty Flow list, merge is expensive and
-             * not applicable for lists
-             */
-            return Futures.transform(flowCapableNodeFuture, new AsyncFunction<Optional<FlowCapableNode>, Void>() {
-
-                @Override
-                public ListenableFuture<Void> apply(final Optional<FlowCapableNode> flowCapNodeOpt) throws Exception {
-                    if (flowCapNodeOpt.isPresent()) {
-                        for (final Table tableData : flowCapNodeOpt.get().getTable()) {
-                            final Table table = new TableBuilder(tableData).setFlow(Collections.<Flow>emptyList()).build();
-                            final InstanceIdentifier<Table> iiToTable = flowCapableNodePath.child(Table.class, tableData.getKey());
-                            txFacade.writeToTransaction(LogicalDatastoreType.OPERATIONAL, iiToTable, table);
-                        }
+                                                             final TxFacade txFacade) {
+        final InstanceIdentifier<FlowCapableNode> flowCapableNodePath = assembleFlowCapableNodeInstanceIdentifier(deviceInfo);
+        final ReadOnlyTransaction readTx = txFacade.getReadTransaction();
+        final CheckedFuture<Optional<FlowCapableNode>, ReadFailedException> flowCapableNodeFuture = readTx.read(
+                LogicalDatastoreType.OPERATIONAL, flowCapableNodePath);
+
+        /* we wish to close readTx for fallBack */
+        Futures.withFallback(flowCapableNodeFuture, new FutureFallback<Optional<FlowCapableNode>>() {
+
+            @Override
+            public ListenableFuture<Optional<FlowCapableNode>> create(final Throwable t) throws Exception {
+                readTx.close();
+                return Futures.immediateFailedFuture(t);
+            }
+        });
+        /*
+         * we have to read actual tables with all information before we set empty Flow list, merge is expensive and
+         * not applicable for lists
+         */
+        return Futures.transform(flowCapableNodeFuture, new AsyncFunction<Optional<FlowCapableNode>, Void>() {
+
+            @Override
+            public ListenableFuture<Void> apply(final Optional<FlowCapableNode> flowCapNodeOpt) throws Exception {
+                if (flowCapNodeOpt.isPresent()) {
+                    for (final Table tableData : flowCapNodeOpt.get().getTable()) {
+                        final Table table = new TableBuilder(tableData).setFlow(Collections.<Flow>emptyList()).build();
+                        final InstanceIdentifier<Table> iiToTable = flowCapableNodePath.child(Table.class, tableData.getKey());
+                        txFacade.writeToTransaction(LogicalDatastoreType.OPERATIONAL, iiToTable, table);
                     }
-                    registry.removeMarked();
-                    readTx.close();
-                    return Futures.immediateFuture(null);
                 }
+                registry.removeMarked();
+                readTx.close();
+                return Futures.immediateFuture(null);
+            }
 
-            });
-        }
-        return Futures.immediateFuture(null);
+        });
     }
 
     private static void processQueueStatistics(final Iterable<QueueStatisticsUpdate> data, final DeviceInfo deviceInfo, final TxFacade txFacade) throws Exception {
index 735c3d16ee7a7f56f8c37a4b594c9e9cdc54a983..048957a5bb78e0933ddf64d5b84f3752402eb603 100644 (file)
@@ -97,7 +97,6 @@ public class StatisticsManagerImpl implements StatisticsManager, StatisticsManag
         final StatisticsContext statisticsContext = new StatisticsContextImpl(deviceInfo, shuttingDownStatisticsPolling, conductor);
         Verify.verify(contexts.putIfAbsent(deviceInfo, statisticsContext) == null, "StatisticsCtx still not closed for Node {}", deviceInfo.getNodeId());
 
-        deviceContext.getDeviceState().setDeviceSynchronized(true);
         deviceInitPhaseHandler.onDeviceContextLevelUp(deviceInfo);
     }
 
index f7f74c9a56d330df0f666bd2d8486e1c6bc689c6..3543a692b24dd33449f3b08da476aaf3d775b310 100644 (file)
@@ -118,7 +118,7 @@ public class DeviceInitializationUtils {
             final TranslatorKey translatorKey = new TranslatorKey(ofVersion, PortGrouping.class.getName());
             final MessageTranslator<PortGrouping, FlowCapableNodeConnector> translator = deviceContext.oook()
                     .lookupTranslator(translatorKey);
-            final BigInteger dataPathId = deviceContext.getPrimaryConnectionContext().getFeatures().getDatapathId();
+            final BigInteger dataPathId = deviceContext.getDeviceInfo().getDatapathId();
 
             for (final PortGrouping port : connectionContext.getFeatures().getPhyPort()) {
                 final FlowCapableNodeConnector fcNodeConnector = translator.translate(port, deviceContext.getDeviceInfo(), null);
index b719795a588ac6f5b878e79fd081cae9a38cff43..5170dd75d64d088b0ace332bd524ef9f36e966c4 100644 (file)
@@ -8,21 +8,13 @@
 
 package org.opendaylight.openflowplugin.impl.device;
 
-import java.util.Arrays;
-import java.util.List;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
-import org.mockito.Mockito;
 import org.mockito.runners.MockitoJUnitRunner;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FeaturesReply;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.features.reply.PhyPort;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.features.reply.PhyPortBuilder;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
 
 /**
  * openflowplugin-impl
@@ -33,11 +25,14 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731
 @RunWith(MockitoJUnitRunner.class)
 public class DeviceStateImplTest {
 
+    @Mock
+    private DeviceInfo deviceInfo;
+
     private DeviceStateImpl deviceState;
 
     @Before
     public void initialization() {
-        deviceState = new DeviceStateImpl();
+        deviceState = new DeviceStateImpl(deviceInfo);
     }
 
     @Test
index 3e4c4f0162caa738b967c46acea0d27829dcf537..2a61af4295b0bdb0aee02652dc4db82702d9055e 100644 (file)
@@ -142,7 +142,7 @@ public class MultipartRequestOnTheFlyCallbackTest {
         };
         multipartRequestOnTheFlyCallback = new MultipartRequestOnTheFlyCallback(dummyRequestContext, String.class,
                 mockedDeviceContext.getMessageSpy(),dummyEventIdentifier, mockedDeviceInfo,
-                mockedDeviceContext.getDeviceFlowRegistry(), mockedDeviceContext, mockedDeviceState);
+                mockedDeviceContext.getDeviceFlowRegistry(), mockedDeviceContext);
     }
 
 
index a5303e23097b8394ad1b861903682001b14d4c42..5eda472bd06517c5b6df15d252f603da4b24f557 100644 (file)
@@ -500,7 +500,7 @@ public class StatisticsGatheringUtilsTest {
                 type,
                 txFacade,
                 deviceContext,
-                deviceState);
+                false);
         Assert.assertTrue(gatherStatisticsResult.get(1, TimeUnit.SECONDS).booleanValue());
         verify(txFacade).submitTransaction();
     }
@@ -518,14 +518,6 @@ public class StatisticsGatheringUtilsTest {
         return new BucketStatsBuilder().setByteCount(BigInteger.valueOf(byteCount)).setPacketCount(BigInteger.valueOf(packetCount)).build();
     }
 
-    @Test
-    public void testDeleteAllKnownFlowsNotSync() throws Exception {
-        when(deviceState.deviceSynchronized()).thenReturn(false);
-        StatisticsGatheringUtils.deleteAllKnownFlows(deviceInfo,
-                deviceContext.getDeviceFlowRegistry(), deviceContext, deviceState);
-        Mockito.verifyNoMoreInteractions(deviceFlowRegistry);
-    }
-
     @Test
     public void testDeleteAllKnownFlows() throws Exception {
         final short tableId = 0;
@@ -542,7 +534,7 @@ public class StatisticsGatheringUtilsTest {
                 .augmentation(FlowCapableNode.class).child(Table.class, new TableKey(tableId));
 
         StatisticsGatheringUtils.deleteAllKnownFlows(deviceInfo,
-                deviceContext.getDeviceFlowRegistry(), txFacade, deviceState);
+                deviceContext.getDeviceFlowRegistry(), txFacade);
 
         verify(txFacade).writeToTransaction(
                 LogicalDatastoreType.OPERATIONAL,