summaryrefslogtreecommitdiffstats
path: root/infra/minimal-distribution/src/main/java/io
diff options
context:
space:
mode:
authorMaros Marsalek <mmarsale@cisco.com>2016-08-17 15:38:01 +0200
committerMaros Marsalek <mmarsale@cisco.com>2016-08-19 12:49:56 +0200
commit3341ac467cc08ac95f937945c7502ac4a019d805 (patch)
tree1b13df9f8709d123c6fe50a9fa21d3686554e65f /infra/minimal-distribution/src/main/java/io
parent672f0c90fdbf4b5dc60cbfaaaf262e16561fdb7a (diff)
Make Restconf thread pools configurable
Change-Id: Ie03a1fde5181cfd8457e36d67afc2cc0c69c1e1d Signed-off-by: Maros Marsalek <mmarsale@cisco.com>
Diffstat (limited to 'infra/minimal-distribution/src/main/java/io')
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/Main.java62
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/cfgattrs/HoneycombConfiguration.groovy59
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/HoneycombNotification2NetconfProvider.groovy4
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfSshServerProvider.groovy8
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NettyThreadGroupProvider.groovy9
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/restconf/HttpConnectorProvider.groovy24
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/restconf/HttpsConnectorProvider.groovy58
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/restconf/JettyServerProvider.groovy81
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/restconf/RestconfModule.groovy6
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/restconf/RestconfProvider.groovy97
10 files changed, 275 insertions, 133 deletions
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/Main.java b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/Main.java
index 6c63c213d..278f0b104 100644
--- a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/Main.java
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/Main.java
@@ -16,6 +16,7 @@
package io.fd.honeycomb.infra.distro;
+import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.inject.ConfigurationException;
import com.google.inject.CreationException;
@@ -42,6 +43,8 @@ import io.fd.honeycomb.infra.distro.restconf.RestconfModule;
import io.fd.honeycomb.infra.distro.schema.SchemaModule;
import io.fd.honeycomb.infra.distro.schema.YangBindingProviderModule;
import java.util.List;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.ServerConnector;
import org.opendaylight.netconf.mapping.api.NetconfOperationServiceFactory;
import org.opendaylight.netconf.sal.rest.api.RestConnector;
import org.slf4j.Logger;
@@ -70,6 +73,9 @@ public final class Main {
init(BASE_MODULES);
}
+ /**
+ * Initialize the Honeycomb infrastructure + all wired plugins.
+ */
public static Injector init(final List<? extends Module> modules) {
try {
LOG.info("Starting honeycomb");
@@ -82,26 +88,50 @@ public final class Main {
.forEach(e -> LOG.trace("Component available under: {} is {}", e.getKey(), e.getValue()));
final HoneycombConfiguration cfgAttributes = injector.getInstance(HoneycombConfiguration.class);
-
+ Preconditions.checkArgument(cfgAttributes.isRestconfEnabled() || cfgAttributes.isNetconfEnabled(),
+ "At least one interface(Restconf|Netconf) has to be enabled for Honeycomb");
// Now get instances for all dependency roots
- LOG.info("Starting RESTCONF");
- injector.getInstance(RestConnector.class);
-
- LOG.info("Starting NETCONF");
- injector.getInstance(
- Key.get(NetconfOperationServiceFactory.class, Names.named("netconf-mapper-honeycomb")));
- injector.getInstance(
- Key.get(NetconfOperationServiceFactory.class, Names.named("netconf-mapper-notification")));
- injector.getInstance(
- Key.get(NetconfOperationServiceFactory.class, Names.named("netconf-mapper-monitoring")));
-
- if (cfgAttributes.isNetconfTcpServerEnabled()) {
- injector.getInstance(NetconfTcpServerProvider.NetconfTcpServer.class);
+ if (cfgAttributes.isRestconfEnabled()) {
+ LOG.info("Starting RESTCONF");
+ final Server server = injector.getInstance(Server.class);
+ final RestConnector instance = injector.getInstance(RestConnector.class);
+
+ if (cfgAttributes.isRestconfHttpEnabled()) {
+ injector.getInstance(Key.get(ServerConnector.class, Names.named("restconf-http")));
+ }
+ if (cfgAttributes.isRestconfHttpsEnabled()) {
+ injector.getInstance(Key.get(ServerConnector.class, Names.named("restconf-https")));
+ }
+
+ try {
+ server.start();
+ } catch (Exception e) {
+ LOG.error("Unable to start Restconf", e);
+ throw new RuntimeException("Unable to start Restconf", e);
+ }
}
- injector.getInstance(NetconfSshServerProvider.NetconfSshServer.class);
- injector.getInstance(HoneycombNotification2NetconfProvider.HoneycombNotification2Netconf.class);
+ if (cfgAttributes.isNetconfEnabled()) {
+ LOG.info("Starting NETCONF");
+ injector.getInstance(
+ Key.get(NetconfOperationServiceFactory.class, Names.named("netconf-mapper-honeycomb")));
+ injector.getInstance(
+ Key.get(NetconfOperationServiceFactory.class, Names.named("netconf-mapper-notification")));
+ injector.getInstance(
+ Key.get(NetconfOperationServiceFactory.class, Names.named("netconf-mapper-monitoring")));
+
+ if (cfgAttributes.isNetconfTcpEnabled()) {
+ LOG.info("Starting NETCONF TCP");
+ injector.getInstance(NetconfTcpServerProvider.NetconfTcpServer.class);
+ }
+
+ if (cfgAttributes.isNetconfSshEnabled()) {
+ LOG.info("Starting NETCONF SSH");
+ injector.getInstance(NetconfSshServerProvider.NetconfSshServer.class);
+ }
+ injector.getInstance(HoneycombNotification2NetconfProvider.HoneycombNotification2Netconf.class);
+ }
LOG.info("Honeycomb started successfully!");
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/cfgattrs/HoneycombConfiguration.groovy b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/cfgattrs/HoneycombConfiguration.groovy
index 422c84435..85708f11e 100644
--- a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/cfgattrs/HoneycombConfiguration.groovy
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/cfgattrs/HoneycombConfiguration.groovy
@@ -41,37 +41,72 @@ class HoneycombConfiguration {
int notificationServiceQueueDepth
// RESTCONF
+ // HTTP
+ @InjectConfig("restconf-http-enabled")
+ String restconfHttp
+
@InjectConfig("restconf-binding-address")
- String restconfBindingAddress
+ Optional<String> restconfBindingAddress
@InjectConfig("restconf-port")
- int restconfPort
+ Optional<Integer> restconfPort
+ // HTTPS
+ @InjectConfig("restconf-https-enabled")
+ String restconfHttps
@InjectConfig("restconf-https-binding-address")
- String restconfHttpsBindingAddress
+ Optional<String> restconfHttpsBindingAddress
@InjectConfig("restconf-https-port")
- int restconfHttpsPort
+ Optional<Integer> restconfHttpsPort
+
@InjectConfig("restconf-websocket-port")
- int restconfWebsocketPort
+ Optional<Integer> restconfWebsocketPort = Optional.of(7779)
+
@InjectConfig("restconf-root-path")
- String restconfRootPath
+ Optional<String> restconfRootPath = Optional.of("/restconf")
+ @InjectConfig("restconf-pool-max-size")
+ Optional<Integer> restPoolMaxSize = Optional.of(10)
+ @InjectConfig("restconf-pool-min-size")
+ Optional<Integer> restPoolMinSize = Optional.of(1)
+
+ @InjectConfig("restconf-acceptors-size")
+ Optional<Integer> acceptorsSize = Optional.of(1)
+ @InjectConfig("restconf-selectors-size")
+ Optional<Integer> selectorsSize = Optional.of(1)
+ @InjectConfig("restconf-https-acceptors-size")
+ Optional<Integer> httpsAcceptorsSize = Optional.of(1)
+ @InjectConfig("restconf-https-selectors-size")
+ Optional<Integer> httpsSelectorsSize = Optional.of(1)
+
+ // Booleans not supported
+ boolean isRestconfHttpEnabled() { Boolean.valueOf(restconfHttp) }
+ boolean isRestconfHttpsEnabled() { Boolean.valueOf(restconfHttps) }
+ boolean isRestconfEnabled() { isRestconfHttpEnabled() || isRestconfHttpsEnabled() }
// NETCONF
@InjectConfig("netconf-netty-threads")
- Optional<Integer> netconfNettyThreads
- // NETCONF TCP optional
+ Integer netconfNettyThreads
+
+ // NETCONF TCP
+ @InjectConfig("netconf-tcp-enabled")
+ String netconfTcp
@InjectConfig("netconf-tcp-binding-address")
Optional<String> netconfTcpBindingAddress
@InjectConfig("netconf-tcp-binding-port")
Optional<Integer> netconfTcpBindingPort
+
// NETCONF SSH
+ @InjectConfig("netconf-ssh-enabled")
+ String netconfSsh
@InjectConfig("netconf-ssh-binding-address")
- String netconfSshBindingAddress
+ Optional<String> netconfSshBindingAddress
@InjectConfig("netconf-ssh-binding-port")
- Integer netconfSshBindingPort
+ Optional<Integer> netconfSshBindingPort
@InjectConfig("netconf-notification-stream-name")
- String netconfNotificationStreamName
+ Optional<String> netconfNotificationStreamName = Optional.of("honeycomb")
- boolean isNetconfTcpServerEnabled() { netconfTcpBindingAddress.isPresent() && netconfTcpBindingPort.isPresent() }
+ boolean isNetconfTcpEnabled() { Boolean.valueOf(netconfTcp) }
+ boolean isNetconfSshEnabled() { Boolean.valueOf(netconfSsh) }
+ boolean isNetconfEnabled() { isNetconfTcpEnabled() || isNetconfSshEnabled() }
@InjectConfig("username")
String username
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/HoneycombNotification2NetconfProvider.groovy b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/HoneycombNotification2NetconfProvider.groovy
index 7e4453ef1..f8c9aaae3 100644
--- a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/HoneycombNotification2NetconfProvider.groovy
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/HoneycombNotification2NetconfProvider.groovy
@@ -52,13 +52,13 @@ class HoneycombNotification2NetconfProvider extends ProviderTrait<HoneycombNotif
@Override
def create() {
- def streamType = new StreamNameType(cfgAttributes.netconfNotificationStreamName);
+ def streamType = new StreamNameType(cfgAttributes.netconfNotificationStreamName.get());
// Register as NETCONF notification publisher under configured name
def netconfNotifReg = netconfNotificationCollector.registerNotificationPublisher(new StreamBuilder()
.setName(streamType)
.setReplaySupport(false)
- .setDescription(cfgAttributes.netconfNotificationStreamName).build());
+ .setDescription(cfgAttributes.netconfNotificationStreamName.get()).build());
// Notification Translator, get notification from HC producers and put into NETCONF notification collector
def domNotificationListener = { notif ->
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfSshServerProvider.groovy b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfSshServerProvider.groovy
index bce4f261a..8b1b5bec2 100644
--- a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfSshServerProvider.groovy
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NetconfSshServerProvider.groovy
@@ -16,6 +16,7 @@
package io.fd.honeycomb.infra.distro.netconf
+import com.google.common.util.concurrent.ThreadFactoryBuilder
import com.google.inject.Inject
import groovy.transform.ToString
import groovy.util.logging.Slf4j
@@ -48,12 +49,13 @@ class NetconfSshServerProvider extends ProviderTrait<NetconfSshServer> {
NioEventLoopGroup nettyThreadgroup
// TODO merge with other executors .. one of the brokers creates also 2 internal executors
- private ScheduledExecutorService pool = Executors.newScheduledThreadPool(1)
+ private ScheduledExecutorService pool =
+ Executors.newScheduledThreadPool(1, new ThreadFactoryBuilder().setNameFormat("netconf-ssh-%d").build())
@Override
def create() {
- def name = InetAddress.getByName(cfgAttributes.netconfSshBindingAddress)
- def bindingAddress = new InetSocketAddress(name, cfgAttributes.netconfSshBindingPort)
+ def name = InetAddress.getByName(cfgAttributes.netconfSshBindingAddress.get())
+ def bindingAddress = new InetSocketAddress(name, cfgAttributes.netconfSshBindingPort.get())
def localAddress = new LocalAddress(cfgAttributes.netconfSshBindingPort.toString())
def localServer = dispatcher.createLocalServer(localAddress)
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NettyThreadGroupProvider.groovy b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NettyThreadGroupProvider.groovy
index da5f3d5b2..bff8e3d8e 100644
--- a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NettyThreadGroupProvider.groovy
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/netconf/NettyThreadGroupProvider.groovy
@@ -16,13 +16,13 @@
package io.fd.honeycomb.infra.distro.netconf
+import com.google.common.util.concurrent.ThreadFactoryBuilder
import com.google.inject.Inject
import groovy.transform.ToString
import groovy.util.logging.Slf4j
-import io.fd.honeycomb.infra.distro.cfgattrs.HoneycombConfiguration
import io.fd.honeycomb.infra.distro.ProviderTrait
+import io.fd.honeycomb.infra.distro.cfgattrs.HoneycombConfiguration
import io.netty.channel.nio.NioEventLoopGroup
-
/**
* Mirror of org.opendaylight.controller.config.yang.netty.threadgroup.NettyThreadgroupModule
*/
@@ -35,8 +35,7 @@ class NettyThreadGroupProvider extends ProviderTrait<NioEventLoopGroup> {
@Override
def create() {
- cfgAttributes.netconfNettyThreads.isPresent() ?
- new NioEventLoopGroup(cfgAttributes.netconfNettyThreads.get()) :
- new NioEventLoopGroup()
+ new NioEventLoopGroup(cfgAttributes.netconfNettyThreads,
+ new ThreadFactoryBuilder().setNameFormat("netconf-netty-%d").build())
}
}
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/restconf/HttpConnectorProvider.groovy b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/restconf/HttpConnectorProvider.groovy
new file mode 100644
index 000000000..0be4a3264
--- /dev/null
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/restconf/HttpConnectorProvider.groovy
@@ -0,0 +1,24 @@
+package io.fd.honeycomb.infra.distro.restconf
+
+import com.google.inject.Inject
+import io.fd.honeycomb.infra.distro.ProviderTrait
+import io.fd.honeycomb.infra.distro.cfgattrs.HoneycombConfiguration
+import org.eclipse.jetty.server.Server
+import org.eclipse.jetty.server.ServerConnector
+
+class HttpConnectorProvider extends ProviderTrait<ServerConnector> {
+
+ @Inject
+ HoneycombConfiguration cfg
+ @Inject
+ Server server
+
+ @Override
+ def create() {
+ def httpConnector = new ServerConnector(server, cfg.acceptorsSize.get(), cfg.selectorsSize.get())
+ httpConnector.setHost(cfg.restconfBindingAddress.get())
+ httpConnector.setPort(cfg.restconfPort.get())
+ server.addConnector(httpConnector)
+ httpConnector
+ }
+}
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/restconf/HttpsConnectorProvider.groovy b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/restconf/HttpsConnectorProvider.groovy
new file mode 100644
index 000000000..6ce5a1555
--- /dev/null
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/restconf/HttpsConnectorProvider.groovy
@@ -0,0 +1,58 @@
+package io.fd.honeycomb.infra.distro.restconf
+
+import com.google.inject.Inject
+import io.fd.honeycomb.infra.distro.ProviderTrait
+import io.fd.honeycomb.infra.distro.cfgattrs.HoneycombConfiguration
+import org.eclipse.jetty.http.HttpVersion
+import org.eclipse.jetty.server.Server
+import org.eclipse.jetty.server.ServerConnector
+import org.eclipse.jetty.server.SslConnectionFactory
+import org.eclipse.jetty.util.ssl.SslContextFactory
+
+class HttpsConnectorProvider extends ProviderTrait<ServerConnector> {
+
+ public static final String KEYSTORE_PASSWORD = "OBF:1v9s1unr1unn1vv51zlk1t331vg91x1b1vgl1t331zly1vu51uob1uo71v8u"
+ public static final String KEYSTORE_NAME = "/honeycomb-keystore"
+
+ @Inject
+ HoneycombConfiguration cfg
+ @Inject
+ Server server
+
+ @Override
+ def create() {
+
+ // SSL Context Factory
+ // Based on:
+ // https://github.com/eclipse/jetty.project/blob/jetty-9.3.x/examples/embedded/src/main/java/org/eclipse/jetty/embedded/LikeJettyXml.java
+ // https://wiki.eclipse.org/Jetty/Howto/Configure_SSL#Loading_Keys_and_Certificates_via_PKCS12
+ // Keystore created with:
+ // openssl genrsa -des3 -out honeycomb.key
+ // openssl req -new -x509 -key honeycomb.key -out honeycomb.crt
+ // openssl pkcs12 -inkey honeycomb.key -in honeycomb.crt -export -out honeycomb.pkcs12
+ // keytool -importkeystore -srckeystore honeycomb.pkcs12 -srcstoretype PKCS12 -destkeystore honeycomb-keystore
+ def sslContextFactory = new SslContextFactory()
+ def keystoreURL = getClass().getResource(KEYSTORE_NAME)
+ sslContextFactory.setKeyStorePath(keystoreURL.path)
+ sslContextFactory.setKeyStorePassword(KEYSTORE_PASSWORD)
+ sslContextFactory.setKeyManagerPassword(KEYSTORE_PASSWORD)
+ sslContextFactory.setTrustStorePath(keystoreURL.path)
+ sslContextFactory.setTrustStorePassword(KEYSTORE_PASSWORD)
+ sslContextFactory.setExcludeCipherSuites(
+ "SSL_RSA_WITH_DES_CBC_SHA",
+ "SSL_DHE_RSA_WITH_DES_CBC_SHA",
+ "SSL_DHE_DSS_WITH_DES_CBC_SHA",
+ "SSL_RSA_EXPORT_WITH_RC4_40_MD5",
+ "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",
+ "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
+ "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA")
+
+ // SSL Connector
+ def sslConnector = new ServerConnector(server, cfg.httpsAcceptorsSize.get(), cfg.httpsSelectorsSize.get(),
+ new SslConnectionFactory(sslContextFactory, HttpVersion.HTTP_1_1.asString()))
+ sslConnector.setHost(cfg.restconfHttpsBindingAddress.get())
+ sslConnector.setPort(cfg.restconfHttpsPort.get())
+ server.addConnector(sslConnector)
+ return sslConnector
+ }
+}
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/restconf/JettyServerProvider.groovy b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/restconf/JettyServerProvider.groovy
new file mode 100644
index 000000000..ff6c300ea
--- /dev/null
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/restconf/JettyServerProvider.groovy
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License")
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.infra.distro.restconf
+
+import com.google.inject.Inject
+import groovy.transform.ToString
+import groovy.util.logging.Slf4j
+import io.fd.honeycomb.infra.distro.ProviderTrait
+import io.fd.honeycomb.infra.distro.cfgattrs.HoneycombConfiguration
+import org.eclipse.jetty.security.ConstraintMapping
+import org.eclipse.jetty.security.ConstraintSecurityHandler
+import org.eclipse.jetty.security.HashLoginService
+import org.eclipse.jetty.security.authentication.BasicAuthenticator
+import org.eclipse.jetty.server.Server
+import org.eclipse.jetty.util.security.Constraint
+import org.eclipse.jetty.util.security.Password
+import org.eclipse.jetty.util.thread.QueuedThreadPool
+import org.eclipse.jetty.webapp.WebAppContext
+
+@Slf4j
+@ToString
+class JettyServerProvider extends ProviderTrait<Server> {
+
+ public static final String REALM = "HCRealm"
+
+ @Inject
+ HoneycombConfiguration cfg
+
+ def create() {
+ def server = new Server(new QueuedThreadPool(cfg.restPoolMaxSize.get(), cfg.restPoolMinSize.get()))
+
+ // Load Realm for basic auth
+ def service = new HashLoginService(REALM)
+ // Reusing the name as role
+ // TODO make this more configurable
+ service.putUser(cfg.username, new Password(cfg.password), cfg.username)
+ server.addBean(service)
+
+ final URL resource = getClass().getResource("/")
+ WebAppContext webapp = new WebAppContext(resource.getPath(), cfg.restconfRootPath.get())
+
+ ConstraintSecurityHandler security = getBaseAuth(service, webapp)
+ server.setHandler(security)
+
+ return server
+ }
+
+ private ConstraintSecurityHandler getBaseAuth(HashLoginService service, WebAppContext webapp) {
+ ConstraintSecurityHandler security = new ConstraintSecurityHandler()
+
+ Constraint constraint = new Constraint()
+ constraint.setName("auth")
+ constraint.setAuthenticate(true)
+ constraint.setRoles(cfg.username)
+
+ ConstraintMapping mapping = new ConstraintMapping()
+ mapping.setPathSpec("/*")
+ mapping.setConstraint(constraint)
+
+ security.setConstraintMappings(Collections.singletonList(mapping))
+ security.setAuthenticator(new BasicAuthenticator())
+ security.setLoginService(service)
+
+ security.setHandler(webapp)
+ security
+ }
+}
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/restconf/RestconfModule.groovy b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/restconf/RestconfModule.groovy
index 1aa4efa9f..4a66a1c3c 100644
--- a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/restconf/RestconfModule.groovy
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/restconf/RestconfModule.groovy
@@ -18,13 +18,19 @@ package io.fd.honeycomb.infra.distro.restconf
import com.google.inject.AbstractModule
import com.google.inject.Singleton
+import com.google.inject.name.Names
import groovy.util.logging.Slf4j
+import org.eclipse.jetty.server.Server
+import org.eclipse.jetty.server.ServerConnector
import org.opendaylight.netconf.sal.rest.api.RestConnector
@Slf4j
class RestconfModule extends AbstractModule {
protected void configure() {
+ bind(Server).toProvider(JettyServerProvider).in(Singleton)
+ bind(ServerConnector).annotatedWith(Names.named("restconf-http")).toProvider(HttpConnectorProvider).in(Singleton)
+ bind(ServerConnector).annotatedWith(Names.named("restconf-https")).toProvider(HttpsConnectorProvider).in(Singleton)
bind(RestConnector).toProvider(RestconfProvider).in(Singleton)
}
}
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/restconf/RestconfProvider.groovy b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/restconf/RestconfProvider.groovy
index bffe1da1a..657e16986 100644
--- a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/restconf/RestconfProvider.groovy
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/restconf/RestconfProvider.groovy
@@ -21,19 +21,6 @@ import groovy.transform.ToString
import groovy.util.logging.Slf4j
import io.fd.honeycomb.infra.distro.ProviderTrait
import io.fd.honeycomb.infra.distro.cfgattrs.HoneycombConfiguration
-import org.eclipse.jetty.http.HttpVersion
-import org.eclipse.jetty.security.ConstraintMapping
-import org.eclipse.jetty.security.ConstraintSecurityHandler
-import org.eclipse.jetty.security.HashLoginService
-import org.eclipse.jetty.security.authentication.BasicAuthenticator
-import org.eclipse.jetty.server.HttpConnectionFactory
-import org.eclipse.jetty.server.Server
-import org.eclipse.jetty.server.ServerConnector
-import org.eclipse.jetty.server.SslConnectionFactory
-import org.eclipse.jetty.util.security.Constraint
-import org.eclipse.jetty.util.security.Password
-import org.eclipse.jetty.util.ssl.SslContextFactory
-import org.eclipse.jetty.webapp.WebAppContext
import org.opendaylight.controller.sal.core.api.Broker
import org.opendaylight.netconf.sal.rest.api.RestConnector
import org.opendaylight.netconf.sal.restconf.impl.RestconfProviderImpl
@@ -43,10 +30,6 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.
@ToString
class RestconfProvider extends ProviderTrait<RestConnector> {
- public static final String KEYSTORE_PASSWORD = "OBF:1v9s1unr1unn1vv51zlk1t331vg91x1b1vgl1t331zly1vu51uob1uo71v8u"
- public static final String KEYSTORE_NAME = "/honeycomb-keystore"
- public static final String REALM = "HCRealm"
-
@Inject
HoneycombConfiguration cfg
@@ -55,84 +38,8 @@ class RestconfProvider extends ProviderTrait<RestConnector> {
def create() {
def instance = new RestconfProviderImpl()
- instance.setWebsocketPort(new PortNumber(cfg.restconfWebsocketPort))
+ instance.setWebsocketPort(new PortNumber(cfg.restconfWebsocketPort.get()))
domBroker.registerProvider(instance)
-
- def server = new Server(InetSocketAddress.createUnresolved(cfg.restconfBindingAddress, cfg.restconfPort))
-
- // Load Realm for basic auth
- def service = new HashLoginService(REALM)
- // Reusing the name as role
- // TODO make this more configurable
- service.putUser(cfg.username, new Password(cfg.password), cfg.username)
- server.addBean(service)
-
- final URL resource = getClass().getResource("/")
- WebAppContext webapp = new WebAppContext(resource.getPath(), cfg.restconfRootPath)
-
- ConstraintSecurityHandler security = getBaseAuth(service, webapp)
- server.setHandler(security)
-
- // SSL Context Factory
- // Based on:
- // https://github.com/eclipse/jetty.project/blob/jetty-9.3.x/examples/embedded/src/main/java/org/eclipse/jetty/embedded/LikeJettyXml.java
- // https://wiki.eclipse.org/Jetty/Howto/Configure_SSL#Loading_Keys_and_Certificates_via_PKCS12
- // Keystore created with:
- // openssl genrsa -des3 -out honeycomb.key
- // openssl req -new -x509 -key honeycomb.key -out honeycomb.crt
- // openssl pkcs12 -inkey honeycomb.key -in honeycomb.crt -export -out honeycomb.pkcs12
- // keytool -importkeystore -srckeystore honeycomb.pkcs12 -srcstoretype PKCS12 -destkeystore honeycomb-keystore
- def sslContextFactory = new SslContextFactory()
- def keystoreURL = getClass().getResource(KEYSTORE_NAME)
- sslContextFactory.setKeyStorePath(keystoreURL.path)
- sslContextFactory.setKeyStorePassword(KEYSTORE_PASSWORD)
- sslContextFactory.setKeyManagerPassword(KEYSTORE_PASSWORD)
- sslContextFactory.setTrustStorePath(keystoreURL.path)
- sslContextFactory.setTrustStorePassword(KEYSTORE_PASSWORD)
- sslContextFactory.setExcludeCipherSuites(
- "SSL_RSA_WITH_DES_CBC_SHA",
- "SSL_DHE_RSA_WITH_DES_CBC_SHA",
- "SSL_DHE_DSS_WITH_DES_CBC_SHA",
- "SSL_RSA_EXPORT_WITH_RC4_40_MD5",
- "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",
- "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
- "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA")
-
- // SSL Connector
- def sslConnector = new ServerConnector(server,
- new SslConnectionFactory(sslContextFactory, HttpVersion.HTTP_1_1.asString()),
- new HttpConnectionFactory())
- sslConnector.setHost(cfg.restconfHttpsBindingAddress)
- sslConnector.setPort(cfg.restconfHttpsPort)
- server.addConnector(sslConnector)
-
- try {
- server.start()
- } catch (Exception e) {
- log.error "Unable to start Restconf", e
- throw new RuntimeException("Unable to start Restconf", e)
- }
-
- return instance
- }
-
- private ConstraintSecurityHandler getBaseAuth(HashLoginService service, WebAppContext webapp) {
- ConstraintSecurityHandler security = new ConstraintSecurityHandler()
-
- Constraint constraint = new Constraint()
- constraint.setName("auth")
- constraint.setAuthenticate(true)
- constraint.setRoles(cfg.username)
-
- ConstraintMapping mapping = new ConstraintMapping()
- mapping.setPathSpec("/*")
- mapping.setConstraint(constraint)
-
- security.setConstraintMappings(Collections.singletonList(mapping))
- security.setAuthenticator(new BasicAuthenticator())
- security.setLoginService(service)
-
- security.setHandler(webapp)
- security
+ instance
}
}