Eliminate NormalizedNodePayload
[netconf.git] / restconf / restconf-nb / src / main / java / org / opendaylight / restconf / nb / rfc8040 / JaxRsNorthbound.java
index 2042e29d061d8e6d5a623f405c6d6df056bf6139..965204df032cf59b9f615074550868e1473dd4d2 100644 (file)
@@ -8,7 +8,9 @@
 package org.opendaylight.restconf.nb.rfc8040;
 
 import com.google.common.annotations.Beta;
+import java.util.Set;
 import javax.servlet.ServletException;
+import javax.ws.rs.core.Application;
 import org.opendaylight.aaa.filterchain.configuration.CustomFilterAdapterConfiguration;
 import org.opendaylight.aaa.filterchain.filters.CustomFilterAdapter;
 import org.opendaylight.aaa.web.FilterDetails;
@@ -17,56 +19,26 @@ import org.opendaylight.aaa.web.WebContext;
 import org.opendaylight.aaa.web.WebContextSecurer;
 import org.opendaylight.aaa.web.WebServer;
 import org.opendaylight.aaa.web.servlet.ServletSupport;
-import org.opendaylight.controller.config.threadpool.util.NamingThreadPoolFactory;
-import org.opendaylight.controller.config.threadpool.util.ScheduledThreadPoolWrapper;
-import org.opendaylight.mdsal.dom.api.DOMActionService;
-import org.opendaylight.mdsal.dom.api.DOMDataBroker;
-import org.opendaylight.mdsal.dom.api.DOMMountPointService;
-import org.opendaylight.mdsal.dom.api.DOMNotificationService;
-import org.opendaylight.mdsal.dom.api.DOMRpcService;
-import org.opendaylight.mdsal.dom.api.DOMSchemaService;
-import org.opendaylight.restconf.nb.rfc8040.databind.DatabindProvider;
-import org.opendaylight.restconf.nb.rfc8040.rests.services.impl.MdsalRestconfServer;
-import org.opendaylight.restconf.nb.rfc8040.rests.services.impl.RestconfDataStreamServiceImpl;
-import org.opendaylight.restconf.nb.rfc8040.rests.services.impl.SubscribeToStreamUtil;
-import org.opendaylight.restconf.nb.rfc8040.rests.utils.RestconfStreamsConstants;
-import org.opendaylight.restconf.nb.rfc8040.streams.StreamsConfiguration;
-import org.opendaylight.restconf.nb.rfc8040.streams.WebSocketInitializer;
-import org.opendaylight.restconf.nb.rfc8040.streams.listeners.ListenersBroker;
+import org.opendaylight.restconf.nb.jaxrs.JaxRsRestconf;
+import org.opendaylight.restconf.nb.jaxrs.JaxRsWebHostMetadata;
+import org.opendaylight.restconf.nb.jaxrs.JsonJaxRsFormattableBodyWriter;
+import org.opendaylight.restconf.nb.jaxrs.XmlJaxRsFormattableBodyWriter;
+import org.opendaylight.restconf.nb.rfc8040.jersey.providers.errors.RestconfDocumentedExceptionMapper;
+import org.opendaylight.restconf.nb.rfc8040.streams.RestconfStreamServletFactory;
+import org.opendaylight.restconf.server.api.RestconfServer;
+import org.opendaylight.restconf.server.spi.DatabindProvider;
 import org.opendaylight.yangtools.concepts.Registration;
 import org.osgi.service.component.annotations.Activate;
 import org.osgi.service.component.annotations.Component;
 import org.osgi.service.component.annotations.Deactivate;
 import org.osgi.service.component.annotations.Reference;
-import org.osgi.service.metatype.annotations.AttributeDefinition;
-import org.osgi.service.metatype.annotations.Designate;
-import org.osgi.service.metatype.annotations.ObjectClassDefinition;
 
 /**
  * Main entrypoint into RFC8040 northbound. Take care of wiring up all applications activating them through JAX-RS.
  */
 @Beta
-@Component(service = { }, configurationPid = "org.opendaylight.restconf.nb.rfc8040")
-@Designate(ocd = JaxRsNorthbound.Configuration.class)
+@Component(service = { })
 public final class JaxRsNorthbound implements AutoCloseable {
-    @ObjectClassDefinition
-    public @interface Configuration {
-        @AttributeDefinition(min = "0", max = "" + StreamsConfiguration.MAXIMUM_FRAGMENT_LENGTH_LIMIT)
-        int maximum$_$fragment$_$length() default 0;
-        @AttributeDefinition(min = "0")
-        int heartbeat$_$interval() default 10000;
-        @AttributeDefinition(min = "1")
-        int idle$_$timeout() default 30000;
-        @AttributeDefinition(min = "1")
-        String ping$_$executor$_$name$_$prefix() default "ping-executor";
-        // FIXME: this is a misnomer: it specifies the core pool size, i.e. minimum thread count, the maximum is set to
-        //        Integer.MAX_VALUE, which is not what we want
-        @AttributeDefinition(min = "0")
-        int max$_$thread$_$count() default 1;
-        @AttributeDefinition
-        boolean use$_$sse() default true;
-    }
-
     private final Registration discoveryReg;
     private final Registration restconfReg;
 
@@ -74,66 +46,34 @@ public final class JaxRsNorthbound implements AutoCloseable {
     public JaxRsNorthbound(@Reference final WebServer webServer, @Reference final WebContextSecurer webContextSecurer,
             @Reference final ServletSupport servletSupport,
             @Reference final CustomFilterAdapterConfiguration filterAdapterConfiguration,
-            @Reference final DOMActionService actionService, @Reference final DOMDataBroker dataBroker,
-            @Reference final DOMMountPointService mountPointService,
-            @Reference final DOMNotificationService notificationService, @Reference final DOMRpcService rpcService,
-            @Reference final DOMSchemaService schemaService, @Reference final DatabindProvider databindProvider,
-            @Reference final MdsalRestconfServer server, @Reference final ListenersBroker listenersBroker,
-            final Configuration configuration) throws ServletException {
-        this(webServer, webContextSecurer, servletSupport, filterAdapterConfiguration, actionService, dataBroker,
-            mountPointService, notificationService, rpcService, schemaService, databindProvider, server,
-            listenersBroker, configuration.ping$_$executor$_$name$_$prefix(), configuration.max$_$thread$_$count(),
-            new StreamsConfiguration(configuration.maximum$_$fragment$_$length(),
-                configuration.idle$_$timeout(), configuration.heartbeat$_$interval(), configuration.use$_$sse()));
-    }
-
-    public JaxRsNorthbound(final WebServer webServer, final WebContextSecurer webContextSecurer,
-            final ServletSupport servletSupport, final CustomFilterAdapterConfiguration filterAdapterConfiguration,
-            final DOMActionService actionService, final DOMDataBroker dataBroker,
-            final DOMMountPointService mountPointService, final DOMNotificationService notificationService,
-            final DOMRpcService rpcService, final DOMSchemaService schemaService,
-            final DatabindProvider databindProvider, final MdsalRestconfServer server,
-            final ListenersBroker listenersBroker, final String pingNamePrefix, final int pingMaxThreadCount,
-            final StreamsConfiguration streamsConfiguration) throws ServletException {
-        final var scheduledThreadPool = new ScheduledThreadPoolWrapper(pingMaxThreadCount,
-            new NamingThreadPoolFactory(pingNamePrefix));
-
-        final SubscribeToStreamUtil streamUtils;
-        final ServletDetails streamServlet;
-        if (streamsConfiguration.useSSE()) {
-            streamUtils = SubscribeToStreamUtil.serverSentEvents(listenersBroker);
-            streamServlet = ServletDetails.builder()
-                .addUrlPattern("/" + URLConstants.SSE_SUBPATH + "/*")
-                .servlet(servletSupport.createHttpServletBuilder(
-                    new DataStreamApplication(databindProvider,
-                        new RestconfDataStreamServiceImpl(scheduledThreadPool, listenersBroker, streamsConfiguration)))
-                    .build())
-                .name("notificationServlet")
-                .asyncSupported(true)
-                .build();
-        } else {
-            streamUtils = SubscribeToStreamUtil.webSockets(listenersBroker);
-            streamServlet = ServletDetails.builder()
-                .addUrlPattern("/" + RestconfStreamsConstants.DATA_SUBSCRIPTION + "/*")
-                .addUrlPattern("/" + RestconfStreamsConstants.NOTIFICATION_STREAM + "/*")
-                .addUrlPattern("/" + RestconfStreamsConstants.DEVICE_NOTIFICATION_STREAM + "/*")
-                .servlet(new WebSocketInitializer(scheduledThreadPool, listenersBroker, streamsConfiguration))
-                .build();
-        }
-
+            @Reference final DatabindProvider databindProvider, @Reference final RestconfServer server,
+            @Reference final RestconfStreamServletFactory servletFactory) throws ServletException {
         final var restconfBuilder = WebContext.builder()
             .name("RFC8040 RESTCONF")
-            .contextPath("/" + URLConstants.BASE_PATH)
+            .contextPath("/" + servletFactory.restconf())
             .supportsSessions(false)
             .addServlet(ServletDetails.builder()
                 .addUrlPattern("/*")
                 .servlet(servletSupport.createHttpServletBuilder(
-                    new RestconfApplication(databindProvider, server, mountPointService, dataBroker, actionService,
-                        notificationService, schemaService, streamUtils))
-                    .build())
+                    new Application() {
+                        @Override
+                        public Set<Object> getSingletons() {
+                            final var errorTagMapping = servletFactory.errorTagMapping();
+
+                            return Set.of(
+                                new JsonJaxRsFormattableBodyWriter(), new XmlJaxRsFormattableBodyWriter(),
+                                new RestconfDocumentedExceptionMapper(databindProvider, errorTagMapping),
+                                new JaxRsRestconf(server, errorTagMapping, servletFactory.prettyPrint()));
+                        }
+                    }).build())
+                .asyncSupported(true)
+                .build())
+            .addServlet(ServletDetails.builder()
+                .addUrlPattern("/" + URLConstants.STREAMS_SUBPATH + "/*")
+                .servlet(servletFactory.newStreamServlet())
+                .name("notificationServlet")
                 .asyncSupported(true)
                 .build())
-            .addServlet(streamServlet)
 
             // Allows user to add javax.servlet.Filter(s) in front of REST services
             .addFilter(FilterDetails.builder()
@@ -152,8 +92,13 @@ public final class JaxRsNorthbound implements AutoCloseable {
             .supportsSessions(false)
             .addServlet(ServletDetails.builder()
                 .addUrlPattern("/*")
-                .servlet(servletSupport.createHttpServletBuilder(new RootFoundApplication(URLConstants.BASE_PATH))
-                    .build())
+                .servlet(servletSupport.createHttpServletBuilder(
+                    new Application() {
+                        @Override
+                        public Set<Object> getSingletons() {
+                            return Set.of(new JaxRsWebHostMetadata(servletFactory.restconf()));
+                        }
+                    }).build())
                 .name("Rootfound")
                 .build());