Merge "Fixed for bug : 1171 - issue while creating subnet"
[controller.git] / opendaylight / md-sal / sal-netconf-connector / src / main / java / org / opendaylight / controller / config / yang / md / sal / connector / netconf / NetconfConnectorModule.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 package org.opendaylight.controller.config.yang.md.sal.connector.netconf;
9
10 import static org.opendaylight.controller.config.api.JmxAttributeValidationException.checkCondition;
11 import static org.opendaylight.controller.config.api.JmxAttributeValidationException.checkNotNull;
12
13 import java.io.File;
14 import java.io.InputStream;
15 import java.net.InetSocketAddress;
16 import java.util.concurrent.ExecutorService;
17
18 import org.opendaylight.controller.netconf.client.NetconfClientDispatcher;
19 import org.opendaylight.controller.netconf.client.conf.NetconfClientConfiguration;
20 import org.opendaylight.controller.netconf.client.conf.NetconfReconnectingClientConfiguration;
21 import org.opendaylight.controller.netconf.client.conf.NetconfReconnectingClientConfigurationBuilder;
22 import org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication.LoginPassword;
23 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
24 import org.opendaylight.controller.sal.connect.api.RemoteDeviceHandler;
25 import org.opendaylight.controller.sal.connect.netconf.NetconfDevice;
26 import org.opendaylight.controller.sal.connect.netconf.listener.NetconfDeviceCommunicator;
27 import org.opendaylight.controller.sal.connect.netconf.sal.NetconfDeviceSalFacade;
28 import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
29 import org.opendaylight.controller.sal.core.api.Broker;
30 import org.opendaylight.protocol.framework.ReconnectStrategy;
31 import org.opendaylight.protocol.framework.ReconnectStrategyFactory;
32 import org.opendaylight.protocol.framework.TimedReconnectStrategy;
33 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Host;
34 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
35 import org.opendaylight.yangtools.yang.model.util.repo.AbstractCachingSchemaSourceProvider;
36 import org.opendaylight.yangtools.yang.model.util.repo.FilesystemSchemaCachingProvider;
37 import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProvider;
38 import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProviders;
39 import org.osgi.framework.BundleContext;
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
42
43 /**
44  *
45  */
46 public final class NetconfConnectorModule extends org.opendaylight.controller.config.yang.md.sal.connector.netconf.AbstractNetconfConnectorModule
47 {
48     private static final Logger logger = LoggerFactory.getLogger(NetconfConnectorModule.class);
49
50     private static AbstractCachingSchemaSourceProvider<String, InputStream> GLOBAL_NETCONF_SOURCE_PROVIDER = null;
51     private BundleContext bundleContext;
52
53     public NetconfConnectorModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier, final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
54         super(identifier, dependencyResolver);
55     }
56
57     public NetconfConnectorModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier, final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, final NetconfConnectorModule oldModule, final java.lang.AutoCloseable oldInstance) {
58         super(identifier, dependencyResolver, oldModule, oldInstance);
59     }
60
61     @Override
62     protected void customValidation() {
63         checkNotNull(getAddress(), addressJmxAttribute);
64         checkCondition(isHostAddressPresent(getAddress()), "Host address not present in " + getAddress(), addressJmxAttribute);
65         checkNotNull(getPort(), portJmxAttribute);
66         checkNotNull(getDomRegistry(), portJmxAttribute);
67         checkNotNull(getDomRegistry(), domRegistryJmxAttribute);
68
69         checkNotNull(getConnectionTimeoutMillis(), connectionTimeoutMillisJmxAttribute);
70         checkCondition(getConnectionTimeoutMillis() > 0, "must be > 0", connectionTimeoutMillisJmxAttribute);
71
72         checkNotNull(getBetweenAttemptsTimeoutMillis(), betweenAttemptsTimeoutMillisJmxAttribute);
73         checkCondition(getBetweenAttemptsTimeoutMillis() > 0, "must be > 0", betweenAttemptsTimeoutMillisJmxAttribute);
74
75         checkNotNull(getClientDispatcher(), clientDispatcherJmxAttribute);
76         checkNotNull(getBindingRegistry(), bindingRegistryJmxAttribute);
77         checkNotNull(getProcessingExecutor(), processingExecutorJmxAttribute);
78
79         // Check username + password in case of ssh
80         if(getTcpOnly() == false) {
81             checkNotNull(getUsername(), usernameJmxAttribute);
82             checkNotNull(getPassword(), passwordJmxAttribute);
83         }
84
85     }
86
87     private boolean isHostAddressPresent(Host address) {
88         return address.getDomainName() != null ||
89                address.getIpAddress() != null && (address.getIpAddress().getIpv4Address() != null || address.getIpAddress().getIpv6Address() != null);
90     }
91
92     @Override
93     public java.lang.AutoCloseable createInstance() {
94         final RemoteDeviceId id = new RemoteDeviceId(getIdentifier());
95
96         final ExecutorService globalProcessingExecutor = getProcessingExecutorDependency().getExecutor();
97
98         final Broker domBroker = getDomRegistryDependency();
99         final BindingAwareBroker bindingBroker = getBindingRegistryDependency();
100
101         final RemoteDeviceHandler salFacade = new NetconfDeviceSalFacade(id, domBroker, bindingBroker, bundleContext, globalProcessingExecutor);
102         final NetconfDevice device =
103                 NetconfDevice.createNetconfDevice(id, getGlobalNetconfSchemaProvider(), globalProcessingExecutor, salFacade);
104         final NetconfDeviceCommunicator listener = new NetconfDeviceCommunicator(id, device);
105         final NetconfReconnectingClientConfiguration clientConfig = getClientConfig(listener);
106
107         final NetconfClientDispatcher dispatcher = getClientDispatcherDependency();
108         listener.initializeRemoteConnection(dispatcher, clientConfig);
109
110         return new AutoCloseable() {
111             @Override
112             public void close() throws Exception {
113                 listener.close();
114                 salFacade.close();
115             }
116         };
117     }
118
119     private synchronized AbstractCachingSchemaSourceProvider<String, InputStream> getGlobalNetconfSchemaProvider() {
120         if(GLOBAL_NETCONF_SOURCE_PROVIDER == null) {
121             final String storageFile = "cache/schema";
122             //            File directory = bundleContext.getDataFile(storageFile);
123             final File directory = new File(storageFile);
124             final SchemaSourceProvider<String> defaultProvider = SchemaSourceProviders.noopProvider();
125             GLOBAL_NETCONF_SOURCE_PROVIDER = FilesystemSchemaCachingProvider.createFromStringSourceProvider(defaultProvider, directory);
126         }
127         return GLOBAL_NETCONF_SOURCE_PROVIDER;
128     }
129
130     public void setBundleContext(final BundleContext bundleContext) {
131         this.bundleContext = bundleContext;
132     }
133
134     public NetconfReconnectingClientConfiguration getClientConfig(final NetconfDeviceCommunicator listener) {
135         final InetSocketAddress socketAddress = getSocketAddress();
136         final ReconnectStrategy strategy = getReconnectStrategy();
137         final long clientConnectionTimeoutMillis = getConnectionTimeoutMillis();
138
139         return NetconfReconnectingClientConfigurationBuilder.create()
140         .withAddress(socketAddress)
141         .withConnectionTimeoutMillis(clientConnectionTimeoutMillis)
142         .withReconnectStrategy(strategy)
143         .withSessionListener(listener)
144         .withAuthHandler(new LoginPassword(getUsername(),getPassword()))
145         .withProtocol(getTcpOnly() ?
146                 NetconfClientConfiguration.NetconfClientProtocol.TCP :
147                 NetconfClientConfiguration.NetconfClientProtocol.SSH)
148         .withConnectStrategyFactory(new ReconnectStrategyFactory() {
149             @Override
150             public ReconnectStrategy createReconnectStrategy() {
151                 return getReconnectStrategy();
152             }
153         })
154         .build();
155     }
156
157     private ReconnectStrategy getReconnectStrategy() {
158         final Long connectionAttempts;
159         if (getMaxConnectionAttempts() != null && getMaxConnectionAttempts() > 0) {
160             connectionAttempts = getMaxConnectionAttempts();
161         } else {
162             logger.trace("Setting {} on {} to infinity", maxConnectionAttemptsJmxAttribute, this);
163             connectionAttempts = null;
164         }
165         final double sleepFactor = getSleepFactor().doubleValue();
166         final int minSleep = getBetweenAttemptsTimeoutMillis();
167         final Long maxSleep = null;
168         final Long deadline = null;
169
170         return new TimedReconnectStrategy(getEventExecutorDependency(), getBetweenAttemptsTimeoutMillis(),
171                 minSleep, sleepFactor, maxSleep, connectionAttempts, deadline);
172     }
173
174     private InetSocketAddress getSocketAddress() {
175         if(getAddress().getDomainName() != null) {
176             return new InetSocketAddress(getAddress().getDomainName().getValue(), getPort().getValue());
177         } else {
178             IpAddress ipAddress = getAddress().getIpAddress();
179             String ip = ipAddress.getIpv4Address() != null ? ipAddress.getIpv4Address().getValue() : ipAddress.getIpv6Address().getValue();
180             return new InetSocketAddress(ip, getPort().getValue());
181         }
182     }
183 }