Juggle the implementation around, allowing us to capture failure early.
JIRA: NETCONF-773
Change-Id: Ib2a587f3a73698ca2b4da1f6775dc0bdf0436be3
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
@Override
public final String toString() {
- return addToStringAttributes(MoreObjects.toStringHelper(this)).toString();
+ return addToStringAttributes(MoreObjects.toStringHelper(this).omitNullValues()).toString();
}
protected ToStringHelper addToStringAttributes(final ToStringHelper helper) {
import org.opendaylight.restconf.common.errors.RestconfFuture;
import org.opendaylight.restconf.common.errors.SettableRestconfFuture;
import org.opendaylight.restconf.nb.rfc8040.jersey.providers.ParameterAwareNormalizedNodeWriter;
+import org.opendaylight.restconf.nb.rfc8040.legacy.NormalizedNodePayload;
import org.opendaylight.restconf.nb.rfc8040.legacy.WriterParameters;
import org.opendaylight.restconf.server.api.DataGetParams;
import org.opendaylight.restconf.server.api.DataGetResult;
import org.opendaylight.restconf.server.api.DatabindContext;
import org.opendaylight.restconf.server.api.DatabindPath.Data;
+import org.opendaylight.restconf.server.api.QueryParams;
import org.opendaylight.restconf.server.spi.RpcImplementation;
+import org.opendaylight.restconf.server.spi.YangLibraryVersionResource;
import org.opendaylight.yangtools.yang.common.Empty;
import org.opendaylight.yangtools.yang.common.ErrorTag;
import org.opendaylight.yangtools.yang.common.ErrorType;
* @see DOMDataTreeReadWriteTransaction
*/
public final class MdsalRestconfStrategy extends RestconfStrategy {
- private final DOMDataBroker dataBroker;
+ private final @NonNull YangLibraryVersionResource yangLibraryVersion;
+ private final @NonNull DOMDataBroker dataBroker;
public MdsalRestconfStrategy(final DatabindContext databind, final DOMDataBroker dataBroker,
final ImmutableMap<QName, RpcImplementation> localRpcs, final @Nullable DOMRpcService rpcService,
final @Nullable DOMMountPointService mountPointService) {
super(databind, localRpcs, rpcService, actionService, sourceProvider, mountPointService);
this.dataBroker = requireNonNull(dataBroker);
+ yangLibraryVersion = YangLibraryVersionResource.of(databind);
+ }
+
+ public @NonNull RestconfFuture<NormalizedNodePayload> yangLibraryVersionGET(final QueryParams params) {
+ return yangLibraryVersion.httpGET(params);
}
@Override
level.add(qualifiedName);
currentNode = currentMixin.childByQName(qualifiedName);
}
-
return currentNode;
}
-
}
import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
import org.opendaylight.restconf.common.errors.RestconfFuture;
import org.opendaylight.restconf.nb.rfc8040.legacy.NormalizedNodePayload;
-import org.opendaylight.restconf.nb.rfc8040.legacy.WriterParameters;
import org.opendaylight.restconf.nb.rfc8040.rests.transactions.MdsalRestconfStrategy;
import org.opendaylight.restconf.nb.rfc8040.rests.transactions.RestconfStrategy;
import org.opendaylight.restconf.nb.rfc8040.rests.transactions.RestconfStrategy.StrategyAndTail;
import org.opendaylight.restconf.server.api.RestconfServer;
import org.opendaylight.restconf.server.spi.RestconfServerConfiguration;
import org.opendaylight.restconf.server.spi.RpcImplementation;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.restconf.rev170126.YangApi;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.restconf.rev170126.restconf.Restconf;
import org.opendaylight.yangtools.yang.common.Empty;
import org.opendaylight.yangtools.yang.common.ErrorTag;
import org.opendaylight.yangtools.yang.common.ErrorType;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.common.Revision;
import org.opendaylight.yangtools.yang.common.YangNames;
-import org.opendaylight.yangtools.yang.data.spi.node.ImmutableNodes;
import org.opendaylight.yangtools.yang.model.api.source.SourceIdentifier;
import org.opendaylight.yangtools.yang.model.api.source.SourceRepresentation;
import org.opendaylight.yangtools.yang.model.api.source.YangTextSource;
import org.opendaylight.yangtools.yang.model.api.source.YinTextSource;
-import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
@Component(service = RestconfServer.class, configurationPid = "org.opendaylight.restconf.server")
@Designate(ocd = RestconfServerConfiguration.class)
public final class MdsalRestconfServer implements RestconfServer, AutoCloseable {
- private static final QName YANG_LIBRARY_VERSION = QName.create(Restconf.QNAME, "yang-library-version").intern();
private static final VarHandle LOCAL_STRATEGY;
static {
@Override
public RestconfFuture<NormalizedNodePayload> yangLibraryVersionGET() {
- final var stack = SchemaInferenceStack.of(localStrategy().modelContext());
- try {
- stack.enterYangData(YangApi.NAME);
- stack.enterDataTree(Restconf.QNAME);
- stack.enterDataTree(YANG_LIBRARY_VERSION);
- } catch (IllegalArgumentException e) {
- return RestconfFuture.failed(new RestconfDocumentedException("RESTCONF is not available"));
- }
- return RestconfFuture.of(new NormalizedNodePayload(stack.toInference(),
- ImmutableNodes.leafNode(YANG_LIBRARY_VERSION,
- stack.modelContext().findModuleStatements("ietf-yang-library").iterator().next().localQNameModule()
- .revisionUnion().unionString()),
- WriterParameters.of(prettyPrint, null)));
+ return localStrategy().yangLibraryVersionGET(queryParams(QueryParameters.of()));
}
}
--- /dev/null
+/*
+ * Copyright (c) 2024 PANTHEON.tech, 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
+ */
+package org.opendaylight.restconf.server.spi;
+
+import static java.util.Objects.requireNonNull;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.opendaylight.restconf.common.errors.RestconfFuture;
+import org.opendaylight.restconf.nb.rfc8040.legacy.NormalizedNodePayload;
+import org.opendaylight.restconf.nb.rfc8040.legacy.WriterParameters;
+import org.opendaylight.restconf.server.api.QueryParams;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.restconf.rev170126.restconf.Restconf;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
+import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack.Inference;
+
+@NonNullByDefault
+record DefaultYangLibraryVersionResource(Inference leafInference, LeafNode<String> leaf)
+ implements YangLibraryVersionResource {
+ static final QName YANG_LIBRARY_VERSION = QName.create(Restconf.QNAME, "yang-library-version").intern();
+
+ DefaultYangLibraryVersionResource {
+ requireNonNull(leafInference);
+ requireNonNull(leaf);
+ }
+
+ @Override
+ public RestconfFuture<NormalizedNodePayload> httpGET(final QueryParams params) {
+ return RestconfFuture.of(new NormalizedNodePayload(leafInference, leaf,
+ WriterParameters.of(params.prettyPrint(), null)));
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2024 PANTHEON.tech, 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
+ */
+package org.opendaylight.restconf.server.spi;
+
+import static java.util.Objects.requireNonNull;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
+import org.opendaylight.restconf.common.errors.RestconfFuture;
+import org.opendaylight.restconf.nb.rfc8040.legacy.NormalizedNodePayload;
+import org.opendaylight.restconf.server.api.QueryParams;
+
+@NonNullByDefault
+record FailedYangLibraryVersionResource(RestconfDocumentedException cause) implements YangLibraryVersionResource {
+ FailedYangLibraryVersionResource {
+ requireNonNull(cause);
+ }
+
+ @Override
+ public RestconfFuture<NormalizedNodePayload> httpGET(final QueryParams params) {
+ return RestconfFuture.failed(cause);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2024 PANTHEON.tech, 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
+ */
+package org.opendaylight.restconf.server.spi;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
+import org.opendaylight.restconf.common.errors.RestconfFuture;
+import org.opendaylight.restconf.nb.rfc8040.legacy.NormalizedNodePayload;
+import org.opendaylight.restconf.server.api.DatabindContext;
+import org.opendaylight.restconf.server.api.QueryParams;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.restconf.rev170126.YangApi;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.restconf.rev170126.restconf.Restconf;
+import org.opendaylight.yangtools.yang.data.spi.node.ImmutableNodes;
+import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack;
+import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack.Inference;
+
+/**
+ * RESTCONF {@code /yang-library-version} content for a {@code GET} operation as per
+ * <a href="https://www.rfc-editor.org/rfc/rfc8040#section-3.3.3">RFC8040, section 3.3.3</a>.
+ */
+@NonNullByDefault
+public sealed interface YangLibraryVersionResource
+ permits DefaultYangLibraryVersionResource, FailedYangLibraryVersionResource {
+
+ RestconfFuture<NormalizedNodePayload> httpGET(QueryParams params);
+
+ static YangLibraryVersionResource of(final DatabindContext databind) {
+ final var modelContext = databind.modelContext();
+
+ final Inference leafInference;
+ try {
+ final var stack = SchemaInferenceStack.of(modelContext);
+ stack.enterYangData(YangApi.NAME);
+ stack.enterDataTree(Restconf.QNAME);
+ stack.enterDataTree(DefaultYangLibraryVersionResource.YANG_LIBRARY_VERSION);
+ leafInference = stack.toInference();
+ } catch (IllegalArgumentException e) {
+ return new FailedYangLibraryVersionResource(new RestconfDocumentedException(
+ "yang-library-version is not available", e));
+ }
+
+ final var it = modelContext.findModuleStatements("ietf-yang-library").iterator();
+ return it.hasNext()
+ ? new DefaultYangLibraryVersionResource(leafInference,
+ ImmutableNodes.leafNode(DefaultYangLibraryVersionResource.YANG_LIBRARY_VERSION,
+ it.next().localQNameModule().revisionUnion().unionString()))
+ : new FailedYangLibraryVersionResource(new RestconfDocumentedException("No ietf-yang-library present"));
+ }
+}