Add blueprint wiring for aaa-authn-odl-plugin
[netconf.git] / netconf / netconf-ssh / src / main / java / org / opendaylight / controller / config / yang / netconf / northbound / ssh / NetconfNorthboundSshModule.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.controller.config.yang.netconf.northbound.ssh;
10
11 import io.netty.channel.ChannelFuture;
12 import io.netty.channel.local.LocalAddress;
13 import io.netty.util.concurrent.GenericFutureListener;
14 import java.io.IOException;
15 import java.net.InetAddress;
16 import java.net.InetSocketAddress;
17 import java.net.UnknownHostException;
18 import java.util.concurrent.Executors;
19 import org.apache.sshd.server.keyprovider.PEMGeneratorHostKeyProvider;
20 import org.opendaylight.netconf.api.NetconfServerDispatcher;
21 import org.opendaylight.netconf.ssh.SshProxyServer;
22 import org.opendaylight.netconf.ssh.SshProxyServerConfigurationBuilder;
23 import org.slf4j.Logger;
24 import org.slf4j.LoggerFactory;
25
26 public class NetconfNorthboundSshModule extends org.opendaylight.controller.config.yang.netconf.northbound.ssh.AbstractNetconfNorthboundSshModule {
27
28     private static final Logger LOG = LoggerFactory.getLogger(NetconfNorthboundSshModule.class);
29
30     public NetconfNorthboundSshModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier, final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
31         super(identifier, dependencyResolver);
32     }
33
34     public NetconfNorthboundSshModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier, final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, final org.opendaylight.controller.config.yang.netconf.northbound.ssh.NetconfNorthboundSshModule oldModule, final java.lang.AutoCloseable oldInstance) {
35         super(identifier, dependencyResolver, oldModule, oldInstance);
36     }
37
38     @Override
39     public void customValidation() {
40         // add custom validation form module attributes here.
41     }
42
43     @Override
44     public java.lang.AutoCloseable createInstance() {
45         final NetconfServerDispatcher dispatch = getDispatcherDependency();
46
47         final LocalAddress localAddress = new LocalAddress(getPort().toString());
48         final ChannelFuture localServer = dispatch.createLocalServer(localAddress);
49
50         final SshProxyServer sshProxyServer = new SshProxyServer(Executors.newScheduledThreadPool(1), getWorkerThreadGroupDependency(), getEventExecutorDependency());
51
52         final InetSocketAddress bindingAddress = getInetAddress();
53         final SshProxyServerConfigurationBuilder sshProxyServerConfigurationBuilder = new SshProxyServerConfigurationBuilder();
54         sshProxyServerConfigurationBuilder.setBindingAddress(bindingAddress);
55         sshProxyServerConfigurationBuilder.setLocalAddress(localAddress);
56         sshProxyServerConfigurationBuilder.setAuthenticator(getAuthProviderDependency());
57         sshProxyServerConfigurationBuilder.setIdleTimeout(Integer.MAX_VALUE);
58         sshProxyServerConfigurationBuilder.setKeyPairProvider(new PEMGeneratorHostKeyProvider());
59
60         localServer.addListener(new GenericFutureListener<ChannelFuture>() {
61
62             @Override
63             public void operationComplete(final ChannelFuture future) {
64                 if(future.isDone() && !future.isCancelled()) {
65                     try {
66                         sshProxyServer.bind(sshProxyServerConfigurationBuilder.createSshProxyServerConfiguration());
67                         LOG.info("Netconf SSH endpoint started successfully at {}", bindingAddress);
68                     } catch (final IOException e) {
69                         throw new RuntimeException("Unable to start SSH netconf server", e);
70                     }
71                 } else {
72                     LOG.warn("Unable to start SSH netconf server at {}", bindingAddress, future.cause());
73                     throw new RuntimeException("Unable to start SSH netconf server", future.cause());
74                 }
75             }
76         });
77
78         return new NetconfServerCloseable(localServer, sshProxyServer);
79     }
80
81     private InetSocketAddress getInetAddress() {
82         try {
83             final InetAddress inetAd = InetAddress.getByName(getBindingAddress().getIpv4Address() == null ? getBindingAddress().getIpv6Address().getValue() : getBindingAddress().getIpv4Address().getValue());
84             return new InetSocketAddress(inetAd, getPort().getValue());
85         } catch (final UnknownHostException e) {
86             throw new IllegalArgumentException("Unable to bind netconf endpoint to address " + getBindingAddress(), e);
87         }
88     }
89
90     private static final class NetconfServerCloseable implements AutoCloseable {
91         private final ChannelFuture localServer;
92         private final SshProxyServer sshProxyServer;
93
94         public NetconfServerCloseable(final ChannelFuture localServer, final SshProxyServer sshProxyServer) {
95             this.localServer = localServer;
96             this.sshProxyServer = sshProxyServer;
97         }
98
99         @Override
100         public void close() throws Exception {
101             sshProxyServer.close();
102
103             if(localServer.isDone()) {
104                 localServer.channel().close();
105             } else {
106                 localServer.cancel(true);
107             }
108         }
109     }
110 }