X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=netconf%2Fcallhome-protocol%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fnetconf%2Fcallhome%2Fprotocol%2FNetconfCallHomeServer.java;h=47ee60eeccf93e7aad2f2087417a73b5f887cba8;hb=2401a0b4ea5e95292b6d7a23274992c5b57f5149;hp=34658aae5588a6bc7e5aa2426852914937c87fbf;hpb=e7abbe8b97f494030992ea8f9cc81a982695852b;p=netconf.git diff --git a/netconf/callhome-protocol/src/main/java/org/opendaylight/netconf/callhome/protocol/NetconfCallHomeServer.java b/netconf/callhome-protocol/src/main/java/org/opendaylight/netconf/callhome/protocol/NetconfCallHomeServer.java index 34658aae55..47ee60eecc 100644 --- a/netconf/callhome-protocol/src/main/java/org/opendaylight/netconf/callhome/protocol/NetconfCallHomeServer.java +++ b/netconf/callhome-protocol/src/main/java/org/opendaylight/netconf/callhome/protocol/NetconfCallHomeServer.java @@ -5,28 +5,26 @@ * 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.netconf.callhome.protocol; -import com.google.common.base.Preconditions; +import static java.util.Objects.requireNonNull; + +import com.google.common.annotations.VisibleForTesting; import java.io.IOException; import java.net.InetSocketAddress; import java.net.SocketAddress; import java.security.PublicKey; -import org.apache.sshd.ClientSession; -import org.apache.sshd.SshClient; -import org.apache.sshd.client.ServerKeyVerifier; -import org.apache.sshd.client.SessionFactory; +import org.apache.sshd.client.SshClient; import org.apache.sshd.client.future.AuthFuture; -import org.apache.sshd.client.session.ClientSessionImpl; -import org.apache.sshd.common.KeyExchange; -import org.apache.sshd.common.Session; -import org.apache.sshd.common.SessionListener; +import org.apache.sshd.client.keyverifier.ServerKeyVerifier; +import org.apache.sshd.client.session.ClientSession; +import org.apache.sshd.client.session.SessionFactory; import org.apache.sshd.common.future.SshFutureListener; import org.apache.sshd.common.io.IoAcceptor; import org.apache.sshd.common.io.IoServiceFactory; -import org.apache.sshd.common.io.mina.MinaServiceFactory; -import org.apache.sshd.common.io.nio2.Nio2ServiceFactory; +import org.apache.sshd.common.session.Session; +import org.apache.sshd.common.session.SessionListener; +import org.apache.sshd.netty.NettyIoServiceFactory; import org.opendaylight.netconf.callhome.protocol.CallHomeSessionContext.Factory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -35,48 +33,46 @@ public class NetconfCallHomeServer implements AutoCloseable, ServerKeyVerifier { private static final Logger LOG = LoggerFactory.getLogger(NetconfCallHomeServer.class); - private final IoAcceptor acceptor; - private final SshClient client; private final CallHomeAuthorizationProvider authProvider; - private final CallHomeSessionContext.Factory sessionFactory; + private final IoServiceFactory serviceFactory; private final InetSocketAddress bindAddress; - private StatusRecorder recorder; + private final StatusRecorder recorder; + private final Factory sessionFactory; + private final IoAcceptor acceptor; + private final SshClient client; + + NetconfCallHomeServer(final SshClient sshClient, final CallHomeAuthorizationProvider authProvider, + final Factory factory, final InetSocketAddress socketAddress, final StatusRecorder recorder) { + this(sshClient, authProvider, factory, socketAddress, recorder, + new NettyIoServiceFactory(factory.getNettyGroup())); + } - NetconfCallHomeServer(SshClient sshClient, CallHomeAuthorizationProvider authProvider, Factory factory, - InetSocketAddress socketAddress, StatusRecorder recorder) { - this.client = Preconditions.checkNotNull(sshClient); - this.authProvider = Preconditions.checkNotNull(authProvider); - this.sessionFactory = Preconditions.checkNotNull(factory); + @VisibleForTesting + NetconfCallHomeServer(final SshClient sshClient, final CallHomeAuthorizationProvider authProvider, + final Factory factory, final InetSocketAddress socketAddress, final StatusRecorder recorder, + final IoServiceFactory serviceFactory) { + this.client = requireNonNull(sshClient); + this.authProvider = requireNonNull(authProvider); + this.sessionFactory = requireNonNull(factory); this.bindAddress = socketAddress; this.recorder = recorder; + this.serviceFactory = requireNonNull(serviceFactory); sshClient.setServerKeyVerifier(this); + sshClient.addSessionListener(createSessionListener()); - SessionFactory clientSessions = new SessionFactory(); - clientSessions.setClient(sshClient); - clientSessions.addListener(createSessionListener()); - - IoServiceFactory minaFactory = createServiceFactory(sshClient); - this.acceptor = minaFactory.createAcceptor(clientSessions); - } - - private IoServiceFactory createServiceFactory(SshClient sshClient) { - try { - return createMinaServiceFactory(sshClient); - } catch (NoClassDefFoundError e) { - LOG.warn("Mina is not available, defaulting to NIO."); - return new Nio2ServiceFactory(sshClient); - } + acceptor = serviceFactory.createAcceptor(new SessionFactory(sshClient)); } - protected IoServiceFactory createMinaServiceFactory(SshClient sshClient) { - return new MinaServiceFactory(sshClient); + @VisibleForTesting + SshClient getClient() { + return client; } SessionListener createSessionListener() { return new SessionListener() { @Override - public void sessionEvent(Session session, Event event) { + public void sessionEvent(final Session session, final Event event) { ClientSession clientSession = (ClientSession) session; LOG.debug("SSH session {} event {}", session, event); switch (event) { @@ -92,12 +88,12 @@ public class NetconfCallHomeServer implements AutoCloseable, ServerKeyVerifier { } @Override - public void sessionCreated(Session session) { + public void sessionCreated(final Session session) { LOG.debug("SSH session {} created", session); } @Override - public void sessionClosed(Session session) { + public void sessionClosed(final Session session) { CallHomeSessionContext ctx = CallHomeSessionContext.getFrom((ClientSession) session); if (ctx != null) { ctx.removeSelf(); @@ -107,7 +103,7 @@ public class NetconfCallHomeServer implements AutoCloseable, ServerKeyVerifier { }; } - private void doPostAuth(final ClientSession session) { + private static void doPostAuth(final ClientSession session) { CallHomeSessionContext.getFrom(session).openNetconfChannel(); } @@ -121,9 +117,11 @@ public class NetconfCallHomeServer implements AutoCloseable, ServerKeyVerifier { } private SshFutureListener newAuthSshFutureListener(final ClientSession session) { + final PublicKey serverKey = session.getKex().getServerKey(); + return new SshFutureListener() { @Override - public void operationComplete(AuthFuture authFuture) { + public void operationComplete(final AuthFuture authFuture) { if (authFuture.isSuccess()) { onSuccess(); } else if (authFuture.isFailure()) { @@ -138,14 +136,9 @@ public class NetconfCallHomeServer implements AutoCloseable, ServerKeyVerifier { LOG.debug("Authorize success"); } - private void onFailure(Throwable throwable) { - ClientSessionImpl impl = (ClientSessionImpl) session; + private void onFailure(final Throwable throwable) { LOG.error("Authorize failed for session {}", session, throwable); - - KeyExchange kex = impl.getKex(); - PublicKey key = kex.getServerKey(); - recorder.reportFailedAuth(key); - + recorder.reportFailedAuth(serverKey); session.close(true); } @@ -157,7 +150,8 @@ public class NetconfCallHomeServer implements AutoCloseable, ServerKeyVerifier { } @Override - public boolean verifyServerKey(ClientSession sshClientSession, SocketAddress remoteAddress, PublicKey serverKey) { + public boolean verifyServerKey(final ClientSession sshClientSession, final SocketAddress remoteAddress, + final PublicKey serverKey) { final CallHomeAuthorization authorization = authProvider.provideAuth(remoteAddress, serverKey); // server is not authorized if (!authorization.isServerAllowed()) { @@ -181,13 +175,14 @@ public class NetconfCallHomeServer implements AutoCloseable, ServerKeyVerifier { client.start(); acceptor.bind(bindAddress); } catch (IOException e) { - LOG.error("Unable to start NETCONF CallHome Service", e); + LOG.error("Unable to start NETCONF CallHome Service on {}", bindAddress, e); throw e; } } @Override - public void close() throws Exception { + public void close() { acceptor.close(true); + serviceFactory.close(true); } }