X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=openflowplugin-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fopenflowplugin%2Fimpl%2Fconnection%2Flistener%2FSystemNotificationsListenerImpl.java;h=e98cca75de4e76269dbd57acc03ca60d02b8c51d;hb=refs%2Fchanges%2F95%2F110195%2F2;hp=5f7a8e9d04d1decb93e6ccbbf9fb7cdf6858ce7c;hpb=a6082c15381046d10772dda7fbdc0e2c620f30a6;p=openflowplugin.git diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/connection/listener/SystemNotificationsListenerImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/connection/listener/SystemNotificationsListenerImpl.java index 5f7a8e9d04..e98cca75de 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/connection/listener/SystemNotificationsListenerImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/connection/listener/SystemNotificationsListenerImpl.java @@ -1,4 +1,4 @@ -/** +/* * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. * * This program and the accompanying materials are made available under the @@ -7,62 +7,86 @@ */ package org.opendaylight.openflowplugin.impl.connection.listener; +import static java.util.Objects.requireNonNull; + import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Preconditions; import java.net.InetSocketAddress; import java.util.Date; import java.util.Objects; +import java.util.concurrent.Executor; import java.util.concurrent.Future; -import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; -import javax.annotation.Nonnull; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; +import org.opendaylight.mdsal.binding.api.NotificationPublishService; +import org.opendaylight.openflowjava.protocol.api.connection.ConnectionAdapter.SystemListener; import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext; import org.opendaylight.openflowplugin.api.openflow.device.Xid; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IetfInetUtil; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.node.ssl.connection.error.service.rev190723.SslErrorBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.node.ssl.connection.error.service.rev190723.SslErrorType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.node.ssl.connection.error.service.rev190723.ssl.error.SwitchCertificateBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FeaturesReply; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.system.rev130927.DisconnectEvent; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.system.rev130927.SslConnectionError; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.system.rev130927.SwitchIdleEvent; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.system.rev130927.SystemNotificationsListener; import org.opendaylight.yangtools.yang.common.RpcError; import org.opendaylight.yangtools.yang.common.RpcResult; +import org.opendaylight.yangtools.yang.common.Uint16; +import org.opendaylight.yangtools.yang.common.Uint32; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -/** - * - */ -public class SystemNotificationsListenerImpl implements SystemNotificationsListener { - +public class SystemNotificationsListenerImpl implements SystemListener { private static final Logger LOG = LoggerFactory.getLogger(SystemNotificationsListenerImpl.class); - private static final Xid ECHO_XID = new Xid(0L); + private static final Logger OF_EVENT_LOG = LoggerFactory.getLogger("OfEventLog"); + private static final Xid ECHO_XID = new Xid(Uint32.ZERO); private final ConnectionContext connectionContext; @VisibleForTesting static final long MAX_ECHO_REPLY_TIMEOUT = 2000; private final long echoReplyTimeout; - private final ThreadPoolExecutor threadPool; + private final Executor executor; + private final NotificationPublishService notificationPublishService; - public SystemNotificationsListenerImpl(@Nonnull final ConnectionContext connectionContext, - long echoReplyTimeout, - @Nonnull final ThreadPoolExecutor threadPool) { - this.threadPool = threadPool; - this.connectionContext = Preconditions.checkNotNull(connectionContext); + public SystemNotificationsListenerImpl(@NonNull final ConnectionContext connectionContext, + final long echoReplyTimeout, final @NonNull Executor executor, + @NonNull final NotificationPublishService notificationPublishService) { + this.connectionContext = requireNonNull(connectionContext); this.echoReplyTimeout = echoReplyTimeout; + this.executor = requireNonNull(executor); + this.notificationPublishService = requireNonNull(notificationPublishService); } @Override - public void onDisconnectEvent(final DisconnectEvent notification) { - LOG.info("ConnectionEvent: Connection closed by device, Device:{}, NodeId:{}", - connectionContext.getConnectionAdapter().getRemoteAddress(), connectionContext.getSafeNodeIdForLOG()); - connectionContext.onConnectionClosed(); + public void onSslConnectionError(final SslConnectionError sslConnectionError) { + final var switchCert = sslConnectionError.getSwitchCertificate(); + notificationPublishService.offerNotification(new SslErrorBuilder() + .setType(SslErrorType.SslConFailed) + .setCode(Uint16.valueOf(SslErrorType.SslConFailed.getIntValue())) + .setNodeIpAddress(remoteAddress()) + .setData(sslConnectionError.getInfo()) + .setSwitchCertificate(switchCert == null ? null : new SwitchCertificateBuilder(switchCert).build()) + .build()); } @Override - public void onSwitchIdleEvent(final SwitchIdleEvent notification) { - threadPool.execute(this::executeOnSwitchIdleEvent); + public void onSwitchIdle(final SwitchIdleEvent switchIdle) { + executor.execute(this::executeOnSwitchIdleEvent); } + @Override + public void onDisconnect(final DisconnectEvent notification) { + OF_EVENT_LOG.debug("Disconnect, Node: {}", connectionContext.getSafeNodeIdForLOG()); + LOG.info("ConnectionEvent: Connection closed by device, Device:{}, NodeId:{}", + connectionContext.getConnectionAdapter().getRemoteAddress(), connectionContext.getSafeNodeIdForLOG()); + connectionContext.onConnectionClosed(); + } + + @SuppressWarnings("checkstyle:IllegalCatch") private void executeOnSwitchIdleEvent() { boolean shouldBeDisconnected = true; @@ -70,18 +94,20 @@ public class SystemNotificationsListenerImpl implements SystemNotificationsListe if (ConnectionContext.CONNECTION_STATE.WORKING.equals(connectionContext.getConnectionState())) { FeaturesReply features = connectionContext.getFeatures(); - LOG.info("Switch Idle state occurred, node={}|auxId={}", remoteAddress, features.getAuxiliaryId()); + LOG.debug("Switch Idle state occurred, node={}|auxId={}", remoteAddress, features.getAuxiliaryId()); + OF_EVENT_LOG.debug("Switch idle state, Node: {}", features.getDatapathId()); connectionContext.changeStateToTimeouting(); EchoInputBuilder builder = new EchoInputBuilder(); builder.setVersion(features.getVersion()); builder.setXid(ECHO_XID.getValue()); - Future> echoReplyFuture = connectionContext.getConnectionAdapter().echo(builder.build()); + Future> echoReplyFuture = + connectionContext.getConnectionAdapter().echo(builder.build()); try { RpcResult echoReplyValue = echoReplyFuture.get(echoReplyTimeout, TimeUnit.MILLISECONDS); - if (echoReplyValue.isSuccessful() && - Objects.equals(echoReplyValue.getResult().getXid(), ECHO_XID.getValue())) { + if (echoReplyValue.isSuccessful() + && Objects.equals(echoReplyValue.getResult().getXid(), ECHO_XID.getValue())) { connectionContext.changeStateToWorking(); shouldBeDisconnected = false; } else { @@ -89,11 +115,13 @@ public class SystemNotificationsListenerImpl implements SystemNotificationsListe } } catch (Exception e) { if (LOG.isWarnEnabled()) { - LOG.warn("Exception while waiting for echoReply from [{}] in TIMEOUTING state: {}", remoteAddress, e.getMessage()); + LOG.warn("Exception while waiting for echoReply from [{}] in TIMEOUTING state: {}", + remoteAddress, e.getMessage()); } if (LOG.isTraceEnabled()) { - LOG.trace("Exception while waiting for echoReply from [{}] in TIMEOUTING state: {}", remoteAddress, e); + LOG.trace("Exception while waiting for echoReply from [{}] in TIMEOUTING state", + remoteAddress, e); } } @@ -101,24 +129,39 @@ public class SystemNotificationsListenerImpl implements SystemNotificationsListe if (shouldBeDisconnected) { if (LOG.isInfoEnabled()) { LOG.info("ConnectionEvent:Closing connection as device is idle. Echo sent at {}. Device:{}, NodeId:{}", - new Date(System.currentTimeMillis() - echoReplyTimeout), remoteAddress, connectionContext.getSafeNodeIdForLOG()); + new Date(System.currentTimeMillis() - echoReplyTimeout), + remoteAddress, connectionContext.getSafeNodeIdForLOG()); } connectionContext.closeConnection(true); } } - private void logErrors(InetSocketAddress remoteAddress, RpcResult echoReplyValue) { + private static void logErrors(final InetSocketAddress remoteAddress, final RpcResult echoReplyValue) { for (RpcError replyError : echoReplyValue.getErrors()) { Throwable cause = replyError.getCause(); if (LOG.isWarnEnabled()) { - LOG.warn("Received EchoReply from [{}] in TIMEOUTING state, Error:{}", remoteAddress, cause.getMessage()); + LOG.warn("Received EchoReply from [{}] in TIMEOUTING state, Error:{}", + remoteAddress, cause.getMessage()); } if (LOG.isTraceEnabled()) { - LOG.trace("Received EchoReply from [{}] in TIMEOUTING state, Error:{}", remoteAddress, cause); + LOG.trace("Received EchoReply from [{}] in TIMEOUTING state", remoteAddress, cause); } + } + } + private @Nullable IpAddress remoteAddress() { + final var connectionAdapter = connectionContext.getConnectionAdapter(); + if (connectionAdapter != null) { + final var remoteAddress = connectionAdapter.getRemoteAddress(); + if (remoteAddress != null) { + final var inetAddress = remoteAddress.getAddress(); + if (inetAddress != null) { + return IetfInetUtil.ipAddressFor(inetAddress.getHostAddress()); + } + } } + return null; } }