Merge "BUG-624 make netconf tcp address optional in config.ini with default value...
[controller.git] / opendaylight / netconf / netconf-util / src / main / java / org / opendaylight / controller / netconf / util / osgi / NetconfConfigUtil.java
1 /*
2  * Copyright (c) 2013 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.netconf.util.osgi;
10
11 import com.google.common.base.Optional;
12 import org.osgi.framework.BundleContext;
13 import org.slf4j.Logger;
14 import org.slf4j.LoggerFactory;
15
16 import java.net.InetSocketAddress;
17
18 public final class NetconfConfigUtil {
19     private static final Logger logger = LoggerFactory.getLogger(NetconfConfigUtil.class);
20
21     public static final InetSocketAddress DEFAULT_NETCONF_TCP_ADDRESS
22             = new InetSocketAddress("127.0.0.1", 8383);
23     public static final InetSocketAddress DEFAULT_NETCONF_SSH_ADDRESS
24             = new InetSocketAddress("0.0.0.0", 1830);
25
26     private static final String PREFIX_PROP = "netconf.";
27
28     private NetconfConfigUtil() {
29     }
30
31     private enum InfixProp {
32         tcp, ssh
33     }
34
35     private static final String PORT_SUFFIX_PROP = ".port";
36     private static final String ADDRESS_SUFFIX_PROP = ".address";
37     private static final String CLIENT_PROP = ".client";
38     private static final String PRIVATE_KEY_PATH_PROP = ".pk.path";
39
40     private static final String CONNECTION_TIMEOUT_MILLIS_PROP = "connectionTimeoutMillis";
41     private static final long DEFAULT_TIMEOUT_MILLIS = 5000;
42
43     public static long extractTimeoutMillis(final BundleContext bundleContext) {
44         final String key = PREFIX_PROP + CONNECTION_TIMEOUT_MILLIS_PROP;
45         final String timeoutString = bundleContext.getProperty(key);
46         if (timeoutString == null || timeoutString.length() == 0) {
47             return DEFAULT_TIMEOUT_MILLIS;
48         }
49         try {
50             return Long.parseLong(timeoutString);
51         } catch (final NumberFormatException e) {
52             logger.warn("Cannot parse {} property: {}, using defaults", key, timeoutString, e);
53             return DEFAULT_TIMEOUT_MILLIS;
54         }
55     }
56
57     public static InetSocketAddress extractTCPNetconfServerAddress(final BundleContext context, final InetSocketAddress defaultAddress) {
58         final Optional<InetSocketAddress> extracted = extractNetconfServerAddress(context, InfixProp.tcp);
59         final InetSocketAddress netconfTcpAddress = getNetconfAddress(defaultAddress, extracted, InfixProp.tcp);
60         logger.debug("Using {} as netconf tcp address", netconfTcpAddress);
61         if (netconfTcpAddress.getAddress().isAnyLocalAddress()) {
62             logger.warn("Unprotected netconf TCP address is configured to ANY local address. This is a security risk. " +
63                     "Consider changing {} to 127.0.0.1", PREFIX_PROP + InfixProp.tcp + ADDRESS_SUFFIX_PROP);
64         }
65         return netconfTcpAddress;
66     }
67
68     public static InetSocketAddress extractTCPNetconfClientAddress(final BundleContext context, final InetSocketAddress defaultAddress) {
69         final Optional<InetSocketAddress> extracted = extractNetconfClientAddress(context, InfixProp.tcp);
70         return getNetconfAddress(defaultAddress, extracted, InfixProp.tcp);
71     }
72
73     /**
74      * Get extracted address or default.
75      *
76      * @throws java.lang.IllegalStateException if neither address is present.
77      */
78     private static InetSocketAddress getNetconfAddress(final InetSocketAddress defaultAddress, Optional<InetSocketAddress> extractedAddress, InfixProp infix) {
79         InetSocketAddress inetSocketAddress;
80
81         if (extractedAddress.isPresent() == false) {
82             logger.debug("Netconf {} address not found, falling back to default {}", infix, defaultAddress);
83
84             if (defaultAddress == null) {
85                 logger.warn("Netconf {} address not found, default address not provided", infix);
86                 throw new IllegalStateException("Netconf " + infix + " address not found, default address not provided");
87             }
88             inetSocketAddress = defaultAddress;
89         } else {
90             inetSocketAddress = extractedAddress.get();
91         }
92
93         return inetSocketAddress;
94     }
95
96     public static InetSocketAddress extractSSHNetconfAddress(final BundleContext context, final InetSocketAddress defaultAddress) {
97         Optional<InetSocketAddress> extractedAddress = extractNetconfServerAddress(context, InfixProp.ssh);
98         InetSocketAddress netconfSSHAddress = getNetconfAddress(defaultAddress, extractedAddress, InfixProp.ssh);
99         logger.debug("Using {} as netconf SSH address", netconfSSHAddress);
100         return netconfSSHAddress;
101     }
102
103     public static String getPrivateKeyPath(final BundleContext context) {
104         return getPropertyValue(context, PREFIX_PROP + InfixProp.ssh + PRIVATE_KEY_PATH_PROP);
105     }
106
107     private static String getPropertyValue(final BundleContext context, final String propertyName) {
108         final String propertyValue = context.getProperty(propertyName);
109         if (propertyValue == null) {
110             throw new IllegalStateException("Cannot find initial property with name '" + propertyName + "'");
111         }
112         return propertyValue;
113     }
114
115     /**
116      * @param context   from which properties are being read.
117      * @param infixProp either tcp or ssh
118      * @return value if address and port are present and valid, Optional.absent otherwise.
119      * @throws IllegalStateException if address or port are invalid, or configuration is missing
120      */
121     private static Optional<InetSocketAddress> extractNetconfServerAddress(final BundleContext context,
122                                                                            final InfixProp infixProp) {
123
124         final Optional<String> address = getProperty(context, PREFIX_PROP + infixProp + ADDRESS_SUFFIX_PROP);
125         final Optional<String> port = getProperty(context, PREFIX_PROP + infixProp + PORT_SUFFIX_PROP);
126
127         if (address.isPresent() && port.isPresent()) {
128             try {
129                 return Optional.of(parseAddress(address, port));
130             } catch (final RuntimeException e) {
131                 logger.warn("Unable to parse {} netconf address from {}:{}, fallback to default",
132                         infixProp, address, port, e);
133             }
134         }
135         return Optional.absent();
136     }
137
138     private static InetSocketAddress parseAddress(final Optional<String> address, final Optional<String> port) {
139         final int portNumber = Integer.valueOf(port.get());
140         return new InetSocketAddress(address.get(), portNumber);
141     }
142
143     private static Optional<InetSocketAddress> extractNetconfClientAddress(final BundleContext context,
144                                                                            final InfixProp infixProp) {
145         final Optional<String> address = getProperty(context,
146                 PREFIX_PROP + infixProp + CLIENT_PROP + ADDRESS_SUFFIX_PROP);
147         final Optional<String> port = getProperty(context,
148                 PREFIX_PROP + infixProp + CLIENT_PROP + PORT_SUFFIX_PROP);
149
150         if (address.isPresent() && port.isPresent()) {
151             try {
152                 return Optional.of(parseAddress(address, port));
153             } catch (final RuntimeException e) {
154                 logger.warn("Unable to parse client {} netconf address from {}:{}, fallback to server address",
155                         infixProp, address, port, e);
156             }
157         }
158         return extractNetconfServerAddress(context, infixProp);
159     }
160
161     private static Optional<String> getProperty(final BundleContext context, final String propKey) {
162         String value = context.getProperty(propKey);
163         if (value != null && value.isEmpty()) {
164             value = null;
165         }
166         return Optional.fromNullable(value);
167     }
168 }