From a0f80753a3b69798d6c169cf4b8419b04cb03e03 Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Thu, 14 Sep 2023 12:20:01 +0200 Subject: [PATCH] Eliminate NormalizedNodePayload.headers Convert the only user working with this facility to return a Response, where it can set the location header directly. JIRA: NETCONF-1102 Change-Id: Ice969014cf5532ea2cb93d1939cad5edf8c76335 Signed-off-by: Robert Varga --- .../AbstractNormalizedNodeBodyWriter.java | 5 --- .../rfc8040/legacy/NormalizedNodePayload.java | 32 +++---------------- .../RestconfStreamsSubscriptionService.java | 6 ++-- ...estconfStreamsSubscriptionServiceImpl.java | 25 ++++++++------- ...onfStreamsSubscriptionServiceImplTest.java | 19 +++++------ 5 files changed, 29 insertions(+), 58 deletions(-) diff --git a/restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/jersey/providers/AbstractNormalizedNodeBodyWriter.java b/restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/jersey/providers/AbstractNormalizedNodeBodyWriter.java index 56da396d34..2107bf8531 100644 --- a/restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/jersey/providers/AbstractNormalizedNodeBodyWriter.java +++ b/restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/jersey/providers/AbstractNormalizedNodeBodyWriter.java @@ -40,11 +40,6 @@ abstract class AbstractNormalizedNodeBodyWriter implements MessageBodyWriter headers; private final @NonNull QueryParameters writerParameters; private final @NonNull Inference inference; private final NormalizedNode data; private NormalizedNodePayload(final Inference inference, final NormalizedNode data, - final QueryParameters writerParameters, final ImmutableMap headers) { + final QueryParameters writerParameters) { this.inference = requireNonNull(inference); this.data = data; this.writerParameters = requireNonNull(writerParameters); - this.headers = requireNonNull(headers); } public static @NonNull NormalizedNodePayload empty(final Inference inference) { - return new NormalizedNodePayload(inference, null, QueryParameters.empty(), ImmutableMap.of()); + return new NormalizedNodePayload(inference, null, QueryParameters.empty()); } public static @NonNull NormalizedNodePayload of(final Inference inference, final NormalizedNode data) { - return new NormalizedNodePayload(inference, requireNonNull(data), QueryParameters.empty(), ImmutableMap.of()); + return new NormalizedNodePayload(inference, requireNonNull(data), QueryParameters.empty()); } public static @NonNull NormalizedNodePayload ofNullable(final Inference inference, final NormalizedNode data) { return data == null ? empty(inference) : of(inference, data); } - // FIXME: can we get rid of this, please? Whoever is using this should be setting a Response instead - @Deprecated - public static @NonNull NormalizedNodePayload ofLocation(final Inference inference, final NodeIdentifier leafId, - final URI location) { - return new NormalizedNodePayload(inference, ImmutableNodes.leafNode(leafId, location.toString()), - QueryParameters.empty(), ImmutableMap.of("Location", location)); - } - public static Object ofReadData(final Inference inference, final NormalizedNode data, final QueryParameters parameters) { - return new NormalizedNodePayload(inference, requireNonNull(data), parameters, ImmutableMap.of()); + return new NormalizedNodePayload(inference, requireNonNull(data), parameters); } public @NonNull Inference inference() { @@ -69,16 +55,6 @@ public final class NormalizedNodePayload { return data; } - /** - * Return headers response headers. - * - * @return map of headers - */ - // FIXME: this is only used for redirect on subscribe - public @NonNull ImmutableMap getNewHeaders() { - return headers; - } - public @NonNull QueryParameters getWriterParameters() { return writerParameters; } diff --git a/restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/services/api/RestconfStreamsSubscriptionService.java b/restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/services/api/RestconfStreamsSubscriptionService.java index 3530725dd5..072faf8065 100644 --- a/restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/services/api/RestconfStreamsSubscriptionService.java +++ b/restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/services/api/RestconfStreamsSubscriptionService.java @@ -12,6 +12,7 @@ import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.core.Context; +import javax.ws.rs.core.Response; import javax.ws.rs.core.UriInfo; import org.opendaylight.restconf.nb.rfc8040.legacy.NormalizedNodePayload; import org.opendaylight.restconf.nb.rfc8040.rests.utils.RestconfStreamsConstants; @@ -25,13 +26,12 @@ public interface RestconfStreamsSubscriptionService { * * @param identifier name of stream * @param uriInfo URI info - * @return {@link NormalizedNodePayload} + * @return a response containing {@link NormalizedNodePayload} */ // FIXME: this is a REST violation: GET does not transfer state! This should work in terms of // https://www.rfc-editor.org/rfc/rfc8639#section-2.4, i.e. when we have that, aggressively deprecate // and remove this special case. Besides it routes to a very bad thing in RestconfDataServiceImpl @GET @Path("data/" + RestconfStreamsConstants.STREAMS_PATH + "/stream/{identifier:.+}") - NormalizedNodePayload subscribeToStream(@Encoded @PathParam("identifier") String identifier, - @Context UriInfo uriInfo); + Response subscribeToStream(@Encoded @PathParam("identifier") String identifier, @Context UriInfo uriInfo); } diff --git a/restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/RestconfStreamsSubscriptionServiceImpl.java b/restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/RestconfStreamsSubscriptionServiceImpl.java index 75ff3437d6..c4162650bd 100644 --- a/restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/RestconfStreamsSubscriptionServiceImpl.java +++ b/restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/RestconfStreamsSubscriptionServiceImpl.java @@ -9,11 +9,11 @@ package org.opendaylight.restconf.nb.rfc8040.rests.services.impl; import java.net.URI; import javax.ws.rs.Path; +import javax.ws.rs.core.Response; import javax.ws.rs.core.UriInfo; import org.opendaylight.mdsal.dom.api.DOMDataBroker; import org.opendaylight.mdsal.dom.api.DOMNotificationService; import org.opendaylight.restconf.common.errors.RestconfDocumentedException; -import org.opendaylight.restconf.nb.rfc8040.NotificationQueryParams; import org.opendaylight.restconf.nb.rfc8040.databind.DatabindProvider; import org.opendaylight.restconf.nb.rfc8040.databind.jaxrs.QueryParams; import org.opendaylight.restconf.nb.rfc8040.legacy.NormalizedNodePayload; @@ -23,6 +23,7 @@ import org.opendaylight.restconf.nb.rfc8040.streams.StreamsConfiguration; import org.opendaylight.yang.gen.v1.subscribe.to.notification.rev161028.Notifi; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier; +import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes; import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack.Inference; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -56,25 +57,27 @@ public class RestconfStreamsSubscriptionServiceImpl implements RestconfStreamsSu } @Override - public NormalizedNodePayload subscribeToStream(final String identifier, final UriInfo uriInfo) { - final NotificationQueryParams params = QueryParams.newNotificationQueryParams(uriInfo); + public Response subscribeToStream(final String identifier, final UriInfo uriInfo) { + final var params = QueryParams.newNotificationQueryParams(uriInfo); - final URI response; + final URI location; if (identifier.contains(RestconfStreamsConstants.DATA_SUBSCRIPTION)) { - response = streamUtils.subscribeToDataStream(identifier, uriInfo, params, handlersHolder); + location = streamUtils.subscribeToDataStream(identifier, uriInfo, params, handlersHolder); } else if (identifier.contains(RestconfStreamsConstants.NOTIFICATION_STREAM)) { - response = streamUtils.subscribeToYangStream(identifier, uriInfo, params, handlersHolder); + location = streamUtils.subscribeToYangStream(identifier, uriInfo, params, handlersHolder); } else { final String msg = "Bad type of notification of sal-remote"; LOG.warn(msg); throw new RestconfDocumentedException(msg); } - // prepare node with value of location - return NormalizedNodePayload.ofLocation( - Inference.ofDataTreePath(handlersHolder.getDatabindProvider().currentContext().modelContext(), - Notifi.QNAME, LOCATION_QNAME), - LOCATION_NODEID, response); + return Response.ok() + .location(location) + .entity(NormalizedNodePayload.of( + Inference.ofDataTreePath(handlersHolder.getDatabindProvider().currentContext().modelContext(), + Notifi.QNAME, LOCATION_QNAME), + ImmutableNodes.leafNode(LOCATION_NODEID, location.toString()))) + .build(); } /** diff --git a/restconf/restconf-nb/src/test/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/RestconfStreamsSubscriptionServiceImplTest.java b/restconf/restconf-nb/src/test/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/RestconfStreamsSubscriptionServiceImplTest.java index 0579dddabd..f842690617 100644 --- a/restconf/restconf-nb/src/test/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/RestconfStreamsSubscriptionServiceImplTest.java +++ b/restconf/restconf-nb/src/test/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/RestconfStreamsSubscriptionServiceImplTest.java @@ -36,7 +36,6 @@ import org.opendaylight.restconf.common.errors.RestconfDocumentedException; import org.opendaylight.restconf.nb.rfc8040.URLConstants; import org.opendaylight.restconf.nb.rfc8040.databind.DatabindContext; import org.opendaylight.restconf.nb.rfc8040.databind.DatabindProvider; -import org.opendaylight.restconf.nb.rfc8040.legacy.NormalizedNodePayload; import org.opendaylight.restconf.nb.rfc8040.streams.StreamsConfiguration; import org.opendaylight.restconf.nb.rfc8040.streams.listeners.ListenerAdapter; import org.opendaylight.restconf.nb.rfc8040.streams.listeners.ListenersBroker; @@ -120,14 +119,13 @@ public class RestconfStreamsSubscriptionServiceImplTest { IdentifierCodec.deserialize("toaster:toaster/toasterStatus", MODEL_CONTEXT), "data-change-event-subscription/toaster:toaster/toasterStatus/datastore=OPERATIONAL/scope=ONE", NotificationOutputType.XML); - final RestconfStreamsSubscriptionServiceImpl streamsSubscriptionService = - new RestconfStreamsSubscriptionServiceImpl(dataBroker, notificationService, databindProvider, - configurationSse); - final NormalizedNodePayload response = streamsSubscriptionService.subscribeToStream( + final var streamsSubscriptionService = new RestconfStreamsSubscriptionServiceImpl(dataBroker, + notificationService, databindProvider, configurationSse); + final var response = streamsSubscriptionService.subscribeToStream( "data-change-event-subscription/toaster:toaster/toasterStatus/datastore=OPERATIONAL/scope=ONE", uriInfo); assertEquals("http://localhost:8181/" + URLConstants.BASE_PATH + "/" + URLConstants.SSE_SUBPATH + "/data-change-event-subscription/toaster:toaster/toasterStatus/datastore=OPERATIONAL/scope=ONE", - response.getNewHeaders().get("Location").toString()); + response.getLocation().toString()); } @Test @@ -136,14 +134,13 @@ public class RestconfStreamsSubscriptionServiceImplTest { IdentifierCodec.deserialize("toaster:toaster/toasterStatus", MODEL_CONTEXT), "data-change-event-subscription/toaster:toaster/toasterStatus/datastore=OPERATIONAL/scope=ONE", NotificationOutputType.XML); - final RestconfStreamsSubscriptionServiceImpl streamsSubscriptionService = - new RestconfStreamsSubscriptionServiceImpl(dataBroker, notificationService, databindProvider, - configurationWs); - final NormalizedNodePayload response = streamsSubscriptionService.subscribeToStream( + final var streamsSubscriptionService = new RestconfStreamsSubscriptionServiceImpl(dataBroker, + notificationService, databindProvider, configurationWs); + final var response = streamsSubscriptionService.subscribeToStream( "data-change-event-subscription/toaster:toaster/toasterStatus/datastore=OPERATIONAL/scope=ONE", uriInfo); assertEquals("ws://localhost:8181/" + URLConstants.BASE_PATH + "/data-change-event-subscription/toaster:toaster/toasterStatus/datastore=OPERATIONAL/scope=ONE", - response.getNewHeaders().get("Location").toString()); + response.getLocation().toString()); } @Test -- 2.36.6