Initial code drop of netconf protocol implementation
[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.opendaylight.controller.config.stat.ConfigProvider;
13 import org.opendaylight.protocol.util.SSLUtil;
14
15 import javax.net.ssl.SSLContext;
16 import java.io.File;
17 import java.io.FileInputStream;
18 import java.io.InputStream;
19 import java.net.InetSocketAddress;
20
21 import static com.google.common.base.Preconditions.checkNotNull;
22 import static com.google.common.base.Preconditions.checkState;
23
24 public class NetconfConfigUtil {
25     private static final String PREFIX_PROP = "netconf.";
26
27     private enum InfixProp {
28         tcp, tls
29     }
30
31     private static final String PORT_SUFFIX_PROP = ".port";
32     private static final String ADDRESS_SUFFIX_PROP = ".address";
33
34     private static final String NETCONF_TLS_KEYSTORE_PROP = PREFIX_PROP + InfixProp.tls + ".keystore";
35     private static final String NETCONF_TLS_KEYSTORE_PASSWORD_PROP = NETCONF_TLS_KEYSTORE_PROP + ".password";
36
37     public static Optional<InetSocketAddress> extractTCPNetconfAddress(ConfigProvider configProvider) {
38         return extractSomeNetconfAddress(configProvider, InfixProp.tcp);
39     }
40
41     public static Optional<TLSConfiguration> extractTLSConfiguration(ConfigProvider configProvider) {
42         Optional<InetSocketAddress> address = extractSomeNetconfAddress(configProvider, InfixProp.tls);
43         if (address.isPresent()) {
44             String keystoreFileName = configProvider.getProperty(NETCONF_TLS_KEYSTORE_PROP);
45             File keystoreFile = new File(keystoreFileName);
46             checkState(keystoreFile.exists() && keystoreFile.isFile() && keystoreFile.canRead(),
47                     "Keystore file %s does not exist or is not readable file", keystoreFileName);
48             keystoreFile = keystoreFile.getAbsoluteFile();
49             String keystorePassword = configProvider.getProperty(NETCONF_TLS_KEYSTORE_PASSWORD_PROP);
50             checkNotNull(keystoreFileName, "Property %s must be defined for tls netconf server",
51                     NETCONF_TLS_KEYSTORE_PROP);
52             keystorePassword = keystorePassword != null ? keystorePassword : "";
53             return Optional.of(new TLSConfiguration(address.get(), keystoreFile, keystorePassword));
54         } else {
55             return Optional.absent();
56         }
57     }
58
59     public static class TLSConfiguration {
60         private final InetSocketAddress address;
61         private final File keystoreFile;
62         private final String keystorePassword;
63         private final SSLContext sslContext;
64
65         TLSConfiguration(InetSocketAddress address, File keystoreFile, String keystorePassword) {
66             this.address = address;
67             this.keystoreFile = keystoreFile;
68             this.keystorePassword = keystorePassword;
69             try {
70                 try (InputStream keyStoreIS = new FileInputStream(keystoreFile)) {
71                     try (InputStream trustStoreIS = new FileInputStream(keystoreFile)) {
72                         sslContext = SSLUtil.initializeSecureContext("password", keyStoreIS, trustStoreIS, "SunX509");
73                     }
74                 }
75             } catch (Exception e) {
76                 throw new RuntimeException("Cannot initialize ssl context for netconf file " + keystoreFile, e);
77             }
78         }
79
80         public SSLContext getSslContext() {
81             return sslContext;
82         }
83
84         public InetSocketAddress getAddress() {
85             return address;
86         }
87
88         public File getKeystoreFile() {
89             return keystoreFile;
90         }
91
92         public String getKeystorePassword() {
93             return keystorePassword;
94         }
95     }
96
97     /**
98      * @param configProvider
99      *            from which properties are being read.
100      * @param infixProp
101      *            either tcp or tls
102      * @return absent if address is missing, value if address and port are
103      *         valid.
104      * @throws IllegalStateException
105      *             if address or port are invalid
106      */
107     private static Optional<InetSocketAddress> extractSomeNetconfAddress(ConfigProvider configProvider,
108             InfixProp infixProp) {
109         String address = configProvider.getProperty(PREFIX_PROP + infixProp + ADDRESS_SUFFIX_PROP);
110         if (address == null) {
111             return Optional.absent();
112         }
113         String portKey = PREFIX_PROP + infixProp + PORT_SUFFIX_PROP;
114         String portString = configProvider.getProperty(portKey);
115         checkNotNull(portString, "Netconf port must be specified in properties file with " + portKey);
116         try {
117             int port = Integer.valueOf(portString);
118             return Optional.of(new InetSocketAddress(address, port));
119         } catch (RuntimeException e) {
120             throw new IllegalStateException("Cannot create " + infixProp + " netconf address from address:" + address
121                     + " and port:" + portString, e);
122         }
123     }
124 }