add restconf
authorMichael Vorburger <mike@vorburger.ch>
Thu, 11 Oct 2018 00:35:27 +0000 (02:35 +0200)
committerMichael Vorburger <mike@vorburger.ch>
Wed, 1 Jul 2020 23:37:34 +0000 (01:37 +0200)
Signed-off-by: Michael Vorburger <mike@vorburger.ch>
13 files changed:
TODO.md
pom.xml
src/main/java/org/opendaylight/controller/simple/ControllerWiring.java
src/main/java/org/opendaylight/genius/simple/GeniusWiring.java
src/main/java/org/opendaylight/infrautils/simple/ConfigImmutableStyle.java [new file with mode: 0644]
src/main/java/org/opendaylight/infrautils/web/WebWiring.java
src/main/java/org/opendaylight/restconf/simple/RestConfConfig.java [new file with mode: 0644]
src/main/java/org/opendaylight/restconf/simple/RestConfModule.java [new file with mode: 0644]
src/main/java/org/opendaylight/restconf/simple/RestConfWiring.java [new file with mode: 0644]
src/test/java/org/opendaylight/genius/simple/test/GeniusSimpleDistributionTest.java
src/test/java/org/opendaylight/infrautils/inject/guice/testutils/tests/GuiceRuleLambdaTest.java [new file with mode: 0644]
src/test/java/org/opendaylight/infrautils/simple/testutils/AbstractSimpleDistributionTest.java
src/test/java/org/opendaylight/restconf/simple/test/RestConfModuleTest.java [new file with mode: 0644]

diff --git a/TODO.md b/TODO.md
index be3c8dbea87eb558e2faffc23e8d3327128b3d0c..fc9e550ef5df593cade59755a4a1822a03e17b56 100644 (file)
--- a/TODO.md
+++ b/TODO.md
@@ -9,20 +9,27 @@
 
 - [X] quit/shutdown shell
 
-- [ ] working deployment
+- [X] working deployment
 
 - [X] working /diagstatus and showSvcStatus (#39) [waiting for infrautils merges]
 
+- [ ] RestConfWiring with Web API
+
+- [ ] make RestConfConfig readable from YAML using http://immutables.github.io/json.html and update @ConfigImmutableStyle for it, then upstream to infrautils
+
 - [ ] ditch AAA and use Filter from Jetty for BASIC auth instead
 
-- [ ] CDS instead of in-memory DS: [CONTROLLER-1831](https://jira.opendaylight.org/browse/CONTROLLER-1831)
+- [ ] NeutronWiring with Web API (req. by netvirt, but not genius)
 
-- [ ] RestConfWiring with Web API
+- [ ] ovsdb https://github.com/vorburger/opendaylight-simple/issues/47
+
+- [ ] CDS instead of in-memory DS: [CONTROLLER-1831](https://jira.opendaylight.org/browse/CONTROLLER-1831)
 
 - [X] OpenFlowPlugin wiring ConfigurationServiceFactoryImpl (OPNFLWPLUG-1037)
 - [ ] OpenFlowPluginWiring PacketProcessingService <odl:action-provider>
+- [ ] OpenFlowPlugin wiring
 
-- [ ] skitt's https://github.com/vorburger/opendaylight-simple/issues/38
+- [X] skitt's https://github.com/vorburger/opendaylight-simple/issues/38
 - [ ] DiagStatusWiring auto-discover ServiceStatusProvider
 - [ ] CLI commands, such as ItmWiring's TepShowState and DiagStatusCommand in DiagStatusWiring, which `implements Action`, should be auto-discovered
 
@@ -40,8 +47,6 @@
 
 - [ ] run genius CSIT
 
-- [ ] NeutronWiring with Web API (req. by netvirt, but not genius)
-
 - [ ] do the same as this already did for genius for all of netvirt
 
 - [ ] run netvirt CSIT
diff --git a/pom.xml b/pom.xml
index 4129d7585568a3ab55cc744cb6ccef1ce666320b..05247ce309a033e75ef828b0e8e6d765064f58c7 100644 (file)
--- a/pom.xml
+++ b/pom.xml
         <type>pom</type>
         <scope>import</scope>
       </dependency>
+      <dependency>
+        <groupId>org.opendaylight.netconf</groupId>
+        <artifactId>restconf-artifacts</artifactId>
+        <version>1.9.0-SNAPSHOT</version>
+        <type>pom</type>
+        <scope>import</scope>
+      </dependency>
 
 <!--
       <dependency>
   </dependencyManagement>
 
   <dependencies>
+    <dependency>
+      <groupId>org.immutables</groupId>
+      <artifactId>value</artifactId>
+    </dependency>
 <!-- TODO integrate neutron (after genius is working)
     <dependency>
       <groupId>org.opendaylight.neutron</groupId>
       </exclusions>
  -->
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.netconf</groupId>
+      <artifactId>restconf-nb-rfc8040</artifactId>
+    </dependency>
 
     <dependency>
       <groupId>org.apache.karaf.shell</groupId>
           <groupId>org.apache.karaf.shell</groupId>
           <artifactId>org.apache.karaf.shell.console</artifactId>
         </exclusion>
-        <!-- osgi.core overlaps (x5) with felix.configadmin, and we don't need it here anyway -->
+        <!-- osgi.core overlaps (x5) with felix.configadmin, and we don't need it here anyway
+             TODO EXCLUDE IT AGAIN LATER; FOR NOW, SOME CLASSES UNFORTUNATELY STILL REFERENCE IT
         <exclusion>
           <groupId>org.osgi</groupId>
           <artifactId>org.osgi.core</artifactId>
         </exclusion>
+         -->
         <!-- osgi.compendium (big) overlaps (x12) with (small) felix.configadmin, and with org.osgi.service.event (x9)
         <exclusion>
           <groupId>org.osgi</groupId>
index acd7a9164a1bc3cd04e65fc55e7f99cf611715be..486af33ba13ebae6b924bd2c31fefeb36d177b2e 100644 (file)
@@ -13,13 +13,21 @@ import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService
 import org.opendaylight.controller.md.sal.binding.impl.BindingDOMNotificationPublishServiceAdapter;
 import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec;
 import org.opendaylight.controller.md.sal.binding.test.DataBrokerTestModule;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
+import org.opendaylight.controller.md.sal.dom.api.DOMNotificationService;
 import org.opendaylight.controller.md.sal.dom.broker.impl.DOMNotificationRouter;
+import org.opendaylight.controller.md.sal.dom.broker.impl.mount.DOMMountPointServiceImpl;
 import org.opendaylight.infrautils.inject.guice.AbstractCloseableModule;
 import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer;
+import org.opendaylight.mdsal.dom.api.DOMRpcService;
+import org.opendaylight.mdsal.dom.api.DOMSchemaService;
+import org.opendaylight.mdsal.dom.broker.DOMRpcRouter;
 import org.opendaylight.mdsal.simple.MdsalWiring;
 
 @SuppressFBWarnings("UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR")
 public class ControllerWiring extends AbstractCloseableModule {
+    // TODO rename this to InMemoryDataStoreModule - because that's what this really is
 
     // TODO propose @Inject and @PreDestroy close() annotations at source to simplify this, a lot...
 
@@ -34,14 +42,32 @@ public class ControllerWiring extends AbstractCloseableModule {
         // TODO this is just for early stage POC! switch to real CDS wiring here, eventually..
         DataBrokerTestModule dataBrokerTestModule = new DataBrokerTestModule(true);
         DataBroker dataBroker = dataBrokerTestModule.getDataBroker();
+        DOMSchemaService domSchemaService = dataBrokerTestModule.getSchemaService();
+
+        bind(DOMSchemaService.class).toInstance(domSchemaService);
+        bind(DOMDataBroker.class).toInstance(dataBrokerTestModule.getDOMDataBroker());
         bind(DataBroker.class).toInstance(dataBroker);
 
         bindingToNormalizedNodeCodec = dataBrokerTestModule.getBindingToNormalizedNodeCodec();
         domNotificationPublishService = dataBrokerTestModule.getDOMNotificationRouter();
+        bind(DOMNotificationService.class).toInstance(domNotificationPublishService);
+
         bindingDOMNotificationPublishServiceAdapter = new BindingDOMNotificationPublishServiceAdapter(
                 bindingToNormalizedNodeCodec, domNotificationPublishService);
         bind(NotificationPublishService.class).toInstance(bindingDOMNotificationPublishServiceAdapter);
         bind(BindingNormalizedNodeSerializer.class).toInstance(bindingToNormalizedNodeCodec);
+
+        bind(DOMMountPointService.class).to(DOMMountPointServiceImpl.class);
+
+        DOMRpcRouter domRpcRouter = DOMRpcRouter.newInstance(domSchemaService);
+        bind(DOMRpcService.class).toInstance(domRpcRouter.getRpcService());
+
+        org.opendaylight.controller.md.sal.dom.broker.impl.DOMRpcRouter controllerDOMRpcService
+            = new org.opendaylight.controller.md.sal.dom.broker.impl.DOMRpcRouter(
+                    domRpcRouter.getRpcService(), domRpcRouter.getRpcProviderService());
+        bind(org.opendaylight.controller.md.sal.dom.api.DOMRpcService.class).toInstance(controllerDOMRpcService);
+        bind(org.opendaylight.controller.md.sal.dom.api.DOMRpcProviderService.class)
+                .toInstance(controllerDOMRpcService);
     }
 
     @Override
@@ -50,5 +76,4 @@ public class ControllerWiring extends AbstractCloseableModule {
         bindingDOMNotificationPublishServiceAdapter.close();
         domNotificationPublishService.close();
     }
-
 }
index d5395bc145e8b2afd7568c7a84a89201d13155aa..5537c7cba9f4f8b65a3697d86d62f1ee2b2551cc 100644 (file)
@@ -15,6 +15,7 @@ import org.opendaylight.infrautils.inject.guice.testutils.AnnotationsModule;
 import org.opendaylight.infrautils.simple.InfraUtilsWiring;
 import org.opendaylight.neutron.simple.NeutronModule;
 import org.opendaylight.openflowplugin.simple.OpenFlowPluginWiring;
+import org.opendaylight.restconf.simple.RestConfModule;
 import org.opendaylight.serviceutils.simple.ServiceUtilsWiring;
 
 public class GeniusWiring extends AbstractModule {
@@ -36,6 +37,9 @@ public class GeniusWiring extends AbstractModule {
         // MD SAL
         install(new ControllerWiring());
 
+        // RESTCONF
+        install(new RestConfModule());
+
         // Daexim
         // TODO write real DaeximWiring, and replace this line with an install(new DaeximWiring());
         bind(DataImportBootReady.class).toInstance(new DataImportBootReady() {});
diff --git a/src/main/java/org/opendaylight/infrautils/simple/ConfigImmutableStyle.java b/src/main/java/org/opendaylight/infrautils/simple/ConfigImmutableStyle.java
new file mode 100644 (file)
index 0000000..556149d
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2017 Red Hat, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.infrautils.simple;
+
+import static org.immutables.value.Value.Style.ImplementationVisibility.PRIVATE;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import org.immutables.value.Value;
+
+/**
+ * <a href="http://immutables.org">Immutables.org</a> style meta annotation.
+ *
+ * @author Michael Vorburger.ch
+ */
+@Target({ElementType.PACKAGE, ElementType.TYPE})
+@Retention(RetentionPolicy.CLASS) // Make it class retention for incremental compilation
+@Value.Style(
+        // generate *Builder as public top level type and the *Immutable impl. as private inner class
+        visibility = PRIVATE,
+        strictBuilder = true)
+public @interface ConfigImmutableStyle { }
+// Beware: Changes made here are not active without a restart in Eclipse (would need separate project)
index adaffada0e0f0a558191e19cc75a6a129aa21b78..d5ac319758b4438e0e6b026d67d043a069188404 100644 (file)
@@ -26,7 +26,7 @@ public class WebWiring extends AbstractModule {
         // TODO read port from a -D parameter or configuration file instead of hard-coding
         bind(WebServer.class).toInstance(new JettyWebServer(8181));
 
-        // JSX-RS
+        // JAX-RS
         bind(ServletSupport.class).to(JerseyServletSupport.class);
 
         // TODO replace this NOOP WebContextSecurer with one with a fixed uid/pwd for HTTP BASIC (and ditch AAA)
diff --git a/src/main/java/org/opendaylight/restconf/simple/RestConfConfig.java b/src/main/java/org/opendaylight/restconf/simple/RestConfConfig.java
new file mode 100644 (file)
index 0000000..f28ad56
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2018 Red Hat, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.restconf.simple;
+
+import java.net.InetAddress;
+import org.immutables.value.Value;
+import org.opendaylight.infrautils.simple.ConfigImmutableStyle;
+
+/**
+ * Configuration for the RESTCONF server.
+ *
+ * @author Michael Vorburger.ch
+ */
+@Value.Immutable
+@ConfigImmutableStyle
+public interface RestConfConfig {
+
+    static RestConfConfigBuilder builder() {
+        return new RestConfConfigBuilder();
+    }
+
+    /**
+     * IP interface which the WebSocket server will listen on.
+     */
+    // TODO make this Optional<InetAddress> and by default run on the same IF as the WebServer (TBD)
+    InetAddress webSocketAddress();
+
+    /**
+     * TCP port which the WebSocket server will listen on.
+     */
+    int webSocketPort();
+
+    /**
+     * Web URL prefix. Defaults to "/restconf".
+     */
+    default String contextPath() {
+        return "/restconf";
+    }
+}
diff --git a/src/main/java/org/opendaylight/restconf/simple/RestConfModule.java b/src/main/java/org/opendaylight/restconf/simple/RestConfModule.java
new file mode 100644 (file)
index 0000000..999cd51
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2018 Red Hat, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.restconf.simple;
+
+import com.google.inject.AbstractModule;
+import java.net.InetAddress;
+
+/**
+ * Guice module for RestConf, based on {@link RestConfWiring}.
+ *
+ * @author Michael Vorburger.ch
+ */
+public class RestConfModule extends AbstractModule {
+
+    @Override
+    protected void configure() {
+        bind(RestConfWiring.class);
+        bind(RestConfConfig.class).toInstance(RestConfConfig.builder()
+                // TODO webSocketAddress should be required, and read from WebServer (configurable in WebWiring)
+                .webSocketAddress(InetAddress.getLoopbackAddress())
+                // TODO webSocketPort should be read from some configuration file
+                .webSocketPort(9090).build());
+    }
+}
diff --git a/src/main/java/org/opendaylight/restconf/simple/RestConfWiring.java b/src/main/java/org/opendaylight/restconf/simple/RestConfWiring.java
new file mode 100644 (file)
index 0000000..80fbcc9
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2018 Red Hat, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.restconf.simple;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.ws.rs.core.Application;
+import org.opendaylight.aaa.web.ServletDetails;
+import org.opendaylight.aaa.web.WebContext;
+import org.opendaylight.aaa.web.WebContextRegistration;
+import org.opendaylight.aaa.web.WebServer;
+import org.opendaylight.aaa.web.servlet.ServletSupport;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
+import org.opendaylight.controller.md.sal.dom.api.DOMNotificationService;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
+import org.opendaylight.mdsal.dom.api.DOMSchemaService;
+import org.opendaylight.netconf.sal.restconf.impl.BrokerFacade;
+import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
+import org.opendaylight.netconf.sal.restconf.impl.RestconfImpl;
+import org.opendaylight.netconf.sal.restconf.impl.RestconfProviderImpl;
+import org.opendaylight.netconf.sal.restconf.impl.StatisticsRestconfServiceWrapper;
+import org.opendaylight.restconf.nb.rfc8040.RestconfApplication;
+import org.opendaylight.restconf.nb.rfc8040.handlers.DOMDataBrokerHandler;
+import org.opendaylight.restconf.nb.rfc8040.handlers.DOMMountPointServiceHandler;
+import org.opendaylight.restconf.nb.rfc8040.handlers.NotificationServiceHandler;
+import org.opendaylight.restconf.nb.rfc8040.handlers.RpcServiceHandler;
+import org.opendaylight.restconf.nb.rfc8040.handlers.SchemaContextHandler;
+import org.opendaylight.restconf.nb.rfc8040.handlers.TransactionChainHandler;
+import org.opendaylight.restconf.nb.rfc8040.services.wrapper.ServicesWrapper;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Standalone wiring for RESTCONF.
+ *
+ * <p>ACK: Some lines here were originally inspired by the CommunityRestConf class
+ * from lighty.io. The differences include (1) that this class is "pure Java",
+ * because the intention here is only to incubate and then propose it upstream
+ * right into the netconf ODL project; (2) that we use infrautils.web (currently
+ * in aaa),
+ *
+ * @author Michael Vorburger.ch, partially based on code in lighty.io
+ */
+@Singleton
+public class RestConfWiring {
+
+    private static final Logger LOG = LoggerFactory.getLogger(RestConfWiring.class);
+
+    // TODO upstream this into ODL netconf/restconf and replace its Blueprint XML with this
+
+    private final WebServer webServer;
+    private final WebContext webContext;
+    private final RestconfProviderImpl webSockerServer;
+    private WebContextRegistration webContextRegistration;
+
+    @Inject
+    public RestConfWiring(RestConfConfig config, WebServer webServer, ServletSupport jaxRS,
+            DOMSchemaService domSchemaService, DOMMountPointService domMountPointService, DOMRpcService domRpcService,
+            DOMDataBroker domDataBroker, DOMNotificationService domNotificationService) {
+        this.webServer = webServer;
+        LOG.info("config = {}", config);
+
+        // WebSocket
+        ControllerContext controllerContext = ControllerContext.newInstance(domSchemaService, domMountPointService,
+                domSchemaService);
+        BrokerFacade broker = BrokerFacade.newInstance(domRpcService, domDataBroker, domNotificationService,
+                controllerContext);
+        RestconfImpl restconf = RestconfImpl.newInstance(broker, controllerContext);
+        StatisticsRestconfServiceWrapper stats = StatisticsRestconfServiceWrapper.newInstance(restconf);
+        IpAddress wsIpAddress = IpAddressBuilder.getDefaultInstance(config.webSocketAddress().getHostAddress());
+        this.webSockerServer = new RestconfProviderImpl(stats, wsIpAddress, new PortNumber(config.webSocketPort()));
+
+        // Servlet
+        TransactionChainHandler transactionChainHandler = new TransactionChainHandler(domDataBroker);
+        SchemaContextHandler schemaCtxHandler = SchemaContextHandler.newInstance(transactionChainHandler,
+                domSchemaService);
+        schemaCtxHandler.init();
+        DOMMountPointServiceHandler domMountPointServiceHandler = DOMMountPointServiceHandler
+                .newInstance(domMountPointService);
+        DOMDataBrokerHandler domDataBrokerHandler = new DOMDataBrokerHandler(domDataBroker);
+        RpcServiceHandler rpcServiceHandler = new RpcServiceHandler(domRpcService);
+        NotificationServiceHandler notificationServiceHandler = new NotificationServiceHandler(domNotificationService);
+        ServicesWrapper servicesWrapper = ServicesWrapper.newInstance(schemaCtxHandler, domMountPointServiceHandler,
+                transactionChainHandler, domDataBrokerHandler, rpcServiceHandler, notificationServiceHandler,
+                domSchemaService);
+
+        // This is currently hard-coded to DRAFT_18; if we ever actually need to support the
+        // older DRAFT_02 for anything, then (only) add it to the RestConfConfig and switch here
+        Application application = new RestconfApplication(schemaCtxHandler,
+                domMountPointServiceHandler, servicesWrapper);
+        HttpServlet servlet = jaxRS.createHttpServletBuilder(application).build();
+        this.webContext = WebContext.builder().contextPath(config.contextPath())
+                .addServlet(ServletDetails.builder().addUrlPattern("/*").servlet(servlet).build())
+                .build();
+
+        // TODO secure it, using web API
+    }
+
+    @PostConstruct
+    public void start() throws ServletException {
+        this.webContextRegistration = this.webServer.registerWebContext(webContext);
+        this.webSockerServer.start();
+    }
+
+    @PreDestroy
+    public void stop() {
+        this.webSockerServer.close();
+        if (webContextRegistration != null) {
+            this.webContextRegistration.close();
+        }
+    }
+}
index 2b6dbb306941ff9a687cb5b6280757f2afb20a76..7992365042ac582688697e0b616406ae01bc7e1d 100644 (file)
@@ -31,10 +31,8 @@ public class GeniusSimpleDistributionTest extends AbstractSimpleDistributionTest
 
     public @Rule GuiceRule2 guice = new GuiceRule2(new GeniusWiring(CLASS_PATH_BINDER), new ShellTestWiring());
 
-    @SuppressWarnings("unused")
-    private @Inject InterfaceManagerService interfaceManagerService;
+    @Inject InterfaceManagerService interfaceManagerService;
 
-    @SuppressWarnings("unused")
-    private @Inject IITMProvider itmProvider;
+    @Inject IITMProvider itmProvider;
 
 }
diff --git a/src/test/java/org/opendaylight/infrautils/inject/guice/testutils/tests/GuiceRuleLambdaTest.java b/src/test/java/org/opendaylight/infrautils/inject/guice/testutils/tests/GuiceRuleLambdaTest.java
new file mode 100644 (file)
index 0000000..9b3a4ff
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2018 Red Hat, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.infrautils.inject.guice.testutils.tests;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import javax.inject.Inject;
+import org.junit.Rule;
+import org.junit.Test;
+import org.opendaylight.infrautils.inject.guice.testutils.AnnotationsModule;
+import org.opendaylight.infrautils.inject.guice.testutils.GuiceRule;
+import org.opendaylight.infrautils.inject.guice.testutils.GuiceRule2;
+
+/**
+ * Test illustrating how to use the GuiceRule with an inline lamda binding.
+ *
+ * @author Michael Vorburger.ch
+ */
+public class GuiceRuleLambdaTest {
+
+    public @Rule GuiceRule guice = new GuiceRule2(
+        binder -> binder.bind(String.class).toInstance("hello, world"),
+        new AnnotationsModule());
+
+    @Inject String string;
+
+    @Test public void testLambdaBinding() {
+        assertThat(string).isEqualTo("hello, world");
+    }
+}
index 55361df2d2b7d16e2b0c70ad06f814aadf52e0af..38b4af6f3cf87589498563210554e25bbe86c206 100644 (file)
@@ -34,5 +34,4 @@ public abstract class AbstractSimpleDistributionTest {
     @Test public void testDistribution() {
         assertThat(closeableInjector).isNotNull();
     }
-
 }
diff --git a/src/test/java/org/opendaylight/restconf/simple/test/RestConfModuleTest.java b/src/test/java/org/opendaylight/restconf/simple/test/RestConfModuleTest.java
new file mode 100644 (file)
index 0000000..3f5031b
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2018 Red Hat, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.restconf.simple.test;
+
+import java.io.IOException;
+import javax.inject.Inject;
+import org.junit.Rule;
+import org.junit.Test;
+import org.opendaylight.aaa.web.WebServer;
+import org.opendaylight.controller.simple.ControllerWiring;
+import org.opendaylight.infrautils.inject.guice.testutils.AnnotationsModule;
+import org.opendaylight.infrautils.inject.guice.testutils.GuiceRule;
+import org.opendaylight.infrautils.inject.guice.testutils.GuiceRule2;
+import org.opendaylight.infrautils.simple.testutils.AbstractSimpleDistributionTest;
+import org.opendaylight.infrautils.testutils.TestHttpClient;
+import org.opendaylight.infrautils.web.WebWiring;
+import org.opendaylight.restconf.simple.RestConfModule;
+
+/**
+ * Tests if the {@link RestConfModule} works.
+ *
+ * @author Michael Vorburger.ch
+ */
+public class RestConfModuleTest extends AbstractSimpleDistributionTest {
+
+    public @Rule GuiceRule guice = new GuiceRule2(
+            RestConfModule.class, ControllerWiring.class, WebWiring.class, AnnotationsModule.class);
+
+    @Inject WebServer webServer;
+    @Inject TestHttpClient http;
+
+    @Test public void testRestConf() throws IOException {
+        // TODO assertThat(http.responseCode(GET, "/restconf/modules/")).isEqualTo(200);
+
+        // TODO test security; add auth support to TestHttpClient, check that w.o. auth it's 401
+    }
+}