Merge "Removed `which` dependency, now using proper shell builtin."
[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 io.netty.channel.local.LocalAddress;
13 import java.net.InetSocketAddress;
14 import org.osgi.framework.BundleContext;
15 import org.slf4j.Logger;
16 import org.slf4j.LoggerFactory;
17
18 public final class NetconfConfigUtil {
19     private static final Logger logger = LoggerFactory.getLogger(NetconfConfigUtil.class);
20
21     private static final String PREFIX_PROP = "netconf.";
22
23     private NetconfConfigUtil() {
24     }
25
26     public enum InfixProp {
27         tcp, ssh
28     }
29
30     private static final String PORT_SUFFIX_PROP = ".port";
31     private static final String ADDRESS_SUFFIX_PROP = ".address";
32     private static final String PRIVATE_KEY_PATH_PROP = ".pk.path";
33
34     private static final String CONNECTION_TIMEOUT_MILLIS_PROP = "connectionTimeoutMillis";
35     private static final long DEFAULT_TIMEOUT_MILLIS = 5000;
36     private static final LocalAddress netconfLocalAddress = new LocalAddress("netconf");
37
38     public static LocalAddress getNetconfLocalAddress() {
39         return netconfLocalAddress;
40     }
41
42     public static long extractTimeoutMillis(final BundleContext bundleContext) {
43         final String key = PREFIX_PROP + CONNECTION_TIMEOUT_MILLIS_PROP;
44         final String timeoutString = bundleContext.getProperty(key);
45         if (timeoutString == null || timeoutString.length() == 0) {
46             return DEFAULT_TIMEOUT_MILLIS;
47         }
48         try {
49             return Long.parseLong(timeoutString);
50         } catch (final NumberFormatException e) {
51             logger.warn("Cannot parse {} property: {}, using defaults", key, timeoutString, e);
52             return DEFAULT_TIMEOUT_MILLIS;
53         }
54     }
55
56     /**
57      * Get extracted address or default.
58      *
59      * @throws java.lang.IllegalStateException if neither address is present.
60      */
61     private static InetSocketAddress getNetconfAddress(final InetSocketAddress defaultAddress, Optional<InetSocketAddress> extractedAddress, InfixProp infix) {
62         InetSocketAddress inetSocketAddress;
63
64         if (extractedAddress.isPresent() == false) {
65             logger.debug("Netconf {} address not found, falling back to default {}", infix, defaultAddress);
66
67             if (defaultAddress == null) {
68                 logger.warn("Netconf {} address not found, default address not provided", infix);
69                 throw new IllegalStateException("Netconf " + infix + " address not found, default address not provided");
70             }
71             inetSocketAddress = defaultAddress;
72         } else {
73             inetSocketAddress = extractedAddress.get();
74         }
75
76         return inetSocketAddress;
77     }
78
79     public static String getPrivateKeyPath(final BundleContext context) {
80         return getPropertyValue(context, getPrivateKeyKey());
81     }
82
83     public static String getPrivateKeyKey() {
84         return PREFIX_PROP + InfixProp.ssh + PRIVATE_KEY_PATH_PROP;
85     }
86
87     private static String getPropertyValue(final BundleContext context, final String propertyName) {
88         final String propertyValue = context.getProperty(propertyName);
89         if (propertyValue == null) {
90             throw new IllegalStateException("Cannot find initial property with name '" + propertyName + "'");
91         }
92         return propertyValue;
93     }
94
95     public static String getNetconfServerAddressKey(InfixProp infixProp) {
96         return PREFIX_PROP + infixProp + ADDRESS_SUFFIX_PROP;
97     }
98
99     /**
100      * @param context   from which properties are being read.
101      * @param infixProp either tcp or ssh
102      * @return value if address and port are present and valid, Optional.absent otherwise.
103      * @throws IllegalStateException if address or port are invalid, or configuration is missing
104      */
105     public static Optional<InetSocketAddress> extractNetconfServerAddress(final BundleContext context,
106                                                                            final InfixProp infixProp) {
107
108         final Optional<String> address = getProperty(context, getNetconfServerAddressKey(infixProp));
109         final Optional<String> port = getProperty(context, PREFIX_PROP + infixProp + PORT_SUFFIX_PROP);
110
111         if (address.isPresent() && port.isPresent()) {
112             try {
113                 return Optional.of(parseAddress(address, port));
114             } catch (final RuntimeException e) {
115                 logger.warn("Unable to parse {} netconf address from {}:{}, fallback to default",
116                         infixProp, address, port, e);
117             }
118         }
119         return Optional.absent();
120     }
121
122     private static InetSocketAddress parseAddress(final Optional<String> address, final Optional<String> port) {
123         final int portNumber = Integer.valueOf(port.get());
124         return new InetSocketAddress(address.get(), portNumber);
125     }
126
127     private static Optional<String> getProperty(final BundleContext context, final String propKey) {
128         String value = context.getProperty(propKey);
129         if (value != null && value.isEmpty()) {
130             value = null;
131         }
132         return Optional.fromNullable(value);
133     }
134 }