Rename RestconfRequestDispatcher to APIResource 31/113831/7
authorRobert Varga <robert.varga@pantheon.tech>
Fri, 4 Oct 2024 12:49:46 +0000 (14:49 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Mon, 7 Oct 2024 13:24:48 +0000 (15:24 +0200)
At this point there is only a teensy-tiny bit of the old 'dispatch()'
logic living in RestconfRequestDispatcher and it now really acts as a
the root of RESTCONF -- i.e. what RFC8040 calls 'API Resource'. Rename
it to match its function.

JIRA: NETCONF-1379
Change-Id: I18437f5346ff6c1c179a477514001a2c4bb692fa
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
protocol/restconf-server/src/main/java/org/opendaylight/restconf/server/APIResource.java [moved from protocol/restconf-server/src/main/java/org/opendaylight/restconf/server/RestconfRequestDispatcher.java with 71% similarity]
protocol/restconf-server/src/main/java/org/opendaylight/restconf/server/AbstractResource.java
protocol/restconf-server/src/main/java/org/opendaylight/restconf/server/PreparedRequest.java
protocol/restconf-server/src/main/java/org/opendaylight/restconf/server/RestconfSession.java
protocol/restconf-server/src/main/java/org/opendaylight/restconf/server/RestconfTransportChannelListener.java
protocol/restconf-server/src/test/java/org/opendaylight/restconf/server/AbstractRequestProcessorTest.java

similarity index 71%
rename from protocol/restconf-server/src/main/java/org/opendaylight/restconf/server/RestconfRequestDispatcher.java
rename to protocol/restconf-server/src/main/java/org/opendaylight/restconf/server/APIResource.java
index 8dafceff123a85826f85b2e0a5522e55d5bb37b6..e9147ed0919b14595e41df8b5edf2f33968950e9 100644 (file)
@@ -18,24 +18,29 @@ import java.util.Map;
 import java.util.stream.Collectors;
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
 import org.opendaylight.restconf.api.query.PrettyPrintParam;
 import org.opendaylight.restconf.server.api.RestconfServer;
 import org.opendaylight.restconf.server.spi.ErrorTagMapping;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-// FIXME: rename to APIResource
-final class RestconfRequestDispatcher extends AbstractResource {
-    private static final Logger LOG = LoggerFactory.getLogger(RestconfRequestDispatcher.class);
+/**
+ * RESTCONF API resource, as defined in
+ * <a href="https://www.rfc-editor.org/rfc/rfc8040#section-3.3>RFC8040, section 3.3</a>.
+ */
+final class APIResource extends AbstractResource {
+    private static final Logger LOG = LoggerFactory.getLogger(APIResource.class);
 
     private final Map<String, AbstractResource> resources;
-    private final @NonNull PrincipalService principalService;
+    private final PrincipalService principalService;
     private final @NonNull String firstSegment;
-    private final @NonNull List<String> otherSegments;
+    private final List<String> otherSegments;
 
-    RestconfRequestDispatcher(final RestconfServer server, final PrincipalService principalService,
-            final List<String> segments, final String restconfPath, final ErrorTagMapping errorTagMapping,
-            final MessageEncoding defaultEncoding, final PrettyPrintParam defaultPrettyPrint) {
+    @NonNullByDefault
+    APIResource(final RestconfServer server, final PrincipalService principalService, final List<String> segments,
+            final String restconfPath, final ErrorTagMapping errorTagMapping, final MessageEncoding defaultEncoding,
+            final PrettyPrintParam defaultPrettyPrint) {
         super(new EndpointInvariants(server, defaultPrettyPrint, errorTagMapping, defaultEncoding,
             URI.create(requireNonNull(restconfPath))));
         this.principalService = requireNonNull(principalService);
@@ -63,11 +68,7 @@ final class RestconfRequestDispatcher extends AbstractResource {
         }
 
         if (!peeler.hasNext()) {
-            // FIXME: we are rejecting requests to '{+restconf}', which matches JAX-RS server behaviour, but is not
-            //        correct: we should be reporting the entire API Resource, as described in
-            //        https://www.rfc-editor.org/rfc/rfc8040#section-3.3
-            LOG.debug("Not servicing root request");
-            return NOT_FOUND;
+            return prepare(method, targetUri, headers, principal);
         }
 
         final var segment = peeler.next();
@@ -80,6 +81,16 @@ final class RestconfRequestDispatcher extends AbstractResource {
         return NOT_FOUND;
     }
 
+    // FIXME: we are rejecting requests to '{+restconf}', which matches JAX-RS server behaviour, but is not correct:
+    //        we should be reporting the entire API Resource, as described in
+    //        https://www.rfc-editor.org/rfc/rfc8040#section-3.3
+    @NonNullByDefault
+    private static PreparedRequest prepare(final ImplementedMethod method, final URI targetUri,
+            final HttpHeaders headers, final @Nullable Principal principal) {
+        LOG.debug("Not servicing root request");
+        return NOT_FOUND;
+    }
+
     String firstSegment() {
         return firstSegment;
     }
index c00e19bfdc28096faa4362864aaefb8045844560..c55911be644658f7e9ce11571ae169c60f9be8db 100644 (file)
@@ -36,7 +36,7 @@ import org.slf4j.LoggerFactory;
  * point in the past.
  */
 @NonNullByDefault
-abstract sealed class AbstractResource permits AbstractLeafResource, RestconfRequestDispatcher {
+abstract sealed class AbstractResource permits AbstractLeafResource, APIResource {
     private static final Logger LOG = LoggerFactory.getLogger(AbstractResource.class);
 
     static final CompletedRequest METHOD_NOT_ALLOWED_READ_ONLY =
index d241130ad71843fc935dea771292f8e674ba3b18..4a2b1a7ba3f9943d0954384dd269fe764aaaff37 100644 (file)
@@ -8,9 +8,8 @@
 package org.opendaylight.restconf.server;
 
 /**
- * The result of
- * {@link RestconfRequestDispatcher#prepare(java.net.URI, SegmentPeeler, io.netty.handler.codec.http.HttpRequest)}. This
- * can either be a {@link CompletedRequest} or a {@link PendingRequest}.
+ * The result of {@link AbstractResource#prepare(java.net.URI, SegmentPeeler, io.netty.handler.codec.http.HttpRequest)}.
+ * This can either be a {@link CompletedRequest} or a {@link PendingRequest}.
  */
 sealed interface PreparedRequest permits CompletedRequest, PendingRequest {
     // Nothing else
index 0e80e2f06cd88d07de5983213371fea3de2fdc55..fc1d7252fa747efd2bc28ecfe6dbe1338357f42b 100644 (file)
@@ -60,15 +60,14 @@ final class RestconfSession extends SimpleChannelInboundHandler<FullHttpRequest>
         Arrays.stream(ImplementedMethod.values())
             .collect(Collectors.toUnmodifiableMap(ImplementedMethod::httpMethod, Function.identity()));
 
-    private final RestconfRequestDispatcher dispatcher;
     private final WellKnownResources wellKnown;
+    private final APIResource apiResource;
     private final HttpScheme scheme;
 
-    RestconfSession(final WellKnownResources wellKnown, final RestconfRequestDispatcher dispatcher,
-            final HttpScheme scheme) {
+    RestconfSession(final WellKnownResources wellKnown, final APIResource apiResource, final HttpScheme scheme) {
         super(FullHttpRequest.class, false);
         this.wellKnown = requireNonNull(wellKnown);
-        this.dispatcher = requireNonNull(dispatcher);
+        this.apiResource = requireNonNull(apiResource);
         this.scheme = requireNonNull(scheme);
     }
 
@@ -177,7 +176,7 @@ final class RestconfSession extends SimpleChannelInboundHandler<FullHttpRequest>
             respond(ctx, streamId, wellKnown.request(version, method, peeler));
             return;
         }
-        if (!segment.equals(dispatcher.firstSegment())) {
+        if (!segment.equals(apiResource.firstSegment())) {
             // Does not match the dispatcher -- we are done now
             LOG.debug("No resource for {}", requestUri);
             msg.release();
@@ -189,7 +188,7 @@ final class RestconfSession extends SimpleChannelInboundHandler<FullHttpRequest>
         //        - invoke dispatcher.prepare() from here first
         //        - handle CompletedRequest to synchronous dispatch just like the above two cases, as it is that simple
 
-        dispatcher.dispatch(peeler, method, targetUri, msg, new RestconfRequest() {
+        apiResource.dispatch(peeler, method, targetUri, msg, new RestconfRequest() {
             @Override
             public void onSuccess(final FullHttpResponse response) {
                 msg.release();
index d96ef1da0837ff67a31244c8e79ff03d1ecdb742..4d316f13bd9c3c40f201294a33ad745c4777bf37 100644 (file)
@@ -27,8 +27,8 @@ final class RestconfTransportChannelListener implements TransportChannelListener
 
     private final RestconfStream.Registry streamRegistry;
     private final NettyEndpointConfiguration configuration;
-    private final RestconfRequestDispatcher dispatcher;
     private final WellKnownResources wellKnown;
+    private final APIResource apiResource;
     private final String restconf;
 
     RestconfTransportChannelListener(final RestconfServer server, final RestconfStream.Registry streamRegistry,
@@ -44,7 +44,7 @@ final class RestconfTransportChannelListener implements TransportChannelListener
         }
         restconf = sb.toString();
         wellKnown = new WellKnownResources(restconf);
-        dispatcher = new RestconfRequestDispatcher(server, principalService, apiRootPath, sb.append('/').toString(),
+        apiResource = new APIResource(server, principalService, apiRootPath, sb.append('/').toString(),
             configuration.errorTagMapping(), configuration.defaultEncoding(), configuration.prettyPrint());
 
         LOG.info("Initialized with service {}", server.getClass());
@@ -59,7 +59,7 @@ final class RestconfTransportChannelListener implements TransportChannelListener
                 new RestconfStreamService(streamRegistry, restconf, configuration.errorTagMapping(),
                     configuration.defaultEncoding(), configuration.prettyPrint()),
                 configuration.sseMaximumFragmentLength().toJava(), configuration.sseHeartbeatIntervalMillis().toJava()),
-            new RestconfSession(wellKnown, dispatcher, channel.scheme()));
+            new RestconfSession(wellKnown, apiResource, channel.scheme()));
     }
 
     @Override
index 05a5f5090265895f7143ec9ec5b5af7cb1e69828..14e96a34af1ea70fd3f6404e18a486fa7b659f1d 100644 (file)
@@ -69,13 +69,13 @@ public class AbstractRequestProcessorTest {
     @Captor
     private ArgumentCaptor<FullHttpResponse> responseCaptor;
 
-    private RestconfRequestDispatcher dispatcher;
+    private APIResource apiResource;
 
     @BeforeEach
     void beforeEach() {
         doReturn(null).when(principalService).acquirePrincipal(any());
-        dispatcher = new RestconfRequestDispatcher(server, principalService, List.of("rests"), "/rests/",
-            ERROR_TAG_MAPPING, MessageEncoding.JSON, PRETTY_PRINT);
+        apiResource = new APIResource(server, principalService, List.of("rests"), "/rests/", ERROR_TAG_MAPPING,
+            MessageEncoding.JSON, PRETTY_PRINT);
     }
 
     protected FullHttpResponse dispatch(final FullHttpRequest request) {
@@ -83,7 +83,7 @@ public class AbstractRequestProcessorTest {
         final var peeler = new SegmentPeeler(targetUri);
         assertEquals("rests", peeler.next());
         final var nettyMethod = request.method();
-        dispatcher.dispatch(peeler, switch (nettyMethod.name()) {
+        apiResource.dispatch(peeler, switch (nettyMethod.name()) {
             case "DELETE" -> ImplementedMethod.DELETE;
             case "GET" -> ImplementedMethod.GET;
             case "OPTIONS" -> ImplementedMethod.OPTIONS;