import io.netty.util.TimerTask;
import java.util.Collections;
import java.util.Iterator;
+import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutionException;
* If context already exist we are in state closing process (connection flapping) and we should not propagate connection close
*/
if (deviceContexts.containsKey(deviceInfo)) {
- LOG.warn("Rejecting connection from node which is already connected and there exist deviceContext for it: {}", connectionContext.getNodeId());
+ DeviceContext deviceContext = deviceContexts.get(deviceInfo);
+ if (!deviceContext.getState().equals(OFPContext.CONTEXT_STATE.TERMINATION)) {
+ LOG.warn("Context state for node {} is not in TERMINATION state, trying to reconnect", connectionContext.getNodeId().getValue());
+ } else {
+ LOG.warn("Rejecting connection from node which is already connected and there exist deviceContext for it: {}", connectionContext.getNodeId().getValue());
+ }
return false;
}
this,
convertorExecutor);
- Verify.verify(deviceContexts.putIfAbsent(deviceInfo, deviceContext) == null, "DeviceCtx still not closed.");
+ deviceContexts.putIfAbsent(deviceInfo, deviceContext);
final LifecycleService lifecycleService = new LifecycleServiceImpl();
lifecycleService.setDeviceContext(deviceContext);
@Override
public void onDeviceContextLevelDown(final DeviceInfo deviceInfo) {
- LOG.debug("onDeviceContextClosed for Node {}", deviceInfo.getNodeId());
deviceContexts.remove(deviceInfo);
- updatePacketInRateLimiters();
LifecycleService lifecycleService = lifecycleServices.remove(deviceInfo);
- try {
- lifecycleService.close();
- } catch (Exception e) {
- LOG.warn("Closing service for node {} was unsuccessful ", deviceInfo.getNodeId().getValue(), e);
+ updatePacketInRateLimiters();
+ if (Objects.nonNull(lifecycleService)) {
+ try {
+ lifecycleService.close();
+ } catch (Exception e) {
+ LOG.warn("Closing service for node {} was unsuccessful ", deviceInfo.getNodeId().getValue(), e);
+ }
}
}
return;
}
+ if (deviceCtx.getState().equals(OFPContext.CONTEXT_STATE.TERMINATION)) {
+ LOG.debug("Device context for node {} is already is termination state, waiting for close all context");
+ return;
+ }
+
+ deviceCtx.setState(OFPContext.CONTEXT_STATE.TERMINATION);
+
if (!connectionContext.equals(deviceCtx.getPrimaryConnectionContext())) {
+ LOG.debug("Node {} disconnected, but not primary connection.", connectionContext.getDeviceInfo().getNodeId().getValue());
/* Connection is not PrimaryConnection so try to remove from Auxiliary Connections */
deviceCtx.removeAuxiliaryConnectionContext(connectionContext);
- } else {
+ }
+ //TODO: Auxiliary connections supported ?
+ {
/* Device is disconnected and so we need to close TxManager */
final ListenableFuture<Void> future = deviceCtx.shuttingDownDataStoreTransactions();
Futures.addCallback(future, new FutureCallback<Void>() {
@Override
public void onSuccess(final Void result) {
- LOG.debug("TxChainManager for device {} is closed successful.", deviceInfo.getNodeId());
+ LOG.debug("TxChainManager for device {} is closed successful.", deviceInfo.getNodeId().getValue());
deviceTerminPhaseHandler.onDeviceContextLevelDown(deviceInfo);
}
@Override
public void onFailure(final Throwable t) {
- LOG.warn("TxChainManager for device {} failed by closing.", deviceInfo.getNodeId(), t);
+ LOG.warn("TxChainManager for device {} failed by closing.", deviceInfo.getNodeId().getValue());
+ LOG.trace("TxChainManager failed by closing. ", t);
deviceTerminPhaseHandler.onDeviceContextLevelDown(deviceInfo);
}
});
/* Add timer for Close TxManager because it could fain ind cluster without notification */
final TimerTask timerTask = timeout -> {
if (!future.isDone()) {
- LOG.info("Shutting down TxChain for node {} not completed during 10 sec. Continue anyway.", deviceInfo.getNodeId());
+ LOG.warn("Shutting down TxChain for node {} not completed during 10 sec. Continue anyway.", deviceInfo.getNodeId().getValue());
future.cancel(false);
}
};
deviceContexts.put(deviceInfo, deviceContext);
}
- @VisibleForTesting
- void removeDeviceContextFromMap(final DeviceInfo deviceInfo){
- deviceContexts.remove(deviceInfo);
- }
-
@Override
public <T extends OFPContext> T gainContext(final DeviceInfo deviceInfo) {
return (T) deviceContexts.get(deviceInfo);