Convert JaxRsNorthbound into a Component 38/104338/2
authorRobert Varga <robert.varga@pantheon.tech>
Wed, 8 Feb 2023 23:18:52 +0000 (00:18 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Thu, 9 Feb 2023 12:49:25 +0000 (13:49 +0100)
We have all we need to ditch blueprint, rehost Config Admin binding and
turn JaxRsNorthbound into a proper Component.

JIRA: NETCONF-959
Change-Id: Id2af0cc4925b34de01198cfcfd98bc63351399d3
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
restconf/restconf-nb/pom.xml
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/JaxRsNorthbound.java
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/streams/StreamsConfiguration.java
restconf/restconf-nb/src/main/resources/OSGI-INF/blueprint/restconf-bp.xml [deleted file]

index ad0cc62362765ba329f075a271597416520aea3f..34496f6df49eb393dfdd8f561a265974eb0f0e88 100644 (file)
       <groupId>org.osgi</groupId>
       <artifactId>org.osgi.service.component.annotations</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.osgi</groupId>
+      <artifactId>org.osgi.service.metatype.annotations</artifactId>
+    </dependency>
 
     <dependency>
       <groupId>org.opendaylight.netconf</groupId>
index 66e1132baa89ab61f9d4dbb33dc8420b70077c10..afd17c770e03c996d73813e086c2ce82e45f7126 100644 (file)
@@ -35,25 +35,66 @@ import org.opendaylight.restconf.nb.rfc8040.rests.services.impl.RestconfDataStre
 import org.opendaylight.restconf.nb.rfc8040.streams.StreamsConfiguration;
 import org.opendaylight.restconf.nb.rfc8040.streams.WebSocketInitializer;
 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)
 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;
 
+    @Activate
+    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,
+            final Configuration configuration) throws ServletException {
+        this(webServer, webContextSecurer, servletSupport, filterAdapterConfiguration, actionService, dataBroker,
+            mountPointService, notificationService, rpcService, schemaService, databindProvider,
+            configuration.ping$_$executor$_$name$_$prefix(), configuration.max$_$thread$_$count(),
+            new StreamsConfiguration(configuration.maximum$_$fragment$_$length(), configuration.heartbeat$_$interval(),
+                configuration.idle$_$timeout(), 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 String pingNamePrefix, final int pingMaxThreadCount, final int maximumFragmentLength,
-            final int heartbeatInterval, final int idleTimeout, final boolean useSSE) throws ServletException {
-        final var streamsConfiguration = new StreamsConfiguration(maximumFragmentLength, idleTimeout, heartbeatInterval,
-            useSSE);
+            final String pingNamePrefix, final int pingMaxThreadCount,
+            final StreamsConfiguration streamsConfiguration) throws ServletException {
         final var scheduledThreadPool = new ScheduledThreadPoolWrapper(pingMaxThreadCount,
             new NamingThreadPoolFactory(pingNamePrefix));
 
@@ -108,6 +149,7 @@ public final class JaxRsNorthbound implements AutoCloseable {
         discoveryReg = webServer.registerWebContext(discoveryBuilder.build());
     }
 
+    @Deactivate
     @Override
     public void close() {
         discoveryReg.close();
index b8b700228fc5162be1ae360412689c9b3419858a..6a10286bfa2fd5a141f1c7bd25f04231c8f15dec 100644 (file)
@@ -19,8 +19,12 @@ import static com.google.common.base.Preconditions.checkArgument;
  * @param useSSE                when is {@code true} use SSE else use WS
  */
 public record StreamsConfiguration(int maximumFragmentLength, int idleTimeout, int heartbeatInterval, boolean useSSE) {
+    // FIXME: can this be 64KiB exactly? if so, maximumFragmentLength should become a Uint16 and validation should be
+    //        pushed out to users
+    public static final int MAXIMUM_FRAGMENT_LENGTH_LIMIT = 65534;
+
     public StreamsConfiguration {
-        checkArgument(maximumFragmentLength >= 0 && maximumFragmentLength < 65535,
+        checkArgument(maximumFragmentLength >= 0 && maximumFragmentLength <= MAXIMUM_FRAGMENT_LENGTH_LIMIT,
             "Maximum fragment length must be disabled (0) or specified by positive value less than 64KiB");
         checkArgument(idleTimeout > 0, "Idle timeout must be specified by positive value.");
         checkArgument(heartbeatInterval >= 0,
diff --git a/restconf/restconf-nb/src/main/resources/OSGI-INF/blueprint/restconf-bp.xml b/restconf/restconf-nb/src/main/resources/OSGI-INF/blueprint/restconf-bp.xml
deleted file mode 100644 (file)
index 2bf394b..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- Copyright (c) 2017 Pantheon technologies s.r.o. 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
--->
-<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
-           xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0">
-  <!-- Restconf providers -->
-  <cm:property-placeholder persistent-id="org.opendaylight.restconf.nb.rfc8040">
-    <cm:default-properties>
-      <cm:property name="maximum-fragment-length" value="0"/>
-      <cm:property name="heartbeat-interval" value="10000"/>
-      <cm:property name="idle-timeout" value="30000"/>
-      <cm:property name="ping-executor-name-prefix" value="ping-executor"/>
-      <cm:property name="max-thread-count" value="1"/>
-      <cm:property name="use-sse" value="true"/>
-    </cm:default-properties>
-  </cm:property-placeholder>
-
-  <reference id="databindProvider" interface="org.opendaylight.restconf.nb.rfc8040.databind.DatabindProvider"/>
-  <reference id="customFilterAdapterConfiguration" interface="org.opendaylight.aaa.filterchain.configuration.CustomFilterAdapterConfiguration"/>
-  <reference id="webContextSecurer" interface="org.opendaylight.aaa.web.WebContextSecurer"/>
-  <reference id="webServer" interface="org.opendaylight.aaa.web.WebServer"/>
-  <reference id="servletSupport" interface="org.opendaylight.aaa.web.servlet.ServletSupport"/>
-  <reference id="dOMActionService" interface="org.opendaylight.mdsal.dom.api.DOMActionService"/>
-  <reference id="dOMDataBroker" interface="org.opendaylight.mdsal.dom.api.DOMDataBroker"/>
-  <reference id="dOMMountPointService" interface="org.opendaylight.mdsal.dom.api.DOMMountPointService"/>
-  <reference id="dOMNotificationService" interface="org.opendaylight.mdsal.dom.api.DOMNotificationService"/>
-  <reference id="dOMRpcService" interface="org.opendaylight.mdsal.dom.api.DOMRpcService"/>
-  <reference id="dOMSchemaService" interface="org.opendaylight.mdsal.dom.api.DOMSchemaService"/>
-
-  <bean id="restconfNorthbound" class="org.opendaylight.restconf.nb.rfc8040.JaxRsNorthbound" destroy-method="close">
-    <argument ref="webServer"/>
-    <argument ref="webContextSecurer"/>
-    <argument ref="servletSupport"/>
-    <argument ref="customFilterAdapterConfiguration"/>
-    <argument ref="dOMActionService"/>
-    <argument ref="dOMDataBroker"/>
-    <argument ref="dOMMountPointService"/>
-    <argument ref="dOMNotificationService"/>
-    <argument ref="dOMRpcService"/>
-    <argument ref="dOMSchemaService"/>
-    <argument ref="databindProvider"/>
-    <argument value="${ping-executor-name-prefix}"/>
-    <argument value="${max-thread-count}"/>
-    <argument value="${maximum-fragment-length}"/>
-    <argument value="${heartbeat-interval}"/>
-    <argument value="${idle-timeout}"/>
-    <argument value="${use-sse}"/>
-  </bean>
-</blueprint>