Search in sources :

Example 1 with DepthParam

use of org.opendaylight.restconf.nb.rfc8040.DepthParam in project netconf by opendaylight.

the class JsonNormalizedNodeBodyWriter method writeNormalizedNode.

private static void writeNormalizedNode(final JsonWriter jsonWriter, final SchemaPath path, final InstanceIdentifierContext<SchemaNode> context, final NormalizedNode data, final DepthParam depth, final List<Set<QName>> fields) throws IOException {
    final RestconfNormalizedNodeWriter nnWriter;
    if (context.getSchemaNode() instanceof RpcDefinition) {
        /*
             *  RpcDefinition is not supported as initial codec in JSONStreamWriter,
             *  so we need to emit initial output declaration..
             */
        final RpcDefinition rpc = (RpcDefinition) context.getSchemaNode();
        final SchemaPath rpcPath = SchemaPath.of(Absolute.of(rpc.getQName(), rpc.getOutput().getQName()));
        nnWriter = createNormalizedNodeWriter(context, rpcPath, jsonWriter, depth, fields);
        final Module module = context.getSchemaContext().findModule(data.getIdentifier().getNodeType().getModule()).get();
        jsonWriter.name(module.getName() + ":output");
        jsonWriter.beginObject();
        writeChildren(nnWriter, (ContainerNode) data);
        jsonWriter.endObject();
    } else if (context.getSchemaNode() instanceof ActionDefinition) {
        /*
             *  ActionDefinition is not supported as initial codec in JSONStreamWriter,
             *  so we need to emit initial output declaration..
             */
        final ActionDefinition actDef = (ActionDefinition) context.getSchemaNode();
        final List<QName> qNames = context.getInstanceIdentifier().getPathArguments().stream().filter(arg -> !(arg instanceof YangInstanceIdentifier.NodeIdentifierWithPredicates)).filter(arg -> !(arg instanceof YangInstanceIdentifier.AugmentationIdentifier)).map(PathArgument::getNodeType).collect(Collectors.toList());
        qNames.add(actDef.getQName());
        qNames.add(actDef.getOutput().getQName());
        final SchemaPath actPath = SchemaPath.of(Absolute.of(qNames));
        nnWriter = createNormalizedNodeWriter(context, actPath, jsonWriter, depth, fields);
        final Module module = context.getSchemaContext().findModule(data.getIdentifier().getNodeType().getModule()).get();
        jsonWriter.name(module.getName() + ":output");
        jsonWriter.beginObject();
        writeChildren(nnWriter, (ContainerNode) data);
        jsonWriter.endObject();
    } else {
        if (SchemaPath.ROOT.equals(path)) {
            nnWriter = createNormalizedNodeWriter(context, path, jsonWriter, depth, fields);
        } else {
            nnWriter = createNormalizedNodeWriter(context, path.getParent(), jsonWriter, depth, fields);
        }
        if (data instanceof MapEntryNode) {
            // Restconf allows returning one list item. We need to wrap it
            // in map node in order to serialize it properly
            nnWriter.write(ImmutableNodes.mapNodeBuilder(data.getIdentifier().getNodeType()).withChild((MapEntryNode) data).build());
        } else {
            nnWriter.write(data);
        }
    }
    nnWriter.flush();
}
Also used : JSONNormalizedNodeStreamWriter(org.opendaylight.yangtools.yang.data.codec.gson.JSONNormalizedNodeStreamWriter) JSONCodecFactorySupplier(org.opendaylight.yangtools.yang.data.codec.gson.JSONCodecFactorySupplier) SchemaPath(org.opendaylight.yangtools.yang.model.api.SchemaPath) Produces(javax.ws.rs.Produces) Provider(javax.ws.rs.ext.Provider) InstanceIdentifierContext(org.opendaylight.restconf.common.context.InstanceIdentifierContext) RpcDefinition(org.opendaylight.yangtools.yang.model.api.RpcDefinition) NormalizedNodePayload(org.opendaylight.restconf.nb.rfc8040.legacy.NormalizedNodePayload) XMLNamespace(org.opendaylight.yangtools.yang.common.XMLNamespace) JsonWriterFactory(org.opendaylight.yangtools.yang.data.codec.gson.JsonWriterFactory) Absolute(org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute) MediaType(javax.ws.rs.core.MediaType) Map(java.util.Map) OutputStreamWriter(java.io.OutputStreamWriter) YangInstanceIdentifier(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier) JsonWriter(com.google.gson.stream.JsonWriter) ContainerNode(org.opendaylight.yangtools.yang.data.api.schema.ContainerNode) OutputStream(java.io.OutputStream) DepthParam(org.opendaylight.restconf.nb.rfc8040.DepthParam) Module(org.opendaylight.yangtools.yang.model.api.Module) SchemaInferenceStack(org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack) Set(java.util.Set) IOException(java.io.IOException) DataContainerChild(org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild) Collectors(java.util.stream.Collectors) StandardCharsets(java.nio.charset.StandardCharsets) QName(org.opendaylight.yangtools.yang.common.QName) MediaTypes(org.opendaylight.restconf.nb.rfc8040.MediaTypes) RestconfNormalizedNodeWriter(org.opendaylight.restconf.nb.rfc8040.jersey.providers.api.RestconfNormalizedNodeWriter) SchemaNode(org.opendaylight.yangtools.yang.model.api.SchemaNode) MultivaluedMap(javax.ws.rs.core.MultivaluedMap) List(java.util.List) PathArgument(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument) Type(java.lang.reflect.Type) NormalizedNodeStreamWriter(org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter) ImmutableNodes(org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes) Annotation(java.lang.annotation.Annotation) JSONCodecFactory(org.opendaylight.yangtools.yang.data.codec.gson.JSONCodecFactory) WebApplicationException(javax.ws.rs.WebApplicationException) ActionDefinition(org.opendaylight.yangtools.yang.model.api.ActionDefinition) MapEntryNode(org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode) NormalizedNode(org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode) RestconfNormalizedNodeWriter(org.opendaylight.restconf.nb.rfc8040.jersey.providers.api.RestconfNormalizedNodeWriter) RpcDefinition(org.opendaylight.yangtools.yang.model.api.RpcDefinition) MapEntryNode(org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode) YangInstanceIdentifier(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier) ActionDefinition(org.opendaylight.yangtools.yang.model.api.ActionDefinition) SchemaPath(org.opendaylight.yangtools.yang.model.api.SchemaPath) List(java.util.List) ContainerNode(org.opendaylight.yangtools.yang.data.api.schema.ContainerNode) PathArgument(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument) Module(org.opendaylight.yangtools.yang.model.api.Module)

Example 2 with DepthParam

use of org.opendaylight.restconf.nb.rfc8040.DepthParam in project netconf by opendaylight.

the class QueryParamsTest method parseUriParametersUserDefinedTest.

/**
 * Test of parsing user defined parameters from URI request.
 */
@Test
public void parseUriParametersUserDefinedTest() {
    final QName containerChild = QName.create("ns", "container-child");
    final var parameters = new MultivaluedHashMap<String, String>();
    parameters.putSingle("content", "config");
    parameters.putSingle("depth", "10");
    parameters.putSingle("fields", "container-child");
    final var params = assertParams(QueryParams::newReadDataParams, parameters);
    // content
    assertEquals(ContentParam.CONFIG, params.content());
    // depth
    final DepthParam depth = params.depth();
    assertNotNull(depth);
    assertEquals(10, depth.value());
    // fields
    assertNotNull(params.fields());
    // fields for write filtering
    final var containerSchema = mock(ContainerSchemaNode.class);
    doReturn(QName.create(containerChild, "container")).when(containerSchema).getQName();
    final var containerChildSchema = mock(LeafSchemaNode.class);
    doReturn(containerChild).when(containerChildSchema).getQName();
    doReturn(containerChildSchema).when(containerSchema).dataChildByName(containerChild);
    final var context = mock(InstanceIdentifierContext.class);
    final var modelContext = mock(EffectiveModelContext.class);
    doReturn(modelContext).when(context).getSchemaContext();
    doReturn(containerSchema).when(context).getSchemaNode();
    final QueryParameters queryParameters = QueryParams.newQueryParameters(params, context);
    final List<Set<QName>> fields = queryParameters.fields();
    assertNotNull(fields);
    assertEquals(1, fields.size());
    assertEquals(Set.of(containerChild), fields.get(0));
}
Also used : MultivaluedHashMap(javax.ws.rs.core.MultivaluedHashMap) Set(java.util.Set) QName(org.opendaylight.yangtools.yang.common.QName) QueryParameters(org.opendaylight.restconf.nb.rfc8040.legacy.QueryParameters) DepthParam(org.opendaylight.restconf.nb.rfc8040.DepthParam) Test(org.junit.Test)

Example 3 with DepthParam

use of org.opendaylight.restconf.nb.rfc8040.DepthParam in project netconf by opendaylight.

the class XmlNormalizedNodeBodyWriter method writeNormalizedNode.

private static void writeNormalizedNode(final XMLStreamWriter xmlWriter, final InstanceIdentifierContext<?> pathContext, final NormalizedNode data, final DepthParam depth, final List<Set<QName>> fields) throws IOException {
    final RestconfNormalizedNodeWriter nnWriter;
    final EffectiveModelContext schemaCtx = pathContext.getSchemaContext();
    if (pathContext.getSchemaNode() instanceof RpcDefinition) {
        /*
             *  RpcDefinition is not supported as initial codec in XMLStreamWriter,
             *  so we need to emit initial output declaration..
             */
        final RpcDefinition rpc = (RpcDefinition) pathContext.getSchemaNode();
        final SchemaPath rpcPath = SchemaPath.of(Absolute.of(rpc.getQName(), rpc.getOutput().getQName()));
        nnWriter = createNormalizedNodeWriter(xmlWriter, schemaCtx, rpcPath, depth, fields);
        writeElements(xmlWriter, nnWriter, (ContainerNode) data);
    } else if (pathContext.getSchemaNode() instanceof ActionDefinition) {
        /*
             *  ActionDefinition is not supported as initial codec in XMLStreamWriter,
             *  so we need to emit initial output declaration..
             */
        final ActionDefinition actDef = (ActionDefinition) pathContext.getSchemaNode();
        final List<QName> qNames = pathContext.getInstanceIdentifier().getPathArguments().stream().filter(arg -> !(arg instanceof YangInstanceIdentifier.NodeIdentifierWithPredicates)).filter(arg -> !(arg instanceof YangInstanceIdentifier.AugmentationIdentifier)).map(PathArgument::getNodeType).collect(Collectors.toList());
        qNames.add(actDef.getQName());
        qNames.add(actDef.getOutput().getQName());
        final SchemaPath actPath = SchemaPath.of(Absolute.of(qNames));
        nnWriter = createNormalizedNodeWriter(xmlWriter, schemaCtx, actPath, depth, fields);
        writeElements(xmlWriter, nnWriter, (ContainerNode) data);
    } else {
        final boolean isRoot = pathContext.getInstanceIdentifier().isEmpty();
        if (isRoot) {
            nnWriter = createNormalizedNodeWriter(xmlWriter, schemaCtx, SchemaPath.ROOT, depth, fields);
        } else {
            final List<QName> qNames = pathContext.getInstanceIdentifier().getPathArguments().stream().filter(arg -> !(arg instanceof YangInstanceIdentifier.NodeIdentifierWithPredicates)).filter(arg -> !(arg instanceof YangInstanceIdentifier.AugmentationIdentifier)).map(PathArgument::getNodeType).collect(Collectors.toList());
            final SchemaPath path = SchemaPath.of(Absolute.of(qNames));
            nnWriter = createNormalizedNodeWriter(xmlWriter, schemaCtx, path.getParent(), depth, fields);
        }
        if (data instanceof MapEntryNode) {
            // Restconf allows returning one list item. We need to wrap it
            // in map node in order to serialize it properly
            nnWriter.write(ImmutableNodes.mapNodeBuilder(data.getIdentifier().getNodeType()).addChild((MapEntryNode) data).build());
        } else if (isRoot) {
            if (data instanceof ContainerNode && ((ContainerNode) data).isEmpty()) {
                writeEmptyDataNode(xmlWriter, data);
            } else {
                writeAndWrapInDataNode(xmlWriter, nnWriter, data);
            }
        } else {
            nnWriter.write(data);
        }
    }
    nnWriter.flush();
}
Also used : SchemaPath(org.opendaylight.yangtools.yang.model.api.SchemaPath) Produces(javax.ws.rs.Produces) Provider(javax.ws.rs.ext.Provider) InstanceIdentifierContext(org.opendaylight.restconf.common.context.InstanceIdentifierContext) RpcDefinition(org.opendaylight.yangtools.yang.model.api.RpcDefinition) NormalizedNodePayload(org.opendaylight.restconf.nb.rfc8040.legacy.NormalizedNodePayload) Absolute(org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute) MediaType(javax.ws.rs.core.MediaType) Map(java.util.Map) XMLStreamException(javax.xml.stream.XMLStreamException) YangInstanceIdentifier(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier) XMLStreamWriter(javax.xml.stream.XMLStreamWriter) XMLConstants(javax.xml.XMLConstants) ContainerNode(org.opendaylight.yangtools.yang.data.api.schema.ContainerNode) OutputStream(java.io.OutputStream) DepthParam(org.opendaylight.restconf.nb.rfc8040.DepthParam) Set(java.util.Set) IOException(java.io.IOException) EffectiveModelContext(org.opendaylight.yangtools.yang.model.api.EffectiveModelContext) Collectors(java.util.stream.Collectors) StandardCharsets(java.nio.charset.StandardCharsets) QName(org.opendaylight.yangtools.yang.common.QName) FactoryConfigurationError(javax.xml.stream.FactoryConfigurationError) MediaTypes(org.opendaylight.restconf.nb.rfc8040.MediaTypes) RestconfNormalizedNodeWriter(org.opendaylight.restconf.nb.rfc8040.jersey.providers.api.RestconfNormalizedNodeWriter) XMLStreamNormalizedNodeStreamWriter(org.opendaylight.yangtools.yang.data.codec.xml.XMLStreamNormalizedNodeStreamWriter) MultivaluedMap(javax.ws.rs.core.MultivaluedMap) XMLOutputFactory(javax.xml.stream.XMLOutputFactory) List(java.util.List) IndentingXMLStreamWriter(javanet.staxutils.IndentingXMLStreamWriter) PathArgument(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument) Type(java.lang.reflect.Type) ImmutableNodes(org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes) Annotation(java.lang.annotation.Annotation) WebApplicationException(javax.ws.rs.WebApplicationException) ActionDefinition(org.opendaylight.yangtools.yang.model.api.ActionDefinition) MapEntryNode(org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode) NormalizedNode(org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode) RestconfNormalizedNodeWriter(org.opendaylight.restconf.nb.rfc8040.jersey.providers.api.RestconfNormalizedNodeWriter) RpcDefinition(org.opendaylight.yangtools.yang.model.api.RpcDefinition) MapEntryNode(org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode) YangInstanceIdentifier(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier) ActionDefinition(org.opendaylight.yangtools.yang.model.api.ActionDefinition) SchemaPath(org.opendaylight.yangtools.yang.model.api.SchemaPath) List(java.util.List) ContainerNode(org.opendaylight.yangtools.yang.data.api.schema.ContainerNode) PathArgument(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument) EffectiveModelContext(org.opendaylight.yangtools.yang.model.api.EffectiveModelContext)

Example 4 with DepthParam

use of org.opendaylight.restconf.nb.rfc8040.DepthParam in project netconf by opendaylight.

the class QueryParams method newReadDataParams.

/**
 * Parse parameters from URI request and check their types and values.
 *
 * @param uriInfo    URI info
 * @return {@link ReadDataParams}
 */
@NonNull
public static ReadDataParams newReadDataParams(final UriInfo uriInfo) {
    ContentParam content = ContentParam.ALL;
    DepthParam depth = null;
    FieldsParam fields = null;
    WithDefaultsParam withDefaults = null;
    PrettyPrintParam prettyPrint = null;
    boolean tagged = false;
    for (Entry<String, List<String>> entry : uriInfo.getQueryParameters().entrySet()) {
        final String paramName = entry.getKey();
        final List<String> paramValues = entry.getValue();
        try {
            switch(paramName) {
                case ContentParam.uriName:
                    content = optionalParam(ContentParam::forUriValue, paramName, paramValues);
                    break;
                case DepthParam.uriName:
                    final String depthStr = optionalParam(paramName, paramValues);
                    try {
                        depth = DepthParam.forUriValue(depthStr);
                    } catch (IllegalArgumentException e) {
                        throw new RestconfDocumentedException(e, new RestconfError(ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE, "Invalid depth parameter: " + depthStr, null, "The depth parameter must be an integer between 1 and 65535 or \"unbounded\""));
                    }
                    break;
                case FieldsParam.uriName:
                    fields = optionalParam(FieldsParam::forUriValue, paramName, paramValues);
                    break;
                case WithDefaultsParam.uriName:
                    final var defaultsVal = optionalParam(WithDefaultsParam::forUriValue, paramName, paramValues);
                    if (defaultsVal != null) {
                        switch(defaultsVal) {
                            case REPORT_ALL:
                                withDefaults = null;
                                tagged = false;
                                break;
                            case REPORT_ALL_TAGGED:
                                withDefaults = null;
                                tagged = true;
                                break;
                            default:
                                withDefaults = defaultsVal;
                                tagged = false;
                        }
                    }
                    break;
                case PrettyPrintParam.uriName:
                    prettyPrint = optionalParam(PrettyPrintParam::forUriValue, paramName, paramValues);
                    break;
                default:
                    throw unhandledParam("read", paramName);
            }
        } catch (IllegalArgumentException e) {
            throw new RestconfDocumentedException("Invalid " + paramName + " value: " + e.getMessage(), ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE, e);
        }
    }
    return ReadDataParams.of(content, depth, fields, withDefaults, tagged, prettyPrint);
}
Also used : RestconfDocumentedException(org.opendaylight.restconf.common.errors.RestconfDocumentedException) WithDefaultsParam(org.opendaylight.restconf.nb.rfc8040.WithDefaultsParam) PrettyPrintParam(org.opendaylight.restconf.nb.rfc8040.PrettyPrintParam) DepthParam(org.opendaylight.restconf.nb.rfc8040.DepthParam) ContentParam(org.opendaylight.restconf.nb.rfc8040.ContentParam) RestconfError(org.opendaylight.restconf.common.errors.RestconfError) List(java.util.List) FieldsParam(org.opendaylight.restconf.nb.rfc8040.FieldsParam) Objects.requireNonNull(java.util.Objects.requireNonNull) NonNull(org.eclipse.jdt.annotation.NonNull)

Aggregations

DepthParam (org.opendaylight.restconf.nb.rfc8040.DepthParam)4 List (java.util.List)3 Set (java.util.Set)3 QName (org.opendaylight.yangtools.yang.common.QName)3 IOException (java.io.IOException)2 OutputStream (java.io.OutputStream)2 Annotation (java.lang.annotation.Annotation)2 Type (java.lang.reflect.Type)2 StandardCharsets (java.nio.charset.StandardCharsets)2 Map (java.util.Map)2 Collectors (java.util.stream.Collectors)2 Produces (javax.ws.rs.Produces)2 WebApplicationException (javax.ws.rs.WebApplicationException)2 MediaType (javax.ws.rs.core.MediaType)2 MultivaluedMap (javax.ws.rs.core.MultivaluedMap)2 Provider (javax.ws.rs.ext.Provider)2 InstanceIdentifierContext (org.opendaylight.restconf.common.context.InstanceIdentifierContext)2 MediaTypes (org.opendaylight.restconf.nb.rfc8040.MediaTypes)2 RestconfNormalizedNodeWriter (org.opendaylight.restconf.nb.rfc8040.jersey.providers.api.RestconfNormalizedNodeWriter)2 NormalizedNodePayload (org.opendaylight.restconf.nb.rfc8040.legacy.NormalizedNodePayload)2