2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
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
9 package org.opendaylight.controller.netconf.util.osgi;
11 import com.google.common.base.Optional;
12 import org.osgi.framework.BundleContext;
13 import org.slf4j.Logger;
14 import org.slf4j.LoggerFactory;
16 import java.net.InetSocketAddress;
18 public final class NetconfConfigUtil {
19 private static final Logger logger = LoggerFactory.getLogger(NetconfConfigUtil.class);
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);
26 private static final String PREFIX_PROP = "netconf.";
28 private NetconfConfigUtil() {
31 private enum InfixProp {
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";
40 private static final String CONNECTION_TIMEOUT_MILLIS_PROP = "connectionTimeoutMillis";
41 private static final long DEFAULT_TIMEOUT_MILLIS = 5000;
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;
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;
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);
65 return netconfTcpAddress;
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);
74 * Get extracted address or default.
76 * @throws java.lang.IllegalStateException if neither address is present.
78 private static InetSocketAddress getNetconfAddress(final InetSocketAddress defaultAddress, Optional<InetSocketAddress> extractedAddress, InfixProp infix) {
79 InetSocketAddress inetSocketAddress;
81 if (extractedAddress.isPresent() == false) {
82 logger.debug("Netconf {} address not found, falling back to default {}", infix, defaultAddress);
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");
88 inetSocketAddress = defaultAddress;
90 inetSocketAddress = extractedAddress.get();
93 return inetSocketAddress;
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;
103 public static String getPrivateKeyPath(final BundleContext context) {
104 return getPropertyValue(context, PREFIX_PROP + InfixProp.ssh + PRIVATE_KEY_PATH_PROP);
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 + "'");
112 return propertyValue;
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
121 private static Optional<InetSocketAddress> extractNetconfServerAddress(final BundleContext context,
122 final InfixProp infixProp) {
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);
127 if (address.isPresent() && port.isPresent()) {
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);
135 return Optional.absent();
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);
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);
150 if (address.isPresent() && port.isPresent()) {
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);
158 return extractNetconfServerAddress(context, infixProp);
161 private static Optional<String> getProperty(final BundleContext context, final String propKey) {
162 String value = context.getProperty(propKey);
163 if (value != null && value.isEmpty()) {
166 return Optional.fromNullable(value);