diff options
Diffstat (limited to 'infra/northbound')
12 files changed, 685 insertions, 0 deletions
diff --git a/infra/northbound/pom.xml b/infra/northbound/pom.xml index 68554ea7f..e234d4c28 100644 --- a/infra/northbound/pom.xml +++ b/infra/northbound/pom.xml @@ -33,6 +33,7 @@ <modules> <module>common</module> <module>bgp</module> + <module>restconf</module> </modules> </project>
\ No newline at end of file diff --git a/infra/northbound/restconf/asciidoc/Readme.adoc b/infra/northbound/restconf/asciidoc/Readme.adoc new file mode 100644 index 000000000..957949ab3 --- /dev/null +++ b/infra/northbound/restconf/asciidoc/Readme.adoc @@ -0,0 +1,14 @@ += restconf + +Provides modules and configuration for RESTCONF northbound interface. + +* To start RESTCONF HTTP use + ** "restconf-http-enabled": "true" +* To start RESTCONF HTTPS use + ** "restconf-https-enabled": "true" +* To disable RESTCONF start use + ** "restconf-http-enabled": "false" + ** "restconf-https-enabled": "false" +* To disable RESTCONF fully + ** comment/remove io.fd.honeycomb.northbound.restconf.RestconfModule +from distribution module configuration
\ No newline at end of file diff --git a/infra/northbound/restconf/pom.xml b/infra/northbound/restconf/pom.xml new file mode 100644 index 000000000..3f7427208 --- /dev/null +++ b/infra/northbound/restconf/pom.xml @@ -0,0 +1,105 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (c) 2017 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. + --> + +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <parent> + <artifactId>impl-parent</artifactId> + <groupId>io.fd.honeycomb.common</groupId> + <version>1.17.10-SNAPSHOT</version> + <relativePath>../../../common/impl-parent</relativePath> + </parent> + <modelVersion>4.0.0</modelVersion> + + <groupId>io.fd.honeycomb.northbound</groupId> + <artifactId>restconf</artifactId> + <version>1.17.10-SNAPSHOT</version> + + <properties> + <jersey.version>1.19.1</jersey.version> + <servlet.version>3.1.0</servlet.version> + <jetty.version>9.3.11.v20160721</jetty.version> + </properties> + + <dependencies> + <!-- DI--> + <dependency> + <groupId>com.google.inject</groupId> + <artifactId>guice</artifactId> + </dependency> + <dependency> + <groupId>net.jmob</groupId> + <artifactId>guice.conf</artifactId> + </dependency> + <dependency> + <groupId>io.fd.honeycomb</groupId> + <artifactId>binding-init</artifactId> + <version>${project.version}</version> + </dependency> + + <!-- Northbound common --> + <dependency> + <groupId>io.fd.honeycomb.northbound</groupId> + <artifactId>common</artifactId> + <version>${project.version}</version> + </dependency> + + <!-- ODL-Restconf --> + <dependency> + <groupId>org.opendaylight.netconf</groupId> + <artifactId>sal-rest-connector</artifactId> + </dependency> + + <!-- Jersey + Jetty for RESTCONF --> + <dependency> + <groupId>org.eclipse.jetty</groupId> + <artifactId>jetty-server</artifactId> + <version>${jetty.version}</version> + </dependency> + <dependency> + <groupId>javax.servlet</groupId> + <artifactId>javax.servlet-api</artifactId> + <version>${servlet.version}</version> + </dependency> + <dependency> + <groupId>org.eclipse.jetty</groupId> + <artifactId>jetty-webapp</artifactId> + <version>${jetty.version}</version> + </dependency> + <dependency> + <groupId>org.eclipse.jetty</groupId> + <artifactId>jetty-servlets</artifactId> + <version>${jetty.version}</version> + </dependency> + <dependency> + <groupId>com.sun.jersey</groupId> + <artifactId>jersey-server</artifactId> + <version>${jersey.version}</version> + </dependency> + <dependency> + <groupId>com.sun.jersey</groupId> + <artifactId>jersey-core</artifactId> + <version>${jersey.version}</version> + </dependency> + <dependency> + <groupId>com.sun.jersey</groupId> + <artifactId>jersey-servlet</artifactId> + <version>${jersey.version}</version> + </dependency> + </dependencies> +</project>
\ No newline at end of file diff --git a/infra/northbound/restconf/src/main/java/io/fd/honeycomb/northbound/restconf/HttpConnectorProvider.java b/infra/northbound/restconf/src/main/java/io/fd/honeycomb/northbound/restconf/HttpConnectorProvider.java new file mode 100644 index 000000000..04a767c32 --- /dev/null +++ b/infra/northbound/restconf/src/main/java/io/fd/honeycomb/northbound/restconf/HttpConnectorProvider.java @@ -0,0 +1,49 @@ +/* + * 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.northbound.restconf; + +import com.google.inject.Inject; +import io.fd.honeycomb.binding.init.ProviderTrait; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.ServerConnector; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +final class HttpConnectorProvider extends ProviderTrait<ServerConnector> { + + private static final Logger LOG = LoggerFactory.getLogger(HttpConnectorProvider.class); + + @Inject + private RestconfConfiguration cfg; + @Inject + private Server server; + + @Override + protected ServerConnector create() { + if (!cfg.isRestconfHttpEnabled()) { + LOG.debug("RESTCONF HTTP disabled, skipping initialization"); + return null; + } + + LOG.info("Starting RESTCONF HTTP"); + ServerConnector httpConnector = new ServerConnector(server, cfg.acceptorsSize.get(), cfg.selectorsSize.get()); + httpConnector.setHost(cfg.restconfBindingAddress.get()); + httpConnector.setPort(cfg.restconfPort.get()); + server.addConnector(httpConnector); + return httpConnector; + } +} diff --git a/infra/northbound/restconf/src/main/java/io/fd/honeycomb/northbound/restconf/HttpsConnectorProvider.java b/infra/northbound/restconf/src/main/java/io/fd/honeycomb/northbound/restconf/HttpsConnectorProvider.java new file mode 100644 index 000000000..5a27bcb8e --- /dev/null +++ b/infra/northbound/restconf/src/main/java/io/fd/honeycomb/northbound/restconf/HttpsConnectorProvider.java @@ -0,0 +1,86 @@ +/* + * 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.northbound.restconf; + +import com.google.inject.Inject; +import io.fd.honeycomb.binding.init.ProviderTrait; + +import java.net.URL; + +import org.eclipse.jetty.http.HttpVersion; +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.ssl.SslContextFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +final class HttpsConnectorProvider extends ProviderTrait<ServerConnector> { + + private static final Logger LOG = LoggerFactory.getLogger(HttpsConnectorProvider.class); + + @Inject + private RestconfConfiguration cfg; + @Inject + private Server server; + + @Override + protected ServerConnector create() { + if (!cfg.isRestconfHttpsEnabled()) { + LOG.debug("RESTCONF HTTPS disabled, skipping initialization"); + return null; + } + LOG.info("Starting RESTCONF HTTPS"); + // 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 + SslContextFactory sslContextFactory = new SslContextFactory(); + URL keystoreURL = getClass().getResource(cfg.restconfKeystore.get()); + sslContextFactory.setKeyStorePath(keystoreURL.getPath()); + sslContextFactory.setKeyStorePassword(cfg.keystorePassword.get()); + sslContextFactory.setKeyManagerPassword((cfg.keystoreManagerPassword.get())); + URL truststoreURL = getClass().getResource(cfg.restconfTruststore.get()); + sslContextFactory.setTrustStorePath(truststoreURL.getPath()); + sslContextFactory.setTrustStorePassword((cfg.truststorePassword.get())); + // TODO HONEYCOMB-167 make this more configurable + 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 + ServerConnector sslConnector = + new ServerConnector(server, cfg.httpsAcceptorsSize.get(), cfg.httpsSelectorsSize.get(), + // The ssl connection factory delegates the real processing to http connection factory + new SslConnectionFactory(sslContextFactory, HttpVersion.HTTP_1_1.asString()), + // That's why http connection factory is also required here + // Order is IMPORTANT here + new HttpConnectionFactory() + ); + sslConnector.setHost(cfg.restconfHttpsBindingAddress.get()); + sslConnector.setPort(cfg.restconfHttpsPort.get()); + server.addConnector(sslConnector); + return sslConnector; + } +} diff --git a/infra/northbound/restconf/src/main/java/io/fd/honeycomb/northbound/restconf/JettyServerProvider.java b/infra/northbound/restconf/src/main/java/io/fd/honeycomb/northbound/restconf/JettyServerProvider.java new file mode 100644 index 000000000..a87459560 --- /dev/null +++ b/infra/northbound/restconf/src/main/java/io/fd/honeycomb/northbound/restconf/JettyServerProvider.java @@ -0,0 +1,94 @@ +/* + * 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.northbound.restconf; + +import com.google.inject.Inject; +import io.fd.honeycomb.binding.init.ProviderTrait; +import io.fd.honeycomb.northbound.CredentialsConfiguration; +import java.net.URL; +import java.util.Collections; +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.server.handler.gzip.GzipHandler; +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; + +final class JettyServerProvider extends ProviderTrait<Server> { + + private static final String REALM = "HCRealm"; + // Mime types to be compressed when requested + private static final String[] GZIP_MIME_TYPES = {"application/xml", + "xml", + "application/yang.data+xml", + "application/json", + "application/yang.data+json"}; + + @Inject + private RestconfConfiguration cfg; + + @Inject + private CredentialsConfiguration credentialsCfg; + + @Override + protected Server create() { + Server server = new Server(new QueuedThreadPool(cfg.restPoolMaxSize.get(), cfg.restPoolMinSize.get())); + + // Load Realm for basic auth + HashLoginService service = new HashLoginService(REALM); + // Reusing the name as role + service.putUser(credentialsCfg.username, new Password(credentialsCfg.password), + new String[]{credentialsCfg.username}); + server.addBean(service); + + final URL resource = getClass().getResource("/"); + WebAppContext webapp = new WebAppContext(resource.getPath(), cfg.restconfRootPath.get()); + + server.setHandler(getGzip(service, webapp)); + return server; + } + + private GzipHandler getGzip(final HashLoginService service, final WebAppContext webapp) { + final GzipHandler gzipHandler = new GzipHandler(); + gzipHandler.setIncludedMimeTypes(GZIP_MIME_TYPES); + gzipHandler.setHandler(getBaseAuth(service, webapp)); + return gzipHandler; + } + + private ConstraintSecurityHandler getBaseAuth(HashLoginService service, WebAppContext webapp) { + Constraint constraint = new Constraint(); + constraint.setName("auth"); + constraint.setAuthenticate(true); + constraint.setRoles(new String[]{credentialsCfg.username}); + + ConstraintMapping mapping = new ConstraintMapping(); + mapping.setPathSpec("/*"); + mapping.setConstraint(constraint); + + ConstraintSecurityHandler security = new ConstraintSecurityHandler(); + security.setConstraintMappings(Collections.singletonList(mapping)); + security.setAuthenticator(new BasicAuthenticator()); + security.setLoginService(service); + + security.setHandler(webapp); + return security; + } +} diff --git a/infra/northbound/restconf/src/main/java/io/fd/honeycomb/northbound/restconf/JettyServerStarter.java b/infra/northbound/restconf/src/main/java/io/fd/honeycomb/northbound/restconf/JettyServerStarter.java new file mode 100644 index 000000000..1bd50bb22 --- /dev/null +++ b/infra/northbound/restconf/src/main/java/io/fd/honeycomb/northbound/restconf/JettyServerStarter.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2017 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.northbound.restconf; + +import static io.fd.honeycomb.northbound.restconf.RestconfModule.RESTCONF_HTTP; +import static io.fd.honeycomb.northbound.restconf.RestconfModule.RESTCONF_HTTPS; + +import com.google.inject.Inject; +import com.google.inject.name.Named; +import io.fd.honeycomb.binding.init.ProviderTrait; + +import javax.annotation.Nullable; + +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.ServerConnector; +import org.opendaylight.netconf.sal.rest.api.RestConnector; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +class JettyServerStarter extends ProviderTrait<JettyServerStarter.ServerInit> { + + private static final Logger LOG = LoggerFactory.getLogger(JettyServerStarter.class); + + @Inject + private Server server; + + // injecting all connectors to make sure that server is started after they are added + @Inject + private RestConnector connector; + + // if HTTP is disabled, null will be injected + @Nullable + @Inject(optional = true) + @Named(RESTCONF_HTTP) + private ServerConnector httpConnectorInit; + + // if HTTPS is disabled, null will be injected + @Nullable + @Inject(optional = true) + @Named(RESTCONF_HTTPS) + private ServerConnector httpsConnectorInit; + + @Override + protected ServerInit create() { + try { + LOG.info("Starting RESTCONF Jetty server"); + server.start(); + LOG.info("RESTCONF Jetty server successfully started"); + } catch (Exception e) { + LOG.error("Unable to start RESTCONF Jetty server", e); + throw new IllegalStateException("Unable to start RESTCONF Jetty server", e); + } + + return new ServerInit() { + }; + } + + interface ServerInit { + } +} diff --git a/infra/northbound/restconf/src/main/java/io/fd/honeycomb/northbound/restconf/RestconfConfiguration.java b/infra/northbound/restconf/src/main/java/io/fd/honeycomb/northbound/restconf/RestconfConfiguration.java new file mode 100644 index 000000000..a02429b26 --- /dev/null +++ b/infra/northbound/restconf/src/main/java/io/fd/honeycomb/northbound/restconf/RestconfConfiguration.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2017 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.northbound.restconf; + +import java.util.Optional; +import net.jmob.guice.conf.core.BindConfig; +import net.jmob.guice.conf.core.InjectConfig; +import net.jmob.guice.conf.core.Syntax; + +//TODO - HONEYCOMB-377 - do not include module to active modules if disabled +@BindConfig(value = "restconf", syntax = Syntax.JSON) +public class RestconfConfiguration { + + public boolean isRestconfHttpEnabled() { + return Boolean.valueOf(restconfHttp); + } + + public boolean isRestconfHttpsEnabled() { + return Boolean.valueOf(restconfHttps); + } + + public boolean isRestconfEnabled() { + return isRestconfHttpEnabled() || isRestconfHttpsEnabled(); + } + + @InjectConfig("restconf-http-enabled") + public String restconfHttp; + @InjectConfig("restconf-binding-address") + public Optional<String> restconfBindingAddress; + @InjectConfig("restconf-port") + public Optional<Integer> restconfPort; + @InjectConfig("restconf-https-enabled") + public String restconfHttps; + @InjectConfig("restconf-https-binding-address") + public Optional<String> restconfHttpsBindingAddress; + @InjectConfig("restconf-https-port") + public Optional<Integer> restconfHttpsPort; + + /** + * Restconf keystore file name. It will be loaded from the classpath so must be present in one of the folders + * packaged with the distribution e.g. cert/ + */ + @InjectConfig("restconf-keystore") + public Optional<String> restconfKeystore = Optional.of("/honeycomb-keystore"); + @InjectConfig("restconf-keystore-password") + public Optional<String> keystorePassword; + @InjectConfig("restconf-keystore-manager-password") + public Optional<String> keystoreManagerPassword; + + /** + * Restconf truststore file name. It will be loaded from the classpath so must be present in one of the folders + * packaged with the distribution e.g. cert/ + */ + @InjectConfig("restconf-truststore") + public Optional<String> restconfTruststore; + @InjectConfig("restconf-truststore-password") + public Optional<String> truststorePassword; + @InjectConfig("restconf-websocket-port") + public Optional<Integer> restconfWebsocketPort = Optional.of(7779); + @InjectConfig("restconf-root-path") + public Optional<String> restconfRootPath = Optional.of("/restconf"); + @InjectConfig("restconf-pool-max-size") + public Optional<Integer> restPoolMaxSize = Optional.of(10); + @InjectConfig("restconf-pool-min-size") + public Optional<Integer> restPoolMinSize = Optional.of(1); + @InjectConfig("restconf-acceptors-size") + public Optional<Integer> acceptorsSize = Optional.of(1); + @InjectConfig("restconf-selectors-size") + public Optional<Integer> selectorsSize = Optional.of(1); + @InjectConfig("restconf-https-acceptors-size") + public Optional<Integer> httpsAcceptorsSize = Optional.of(1); + @InjectConfig("restconf-https-selectors-size") + public Optional<Integer> httpsSelectorsSize = Optional.of(1); + + @Override + public String toString() { + return "RestconfConfiguration{" + + "restconfHttp='" + restconfHttp + '\'' + + ", restconfBindingAddress=" + restconfBindingAddress + + ", restconfPort=" + restconfPort + + ", restconfHttps='" + restconfHttps + '\'' + + ", restconfHttpsBindingAddress=" + restconfHttpsBindingAddress + + ", restconfHttpsPort=" + restconfHttpsPort + + ", restconfKeystore=" + restconfKeystore + + ", keystorePassword=" + keystorePassword + + ", keystoreManagerPassword=" + keystoreManagerPassword + + ", restconfTruststore=" + restconfTruststore + + ", truststorePassword=" + truststorePassword + + ", restconfWebsocketPort=" + restconfWebsocketPort + + ", restconfRootPath=" + restconfRootPath + + ", restPoolMaxSize=" + restPoolMaxSize + + ", restPoolMinSize=" + restPoolMinSize + + ", acceptorsSize=" + acceptorsSize + + ", selectorsSize=" + selectorsSize + + ", httpsAcceptorsSize=" + httpsAcceptorsSize + + ", httpsSelectorsSize=" + httpsSelectorsSize + + '}'; + } +} diff --git a/infra/northbound/restconf/src/main/java/io/fd/honeycomb/northbound/restconf/RestconfConfigurationModule.java b/infra/northbound/restconf/src/main/java/io/fd/honeycomb/northbound/restconf/RestconfConfigurationModule.java new file mode 100644 index 000000000..1e18a3700 --- /dev/null +++ b/infra/northbound/restconf/src/main/java/io/fd/honeycomb/northbound/restconf/RestconfConfigurationModule.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2017 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.northbound.restconf; + +import com.google.inject.AbstractModule; +import net.jmob.guice.conf.core.ConfigurationModule; + +public class RestconfConfigurationModule extends AbstractModule { + + @Override + protected void configure() { + install(ConfigurationModule.create()); + requestInjection(RestconfConfiguration.class); + } +} diff --git a/infra/northbound/restconf/src/main/java/io/fd/honeycomb/northbound/restconf/RestconfModule.java b/infra/northbound/restconf/src/main/java/io/fd/honeycomb/northbound/restconf/RestconfModule.java new file mode 100644 index 000000000..9f9ecf7a2 --- /dev/null +++ b/infra/northbound/restconf/src/main/java/io/fd/honeycomb/northbound/restconf/RestconfModule.java @@ -0,0 +1,59 @@ +/* + * 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.northbound.restconf; + +import com.google.inject.Singleton; +import com.google.inject.name.Names; +import io.fd.honeycomb.northbound.NorthboundAbstractModule; +import io.fd.honeycomb.northbound.restconf.JettyServerStarter.ServerInit; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.ServerConnector; +import org.opendaylight.netconf.sal.rest.api.RestConnector; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class RestconfModule extends NorthboundAbstractModule<RestconfConfiguration> { + + private static final Logger LOG = LoggerFactory.getLogger(RestconfModule.class); + + public static final String RESTCONF_HTTP = "restconf-http"; + public static final String RESTCONF_HTTPS = "restconf-https"; + + public RestconfModule() { + super(new RestconfConfigurationModule(), RestconfConfiguration.class); + } + + @Override + protected void configure() { + if (!getConfiguration().isRestconfEnabled()) { + LOG.info("Restconf is disabled, skipping configuration"); + return; + } + + LOG.info("Starting RESTCONF Northbound"); + install(new RestconfConfigurationModule()); + bind(Server.class).toProvider(JettyServerProvider.class).in(Singleton.class); + bind(ServerConnector.class).annotatedWith(Names.named(RESTCONF_HTTP)) + .toProvider(HttpConnectorProvider.class) + .in(Singleton.class); + bind(ServerConnector.class).annotatedWith(Names.named(RESTCONF_HTTPS)) + .toProvider(HttpsConnectorProvider.class) + .in(Singleton.class); + bind(RestConnector.class).toProvider(RestconfProvider.class).in(Singleton.class); + bind(ServerInit.class).toProvider(JettyServerStarter.class).asEagerSingleton(); + } +} diff --git a/infra/northbound/restconf/src/main/java/io/fd/honeycomb/northbound/restconf/RestconfProvider.java b/infra/northbound/restconf/src/main/java/io/fd/honeycomb/northbound/restconf/RestconfProvider.java new file mode 100644 index 000000000..d519a931d --- /dev/null +++ b/infra/northbound/restconf/src/main/java/io/fd/honeycomb/northbound/restconf/RestconfProvider.java @@ -0,0 +1,40 @@ +/* + * 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.northbound.restconf; + +import com.google.inject.Inject; +import io.fd.honeycomb.binding.init.ProviderTrait; +import org.opendaylight.controller.sal.core.api.Broker; +import org.opendaylight.netconf.sal.rest.api.RestConnector; +import org.opendaylight.netconf.sal.restconf.impl.RestconfProviderImpl; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber; + +final class RestconfProvider extends ProviderTrait<RestConnector> { + + @Inject + private RestconfConfiguration cfg; + @Inject + private Broker domBroker; + + @Override + protected RestconfProviderImpl create() { + RestconfProviderImpl instance = new RestconfProviderImpl(); + instance.setWebsocketPort(new PortNumber(cfg.restconfWebsocketPort.get())); + domBroker.registerProvider(instance); + return instance; + } +} diff --git a/infra/northbound/restconf/src/main/resources/honeycomb-minimal-resources/config/restconf.json b/infra/northbound/restconf/src/main/resources/honeycomb-minimal-resources/config/restconf.json new file mode 100644 index 000000000..d04e4ed3d --- /dev/null +++ b/infra/northbound/restconf/src/main/resources/honeycomb-minimal-resources/config/restconf.json @@ -0,0 +1,21 @@ +{ + "restconf-http-enabled": "true", + "restconf-root-path": "/restconf", + "restconf-binding-address": "127.0.0.1", + "restconf-port": 8183, + "restconf-https-enabled": "true", + "restconf-https-binding-address": "0.0.0.0", + "restconf-https-port": 8445, + "restconf-keystore": "/honeycomb-keystore", + "restconf-keystore-password": "OBF:1v9s1unr1unn1vv51zlk1t331vg91x1b1vgl1t331zly1vu51uob1uo71v8u", + "restconf-keystore-manager-password": "OBF:1v9s1unr1unn1vv51zlk1t331vg91x1b1vgl1t331zly1vu51uob1uo71v8u", + "restconf-truststore": "/honeycomb-keystore", + "restconf-truststore-password": "OBF:1v9s1unr1unn1vv51zlk1t331vg91x1b1vgl1t331zly1vu51uob1uo71v8u", + "restconf-websocket-port": 7779, + "restconf-pool-max-size": 10, + "restconf-pool-min-size": 1, + "restconf-acceptors-size": 1, + "restconf-selectors-size": 1, + "restconf-https-acceptors-size": 1, + "restconf-https-selectors-size": 1 +} |