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;
+import org.opendaylight.aaa.web.ServletDetails;
+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.RestconfDataStreamServiceImpl;
-import org.opendaylight.restconf.nb.rfc8040.streams.Configuration;
-import org.opendaylight.restconf.nb.rfc8040.streams.WebSocketInitializer;
-import org.opendaylight.restconf.nb.rfc8040.web.WebInitializer;
+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;
/**
* Main entrypoint into RFC8040 northbound. Take care of wiring up all applications activating them through JAX-RS.
*/
@Beta
+@Component(service = { })
public final class JaxRsNorthbound implements AutoCloseable {
- private final WebInitializer webInitializer;
-
- 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 String pingNamePrefix, final int pingMaxThreadCount, final int maximumFragmentLength,
- final int heartbeatInterval, final int idleTimeout, final boolean useSSE) throws ServletException {
- final var configuration = new Configuration(maximumFragmentLength, idleTimeout, heartbeatInterval, useSSE);
- final var scheduledThreadPool = new ScheduledThreadPoolWrapper(pingMaxThreadCount,
- new NamingThreadPoolFactory(pingNamePrefix));
-
- webInitializer = new WebInitializer(webServer, webContextSecurer, servletSupport,
- new RestconfApplication(databindProvider, mountPointService, dataBroker, rpcService, actionService,
- notificationService, schemaService, configuration),
- new DataStreamApplication(databindProvider, mountPointService,
- new RestconfDataStreamServiceImpl(scheduledThreadPool, configuration)),
- filterAdapterConfiguration,
- new WebSocketInitializer(scheduledThreadPool, configuration));
+ private final Registration discoveryReg;
+ private final Registration restconfReg;
+
+ @Activate
+ public JaxRsNorthbound(@Reference final WebServer webServer, @Reference final WebContextSecurer webContextSecurer,
+ @Reference final ServletSupport servletSupport,
+ @Reference final CustomFilterAdapterConfiguration filterAdapterConfiguration,
+ @Reference final DatabindProvider databindProvider, @Reference final RestconfServer server,
+ @Reference final RestconfStreamServletFactory servletFactory) throws ServletException {
+ final var restconfBuilder = WebContext.builder()
+ .name("RFC8040 RESTCONF")
+ .contextPath("/" + servletFactory.restconf())
+ .supportsSessions(false)
+ .addServlet(ServletDetails.builder()
+ .addUrlPattern("/*")
+ .servlet(servletSupport.createHttpServletBuilder(
+ 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())
+
+ // Allows user to add javax.servlet.Filter(s) in front of REST services
+ .addFilter(FilterDetails.builder()
+ .addUrlPattern("/*")
+ .filter(new CustomFilterAdapter(filterAdapterConfiguration))
+ .asyncSupported(true)
+ .build());
+
+ webContextSecurer.requireAuthentication(restconfBuilder, true, "/*");
+
+ restconfReg = webServer.registerWebContext(restconfBuilder.build());
+
+ final var discoveryBuilder = WebContext.builder()
+ .name("RFC6415 Web Host Metadata")
+ .contextPath("/.well-known")
+ .supportsSessions(false)
+ .addServlet(ServletDetails.builder()
+ .addUrlPattern("/*")
+ .servlet(servletSupport.createHttpServletBuilder(
+ new Application() {
+ @Override
+ public Set<Object> getSingletons() {
+ return Set.of(new JaxRsWebHostMetadata(servletFactory.restconf()));
+ }
+ }).build())
+ .name("Rootfound")
+ .build());
+
+ webContextSecurer.requireAuthentication(discoveryBuilder, true, "/*");
+
+ discoveryReg = webServer.registerWebContext(discoveryBuilder.build());
}
+ @Deactivate
@Override
public void close() {
- webInitializer.close();
+ discoveryReg.close();
+ restconfReg.close();
}
}