--- /dev/null
+/**
+ * Copyright (c) 2016 Pantheon Technologies s.r.o. 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.connection;
+
+/**
+ * Define all possible states of connection after handshake
+ */
+public enum ConnectionStatus {
+
+ // this flag should be return if no connection on this node exists
+ MAY_CONTINUE,
+
+ // this flag should be return if node still connected but not in termination state
+ ALREADY_CONNECTED,
+
+ // this flag should be return if node still connected but already in termination state
+ CLOSING
+}
import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext;
import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceReplyProcessor;
import org.opendaylight.openflowplugin.api.openflow.device.handlers.MultiMsgCollector;
+import org.opendaylight.openflowplugin.api.openflow.lifecycle.LifecycleService;
import org.opendaylight.openflowplugin.api.openflow.registry.ItemLifeCycleRegistry;
import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageSpy;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
void setSwitchFeaturesMandatory(boolean switchFeaturesMandatory);
+ void putLifecycleServiceIntoTxChainManager(LifecycleService lifecycleService);
+
+ void replaceConnectionContext(ConnectionContext connectionContext);
}
*/
ServiceGroupIdentifier getServiceIdentifier();
+ /**
+ * Many uses in log, this will make code more readable
+ * @return string representation of nodeId
+ */
+ default String getLOGValue() {
+ return getNodeId().getValue();
+ }
+
}
package org.opendaylight.openflowplugin.api.openflow.device.handlers;
import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext;
+import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionStatus;
/**
* Created by Martin Bobak <mbobak@cisco.com> on 26.2.2015.
* Method is used to propagate information about established connection with device.
* It propagates connected device's connection context.
*/
- boolean deviceConnected(ConnectionContext connectionContext) throws Exception;
+ ConnectionStatus deviceConnected(ConnectionContext connectionContext) throws Exception;
}
+++ /dev/null
-/*
- * 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
- */
-
-package org.opendaylight.openflowplugin.api.openflow.lifecycle;
-
-import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.OfpRole;
-
-/**
- * This API is for all listeners who wish to know about role change in cluster
- */
-public interface RoleChangeListener {
-
- /**
- * Notification when initialization for role context is done
- * @param deviceInfo
- * @param success or failure
- */
- void roleInitializationDone(final DeviceInfo deviceInfo, final boolean success);
-
- /**
- * Notification when the role change on device is done
- * @param deviceInfo
- * @param newRole
- */
- void roleChangeOnDevice(final DeviceInfo deviceInfo, final OfpRole newRole);
-
-}
import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceInitializationPhaseHandler;
import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceLifecycleSupervisor;
import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceTerminationPhaseHandler;
-import org.opendaylight.openflowplugin.api.openflow.lifecycle.RoleChangeListener;
/**
* Manager for role change on device
future.get(1, TimeUnit.SECONDS);
LOG.info("Unregister outbound queue successful.");
} catch (InterruptedException | TimeoutException | ExecutionException e) {
- LOG.warn("Unregister outbound queue throws exception for node {} ", nodeId);
- LOG.trace("Unregister outbound queue throws exception for node {} ", nodeId, e);
+ LOG.warn("Unregister outbound queue throws exception for node {} ", getSafeNodeIdForLOG());
+ LOG.trace("Unregister outbound queue throws exception for node {} ", getSafeNodeIdForLOG(), e);
}
closeHandshakeContext();
}
if (propagate) {
- LOG.debug("Propagating device disconnect for node {}", nodeId);
+ LOG.debug("Propagating device disconnect for node {}", getSafeNodeIdForLOG());
propagateDeviceDisconnectedEvent();
} else {
- LOG.debug("Close connection without propagating for node {}", nodeId);
+ LOG.debug("Close connection without propagating for node {}", getSafeNodeIdForLOG());
}
}
private void closeHandshakeContext() {
- LOG.debug("Trying closing handshake context for node {}", nodeId);
+ LOG.debug("Trying closing handshake context for node {}", getSafeNodeIdForLOG());
if (handshakeContext != null) {
try {
handshakeContext.close();
}
}
+ /**
+ * This method returns safe nodeId for logging
+ * @return string value od nodeId or string "null"
+ */
+ private String getSafeNodeIdForLOG() {
+ return null == nodeId ? "null" : nodeId.getValue();
+ }
+
@Override
public void setOutboundQueueHandleRegistration(OutboundQueueHandlerRegistration<OutboundQueueProvider> outboundQueueHandlerRegistration) {
this.outboundQueueHandlerRegistration = outboundQueueHandlerRegistration;
import com.google.common.util.concurrent.ListenableFuture;
import javax.annotation.Nullable;
import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext;
+import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionStatus;
import org.opendaylight.openflowplugin.api.openflow.connection.HandshakeContext;
import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceConnectedHandler;
import org.opendaylight.openflowplugin.api.openflow.md.core.HandshakeListener;
return new FutureCallback<RpcResult<BarrierOutput>>() {
@Override
public void onSuccess(@Nullable final RpcResult<BarrierOutput> result) {
- LOG.debug("succeeded by getting sweep barrier after posthandshake for device {}", connectionContext.getNodeId());
+ LOG.debug("succeeded by getting sweep barrier after post-handshake for device {}", connectionContext.getNodeId().getValue());
try {
- if (!deviceConnectedHandler.deviceConnected(connectionContext)) {
- connectionContext.closeConnection(true);
+ ConnectionStatus connectionStatusResult = deviceConnectedHandler.deviceConnected(connectionContext);
+ if (ConnectionStatus.CLOSING.equals(connectionStatusResult)) {
+ connectionContext.closeConnection(false);
}
SessionStatistics.countEvent(connectionContext.getNodeId().toString(),
SessionStatistics.ConnectionStatus.CONNECTION_CREATED);
} catch (final Exception e) {
- LOG.error("ConnectionContext initial processing failed: {}", e.getMessage());
+ LOG.error("ConnectionContext initial processing failed: ", e);
SessionStatistics.countEvent(connectionContext.getNodeId().toString(),
SessionStatistics.ConnectionStatus.CONNECTION_DISCONNECTED_BY_OFP);
connectionContext.closeConnection(true);
@Override
public void onFailure(final Throwable t) {
- LOG.error("failed to get sweep barrier after posthandshake for device {}", connectionContext.getNodeId());
+ LOG.error("failed to get sweep barrier after post-handshake for device {}", connectionContext.getNodeId());
connectionContext.closeConnection(false);
}
};
import org.opendaylight.openflowplugin.api.openflow.device.TranslatorLibrary;
import org.opendaylight.openflowplugin.api.openflow.device.Xid;
import org.opendaylight.openflowplugin.api.openflow.device.handlers.MultiMsgCollector;
+import org.opendaylight.openflowplugin.api.openflow.lifecycle.LifecycleService;
import org.opendaylight.openflowplugin.api.openflow.md.core.SwitchConnectionDistinguisher;
import org.opendaylight.openflowplugin.api.openflow.md.core.TranslatorKey;
import org.opendaylight.openflowplugin.api.openflow.registry.ItemLifeCycleRegistry;
// TODO: high water mark factor should be parametrized
private static final float HIGH_WATERMARK_FACTOR = 0.95f;
- private final ConnectionContext primaryConnectionContext;
+ private ConnectionContext primaryConnectionContext;
private final DeviceState deviceState;
private final DataBroker dataBroker;
private final Map<SwitchConnectionDistinguisher, ConnectionContext> auxiliaryConnectionContexts;
@Nonnull final MessageSpy messageSpy,
@Nonnull final TranslatorLibrary translatorLibrary,
@Nonnull final DeviceManager manager,
- final ConvertorExecutor convertorExecutor) {
+ final ConvertorExecutor convertorExecutor) {
this.primaryConnectionContext = Preconditions.checkNotNull(primaryConnectionContext);
this.deviceInfo = primaryConnectionContext.getDeviceInfo();
this.deviceState = new DeviceStateImpl();
public void removeAuxiliaryConnectionContext(final ConnectionContext connectionContext) {
final SwitchConnectionDistinguisher connectionDistinguisher = createConnectionDistinguisher(connectionContext);
LOG.debug("auxiliary connection dropped: {}, nodeId:{}", connectionContext.getConnectionAdapter()
- .getRemoteAddress(), getDeviceInfo().getNodeId());
+ .getRemoteAddress(), getDeviceInfo().getLOGValue());
auxiliaryConnectionContexts.remove(connectionDistinguisher);
}
// Trigger off a notification
notificationPublishService.offerNotification(flowRemovedNotification);
} else if(LOG.isDebugEnabled()) {
- LOG.debug("For nodeId={} isNotificationFlowRemovedOff={}", getDeviceInfo().getNodeId(), deviceManager.getIsNotificationFlowRemovedOff());
+ LOG.debug("For nodeId={} isNotificationFlowRemovedOff={}", getDeviceInfo().getLOGValue(), deviceManager.getIsNotificationFlowRemovedOff());
}
final ItemLifecycleListener itemLifecycleListener = flowLifeCycleKeeper.getItemLifecycleListener();
public synchronized void close() {
LOG.debug("closing deviceContext: {}, nodeId:{}",
getPrimaryConnectionContext().getConnectionAdapter().getRemoteAddress(),
- getDeviceInfo().getNodeId());
+ getDeviceInfo().getLOGValue());
// NOOP
throw new UnsupportedOperationException("Autocloseble.close will be removed soon");
}
@Override
public synchronized void shutdownConnection() {
- LOG.debug("Shutdown method for node {}", getDeviceInfo().getNodeId());
+ LOG.debug("Shutdown method for node {}", getDeviceInfo().getLOGValue());
if (CONTEXT_STATE.TERMINATION.equals(getState())) {
- LOG.debug("DeviceCtx for Node {} is in termination process.", getDeviceInfo().getNodeId());
+ LOG.debug("DeviceCtx for Node {} is in termination process.", getDeviceInfo().getLOGValue());
return;
}
setState(CONTEXT_STATE.TERMINATION);
if (ConnectionContext.CONNECTION_STATE.RIP.equals(getPrimaryConnectionContext().getConnectionState())) {
- LOG.debug("ConnectionCtx for Node {} is in RIP state.", getDeviceInfo().getNodeId());
+ LOG.debug("ConnectionCtx for Node {} is in RIP state.", getDeviceInfo().getLOGValue());
return;
}
/* Terminate Auxiliary Connection */
@Override
public void startupClusterServices() throws ExecutionException, InterruptedException {
- LOG.debug("Initializing transaction chain manager for node {}", getDeviceInfo().getNodeId());
+ LOG.debug("Initializing transaction chain manager for node {}", getDeviceInfo().getLOGValue());
this.transactionChainManager.activateTransactionManager();
- LOG.debug("Waiting to get node {} information", getDeviceInfo().getNodeId());
+ LOG.debug("Waiting to get node {} information", getDeviceInfo().getLOGValue());
DeviceInitializationUtils.initializeNodeInformation(this, switchFeaturesMandatory, this.convertorExecutor);
}
public DeviceInfo getDeviceInfo() {
return this.deviceInfo;
}
+
+ @Override
+ public void putLifecycleServiceIntoTxChainManager(final LifecycleService lifecycleService){
+ this.transactionChainManager.setLifecycleService(lifecycleService);
+ }
+
+ @Override
+ public void replaceConnectionContext(final ConnectionContext connectionContext){
+ // Act like we are initializing the context
+ setState(CONTEXT_STATE.INITIALIZATION);
+ this.primaryConnectionContext = connectionContext;
+ this.onPublished();
+ }
}
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
-import com.google.common.base.Verify;
import com.google.common.collect.Iterators;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import org.opendaylight.openflowjava.protocol.api.connection.OutboundQueueHandlerRegistration;
import org.opendaylight.openflowplugin.api.openflow.OFPContext;
import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext;
+import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionStatus;
import org.opendaylight.openflowplugin.api.openflow.connection.OutboundQueueProvider;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
import org.opendaylight.openflowplugin.impl.connection.OutboundQueueProviderImpl;
import org.opendaylight.openflowplugin.impl.device.listener.OpenflowProtocolListenerFullImpl;
import org.opendaylight.openflowplugin.impl.lifecycle.LifecycleServiceImpl;
-import org.opendaylight.openflowplugin.impl.util.DeviceInitializationUtils;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodesBuilder;
final ClusterSingletonServiceProvider singletonServiceProvider,
final NotificationPublishService notificationPublishService,
final HashedWheelTimer hashedWheelTimer,
- final ConvertorExecutor convertorExecutor) {
+ final ConvertorExecutor convertorExecutor) {
this.switchFeaturesMandatory = switchFeaturesMandatory;
this.globalNotificationQuota = globalNotificationQuota;
this.isNotificationFlowRemovedOff = isNotificationFlowRemovedOff;
}
@Override
- public boolean deviceConnected(@CheckForNull final ConnectionContext connectionContext) throws Exception {
+ public ConnectionStatus deviceConnected(@CheckForNull final ConnectionContext connectionContext) throws Exception {
Preconditions.checkArgument(connectionContext != null);
DeviceInfo deviceInfo = connectionContext.getDeviceInfo();
if (deviceContexts.containsKey(deviceInfo)) {
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());
+ LOG.info("Node {} already connected but context state not in TERMINATION state, replacing connection context",
+ connectionContext.getDeviceInfo().getLOGValue());
+ deviceContext.replaceConnectionContext(connectionContext);
+ return ConnectionStatus.ALREADY_CONNECTED;
} else {
- LOG.warn("Rejecting connection from node which is already connected and there exist deviceContext for it: {}", connectionContext.getNodeId().getValue());
+ LOG.warn("Rejecting connection from node which is already connected and there exist deviceContext for it: {}",
+ connectionContext.getDeviceInfo().getLOGValue());
+ return ConnectionStatus.CLOSING;
}
- return false;
}
LOG.info("ConnectionEvent: Device connected to controller, Device:{}, NodeId:{}",
final LifecycleService lifecycleService = new LifecycleServiceImpl();
lifecycleService.setDeviceContext(deviceContext);
+ deviceContext.putLifecycleServiceIntoTxChainManager(lifecycleService);
lifecycleServices.putIfAbsent(deviceInfo, lifecycleService);
connectionAdapter.setMessageListener(messageListener);
deviceInitPhaseHandler.onDeviceContextLevelUp(connectionContext.getDeviceInfo(), lifecycleService);
- return true;
+ return ConnectionStatus.MAY_CONTINUE;
}
private void updatePacketInRateLimiters() {
@Override
public void onDeviceContextLevelDown(final DeviceInfo deviceInfo) {
+
deviceContexts.remove(deviceInfo);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Device context removed for node {}", deviceInfo.getLOGValue());
+ }
+
LifecycleService lifecycleService = lifecycleServices.remove(deviceInfo);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Lifecycle service removed for node {}", deviceInfo.getLOGValue());
+ }
+
updatePacketInRateLimiters();
if (Objects.nonNull(lifecycleService)) {
try {
lifecycleService.close();
+ LOG.debug("Lifecycle service successfully closed for node {}", deviceInfo.getLOGValue());
} catch (Exception e) {
- LOG.warn("Closing service for node {} was unsuccessful ", deviceInfo.getNodeId().getValue(), e);
+ LOG.warn("Closing lifecycle service for node {} was unsuccessful ", deviceInfo.getLOGValue(), e);
}
}
}
final DeviceContext deviceCtx = this.deviceContexts.get(deviceInfo);
if (null == deviceCtx) {
- LOG.info("DeviceContext for Node {} was not found. Connection is terminated without OFP context suite.", deviceInfo.getNodeId());
+ LOG.info("DeviceContext for Node {} was not found. Connection is terminated without OFP context suite.", deviceInfo.getLOGValue());
return;
}
deviceCtx.setState(OFPContext.CONTEXT_STATE.TERMINATION);
if (!connectionContext.equals(deviceCtx.getPrimaryConnectionContext())) {
- LOG.debug("Node {} disconnected, but not primary connection.", connectionContext.getDeviceInfo().getNodeId().getValue());
+ LOG.debug("Node {} disconnected, but not primary connection.", connectionContext.getDeviceInfo().getLOGValue());
/* Connection is not PrimaryConnection so try to remove from Auxiliary Connections */
deviceCtx.removeAuxiliaryConnectionContext(connectionContext);
}
@Override
public void onSuccess(final Void result) {
- LOG.debug("TxChainManager for device {} is closed successful.", deviceInfo.getNodeId().getValue());
+ LOG.debug("TxChainManager for device {} is closed successful.", deviceInfo.getLOGValue());
deviceTerminPhaseHandler.onDeviceContextLevelDown(deviceInfo);
}
@Override
public void onFailure(final Throwable t) {
- LOG.warn("TxChainManager for device {} failed by closing.", deviceInfo.getNodeId().getValue());
+ LOG.warn("TxChainManager for device {} failed by closing.", deviceInfo.getLOGValue());
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.warn("Shutting down TxChain for node {} not completed during 10 sec. Continue anyway.", deviceInfo.getNodeId().getValue());
+ LOG.warn("Shutting down TxChain for node {} not completed during 10 sec. Continue anyway.", deviceInfo.getLOGValue());
future.cancel(false);
}
};
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
+
+import java.util.Objects;
import java.util.concurrent.CancellationException;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
private final Object txLock = new Object();
private final KeyedInstanceIdentifier<Node, NodeKey> nodeII;
private final DataBroker dataBroker;
+ private LifecycleService lifecycleService;
@GuardedBy("txLock")
private WriteTransaction wTx;
txChainFactory = dataBroker.createTransactionChain(TransactionChainManager.this);
}
+ public void setLifecycleService(final LifecycleService lifecycleService) {
+ this.lifecycleService = lifecycleService;
+ }
+
void initialSubmitWriteTransaction() {
enableSubmit();
submitWriteTransaction();
if (initCommit) {
LOG.warn("Initial commit failed. ", t);
wTx = null;
+ if (Objects.nonNull(lifecycleService)) {
+ lifecycleService.closeConnection();
+ }
}
}
});
try {
if (LOG.isDebugEnabled()) {
- LOG.debug("Starting clustering MASTER services for node {}", this.deviceContext.getDeviceInfo().getNodeId().getValue());
+ LOG.debug("Starting clustering MASTER services for node {}", this.deviceContext.getDeviceInfo().getLOGValue());
LOG.debug("===============================================");
}
private boolean connectionInterrupted() {
if (this.deviceContext.getPrimaryConnectionContext().getConnectionState().equals(ConnectionContext.CONNECTION_STATE.RIP)) {
- LOG.warn("Node {} was disconnected, will stop starting MASTER services.", this.deviceContext.getDeviceInfo().getNodeId().getValue());
+ LOG.warn("Node {} was disconnected, will stop starting MASTER services.", this.deviceContext.getDeviceInfo().getLOGValue());
return true;
}
return false;
@Override
public ListenableFuture<Void> closeServiceInstance() {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Stopping clustering MASTER services for node {}", this.deviceContext.getDeviceInfo().getLOGValue());
+ LOG.debug("===============================================");
+ }
+
+ LOG.info("Stopping role context cluster services for node {}", getIdentifier());
roleContext.stopClusterServices();
+
+ LOG.info("Stopping statistics context cluster services for node {}", getIdentifier());
statContext.stopClusterServices();
+
+ LOG.info("Stopping rpc context cluster services for node {}", getIdentifier());
rpcContext.stopClusterServices();
+
+ LOG.info("Stopping device context cluster services for node {}", getIdentifier());
return deviceContext.stopClusterServices();
}
.filter(Objects::nonNull)
.count();
- LOG.debug("Finished filling flow registry with {} flows for node: {}", flowCount, getIdentifier());
+ LOG.debug("Finished filling flow registry with {} flows for node: {}", flowCount, deviceContext.getDeviceInfo().getLOGValue());
}
}
@Override
public void onFailure(Throwable t) {
if (deviceFlowRegistryFill.isCancelled()) {
- LOG.debug("Cancelled filling flow registry with flows for node: {}", getIdentifier());
+ LOG.debug("Cancelled filling flow registry with flows for node: {}", deviceContext.getDeviceInfo().getLOGValue());
} else {
- LOG.warn("Failed filling flow registry with flows for node: {} with exception: {}", getIdentifier(), t);
+ LOG.warn("Failed filling flow registry with flows for node: {} with exception: {}", deviceContext.getDeviceInfo().getLOGValue(), t);
}
}
});
final DeviceContext deviceContext = Preconditions.checkNotNull(lifecycleService.getDeviceContext());
final RoleContext roleContext = new RoleContextImpl(deviceInfo, hashedWheelTimer, this, lifecycleService);
roleContext.setSalRoleService(new SalRoleServiceImpl(roleContext, deviceContext));
- Verify.verify(contexts.putIfAbsent(deviceInfo, roleContext) == null, "Role context for master Node %s is still not closed.", deviceInfo.getNodeId());
+ Verify.verify(contexts.putIfAbsent(deviceInfo, roleContext) == null, "Role context for master Node %s is still not closed.", deviceInfo.getLOGValue());
Futures.addCallback(roleContext.makeDeviceSlave(), new FutureCallback<RpcResult<SetRoleOutput>>() {
@Override
public void onSuccess(@Nullable RpcResult<SetRoleOutput> setRoleOutputRpcResult) {
if (LOG.isDebugEnabled()) {
- LOG.debug("Role SLAVE was successfully propagated on device, node {}", deviceInfo.getNodeId().getValue());
+ LOG.debug("Role SLAVE was successfully propagated on device, node {}", deviceInfo.getLOGValue());
}
}
@Override
public void onFailure(Throwable throwable) {
- LOG.warn("Was not able to set role SLAVE to device on node {} ",deviceInfo.getNodeId().getValue());
+ LOG.warn("Was not able to set role SLAVE to device on node {} ",deviceInfo.getLOGValue());
lifecycleService.closeConnection();
}
});
Futures.addCallback(delFuture, new FutureCallback<Void>() {
@Override
public void onSuccess(final Void result) {
- LOG.debug("Delete Node {} was successful", deviceInfo);
+ LOG.debug("Delete Node {} was successful", deviceInfo.getLOGValue());
contexts.remove(deviceInfo);
}
if (numRetries > 0) {
// We "used" one retry here, so decrement it
final int curRetries = numRetries - 1;
- LOG.debug("Delete node {} failed with exception {}. Trying again (retries left: {})", deviceInfo.getNodeId(), t, curRetries);
+ LOG.debug("Delete node {} failed with exception {}. Trying again (retries left: {})", deviceInfo.getLOGValue(), t, curRetries);
// Recursive call to this method with "one less" retry
removeDeviceFromOperationalDS(deviceInfo, curRetries);
return;
}
// No retries left, so we will just close the role context, and ignore datastore cleanup
- LOG.warn("Delete node {} failed with exception {}. No retries left, aborting", deviceInfo.getNodeId(), t);
+ LOG.warn("Delete node {} failed with exception {}. No retries left, aborting", deviceInfo.getLOGValue(), t);
contexts.remove(deviceInfo);
}
});
public void onDeviceContextLevelDown(final DeviceInfo deviceInfo) {
final RpcContext removedContext = contexts.remove(deviceInfo);
if (removedContext != null) {
- LOG.info("Unregister RPCs services for device context closure");
+ LOG.debug("Unregister RPCs services for node {}", deviceInfo.getLOGValue());
removedContext.close();
}
deviceTerminPhaseHandler.onDeviceContextLevelDown(deviceInfo);
public void onDeviceContextLevelUp(final DeviceInfo deviceInfo, final LifecycleService lifecycleService) throws Exception {
final StatisticsContext statisticsContext = new StatisticsContextImpl(deviceInfo, isStatisticsPollingEnabled, lifecycleService, convertorExecutor, this);
- Verify.verify(contexts.putIfAbsent(deviceInfo, statisticsContext) == null, "StatisticsCtx still not closed for Node {}", deviceInfo.getNodeId());
+ Verify.verify(contexts.putIfAbsent(deviceInfo, statisticsContext) == null, "StatisticsCtx still not closed for Node {}", deviceInfo.getLOGValue());
lifecycleService.setStatContext(statisticsContext);
deviceInitPhaseHandler.onDeviceContextLevelUp(deviceInfo, lifecycleService);
}
final long STATS_TIMEOUT_SEC = averageTime > 0 ? 3 * averageTime : DEFAULT_STATS_TIMEOUT_SEC;
final TimerTask timerTask = timeout -> {
if (!deviceStatisticsCollectionFuture.isDone()) {
- LOG.info("Statistics collection for node {} still in progress even after {} secs", deviceInfo.getNodeId(), STATS_TIMEOUT_SEC);
+ LOG.info("Statistics collection for node {} still in progress even after {} secs", deviceInfo.getLOGValue(), STATS_TIMEOUT_SEC);
deviceStatisticsCollectionFuture.cancel(true);
}
};
public void onDeviceContextLevelDown(final DeviceInfo deviceInfo) {
final StatisticsContext statisticsContext = contexts.remove(deviceInfo);
if (null != statisticsContext) {
- LOG.trace("Removing device context from stack. No more statistics gathering for device: {}", deviceInfo.getNodeId());
+ LOG.debug("Removing device context from stack. No more statistics gathering for device: {}", deviceInfo.getLOGValue());
statisticsContext.close();
}
deviceTerminPhaseHandler.onDeviceContextLevelDown(deviceInfo);
@Test
public void testOnHandshakeFailure2() throws Exception {
Mockito.when(connectionAdapter.getRemoteAddress()).thenReturn(InetSocketAddress.createUnresolved("ut-ofp.example.org", 4242));
+ connectionContextSpy.setNodeId(new NodeId("openflow:1"));
handshakeListener.onHandshakeFailure();
Mockito.verify(handshakeContext).close();
Mockito.verify(connectionContextSpy).closeConnection(false);
import java.math.BigInteger;
import java.net.InetSocketAddress;
import java.util.concurrent.atomic.AtomicLong;
+
+import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
assertEquals(0, deviceContext.getDeviceMeterRegistry().getAllMeterIds().size());
}
+
+ @Test
+ public void replaceConnectionContext() throws Exception {
+
+ final ConnectionContext connectionContext1 = mock(ConnectionContext.class);
+ Assert.assertEquals(deviceContext.getPrimaryConnectionContext(), connectionContext);
+ Mockito.when(connectionContext1.getConnectionAdapter()).thenReturn(connectionAdapter);
+ Mockito.doNothing().when(connectionAdapter).setPacketInFiltering(Mockito.anyBoolean());
+ deviceContext.replaceConnectionContext(connectionContext1);
+ Assert.assertEquals(deviceContext.getPrimaryConnectionContext(), connectionContext1);
+
+ }
+
}