Search in sources :

Example 1 with InstanceIdentifierContext

use of org.opendaylight.restconf.common.context.InstanceIdentifierContext 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 InstanceIdentifierContext

use of org.opendaylight.restconf.common.context.InstanceIdentifierContext in project netconf by opendaylight.

the class RestconfImpl method prepareIIDSubsStreamOutput.

/**
 * Prepare instance identifier.
 *
 * @return {@link InstanceIdentifierContext} of location leaf for
 *         notification
 */
private InstanceIdentifierContext<?> prepareIIDSubsStreamOutput() {
    final QName qnameBase = QName.create("subscribe:to:notification", "2016-10-28", "notifi");
    final EffectiveModelContext schemaCtx = controllerContext.getGlobalSchema();
    final DataSchemaNode location = ((ContainerSchemaNode) schemaCtx.findModule(qnameBase.getModule()).orElse(null).getDataChildByName(qnameBase)).getDataChildByName(QName.create(qnameBase, "location"));
    final List<PathArgument> path = new ArrayList<>();
    path.add(NodeIdentifier.create(qnameBase));
    path.add(NodeIdentifier.create(QName.create(qnameBase, "location")));
    return new InstanceIdentifierContext<SchemaNode>(YangInstanceIdentifier.create(path), location, null, schemaCtx);
}
Also used : ContainerSchemaNode(org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode) DataSchemaNode(org.opendaylight.yangtools.yang.model.api.DataSchemaNode) QName(org.opendaylight.yangtools.yang.common.QName) ArrayList(java.util.ArrayList) InstanceIdentifierContext(org.opendaylight.restconf.common.context.InstanceIdentifierContext) PathArgument(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument) EffectiveModelContext(org.opendaylight.yangtools.yang.model.api.EffectiveModelContext)

Example 3 with InstanceIdentifierContext

use of org.opendaylight.restconf.common.context.InstanceIdentifierContext in project netconf by opendaylight.

the class RestconfDocumentedExceptionMapper method toJsonResponseBody.

private static Object toJsonResponseBody(final NormalizedNodeContext errorsNode, final DataNodeContainer errorsSchemaNode) {
    final ByteArrayOutputStream outStream = new ByteArrayOutputStream();
    NormalizedNode data = errorsNode.getData();
    final InstanceIdentifierContext<?> context = errorsNode.getInstanceIdentifierContext();
    final DataSchemaNode schema = (DataSchemaNode) context.getSchemaNode();
    final OutputStreamWriter outputWriter = new OutputStreamWriter(outStream, StandardCharsets.UTF_8);
    if (data == null) {
        throw new RestconfDocumentedException(Response.Status.NOT_FOUND);
    }
    boolean isDataRoot = false;
    XMLNamespace initialNs = null;
    SchemaPath path;
    if (context.getSchemaNode() instanceof SchemaContext) {
        isDataRoot = true;
        path = SchemaPath.ROOT;
    } else {
        final List<QName> qNames = context.getInstanceIdentifier().getPathArguments().stream().filter(arg -> !(arg instanceof NodeIdentifierWithPredicates)).filter(arg -> !(arg instanceof AugmentationIdentifier)).map(PathArgument::getNodeType).collect(Collectors.toList());
        path = SchemaPath.of(Absolute.of(qNames)).getParent();
    }
    if (!schema.isAugmenting() && !(schema instanceof SchemaContext)) {
        initialNs = schema.getQName().getNamespace();
    }
    final JsonWriter jsonWriter = JsonWriterFactory.createJsonWriter(outputWriter);
    final NormalizedNodeStreamWriter jsonStreamWriter = JSONNormalizedNodeStreamWriter.createExclusiveWriter(JSONCodecFactorySupplier.DRAFT_LHOTKA_NETMOD_YANG_JSON_02.getShared(context.getSchemaContext()), path, initialNs, jsonWriter);
    // We create a delegating writer to special-case error-info as error-info is defined as an empty
    // container in the restconf yang schema but we create a leaf node so we can output it. The delegate
    // stream writer validates the node type against the schema and thus will expect a LeafSchemaNode but
    // the schema has a ContainerSchemaNode so, to avoid an error, we override the leafNode behavior
    // for error-info.
    final NormalizedNodeStreamWriter streamWriter = new ForwardingNormalizedNodeStreamWriter() {

        private boolean inOurLeaf;

        @Override
        protected NormalizedNodeStreamWriter delegate() {
            return jsonStreamWriter;
        }

        @Override
        public void startLeafNode(final NodeIdentifier name) throws IOException {
            if (name.getNodeType().equals(RestConfModule.ERROR_INFO_QNAME)) {
                inOurLeaf = true;
                jsonWriter.name(RestConfModule.ERROR_INFO_QNAME.getLocalName());
            } else {
                super.startLeafNode(name);
            }
        }

        @Override
        public void scalarValue(final Object value) throws IOException {
            if (inOurLeaf) {
                jsonWriter.value(value.toString());
            } else {
                super.scalarValue(value);
            }
        }

        @Override
        public void endNode() throws IOException {
            if (inOurLeaf) {
                inOurLeaf = false;
            } else {
                super.endNode();
            }
        }
    };
    final NormalizedNodeWriter nnWriter = NormalizedNodeWriter.forStreamWriter(streamWriter);
    try {
        if (isDataRoot) {
            writeDataRoot(outputWriter, nnWriter, (ContainerNode) data);
        } else {
            if (data instanceof MapEntryNode) {
                data = ImmutableNodes.mapNodeBuilder(data.getIdentifier().getNodeType()).withChild((MapEntryNode) data).build();
            }
            nnWriter.write(data);
        }
        nnWriter.flush();
        outputWriter.flush();
    } catch (final IOException e) {
        LOG.warn("Error writing error response body", e);
    }
    try {
        streamWriter.close();
    } catch (IOException e) {
        LOG.warn("Failed to close stream writer", e);
    }
    return outStream.toString(StandardCharsets.UTF_8);
}
Also used : JSONNormalizedNodeStreamWriter(org.opendaylight.yangtools.yang.data.codec.gson.JSONNormalizedNodeStreamWriter) JSONCodecFactorySupplier(org.opendaylight.yangtools.yang.data.codec.gson.JSONCodecFactorySupplier) Provider(javax.ws.rs.ext.Provider) NodeIdentifier(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier) ForwardingNormalizedNodeStreamWriter(org.opendaylight.yangtools.yang.data.api.schema.stream.ForwardingNormalizedNodeStreamWriter) SchemaContext(org.opendaylight.yangtools.yang.model.api.SchemaContext) ExceptionMapper(javax.ws.rs.ext.ExceptionMapper) LoggerFactory(org.slf4j.LoggerFactory) XMLNamespace(org.opendaylight.yangtools.yang.common.XMLNamespace) Absolute(org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) ERRORS_CONTAINER_QNAME(org.opendaylight.netconf.sal.rest.api.Draft02.RestConfModule.ERRORS_CONTAINER_QNAME) MediaType(javax.ws.rs.core.MediaType) NormalizedNodeWriter(org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter) XMLStreamException(javax.xml.stream.XMLStreamException) YangInstanceIdentifier(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier) XMLStreamWriter(javax.xml.stream.XMLStreamWriter) ContainerNode(org.opendaylight.yangtools.yang.data.api.schema.ContainerNode) CollectionNodeBuilder(org.opendaylight.yangtools.yang.data.api.schema.builder.CollectionNodeBuilder) Context(javax.ws.rs.core.Context) ListSchemaNode(org.opendaylight.yangtools.yang.model.api.ListSchemaNode) ContainerSchemaNode(org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode) DataContainerChild(org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild) Collectors(java.util.stream.Collectors) StandardCharsets(java.nio.charset.StandardCharsets) Preconditions.checkState(com.google.common.base.Preconditions.checkState) ErrorTags(org.opendaylight.restconf.common.ErrorTags) XMLStreamNormalizedNodeStreamWriter(org.opendaylight.yangtools.yang.data.codec.xml.XMLStreamNormalizedNodeStreamWriter) List(java.util.List) HttpHeaders(javax.ws.rs.core.HttpHeaders) Response(javax.ws.rs.core.Response) PathArgument(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument) ImmutableNodes(org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes) MapEntryNode(org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode) Iterables(com.google.common.collect.Iterables) SchemaPath(org.opendaylight.yangtools.yang.model.api.SchemaPath) ByteArrayOutputStream(java.io.ByteArrayOutputStream) InstanceIdentifierContext(org.opendaylight.restconf.common.context.InstanceIdentifierContext) ArrayList(java.util.ArrayList) RestConfModule(org.opendaylight.netconf.sal.rest.api.Draft02.RestConfModule) JsonWriterFactory(org.opendaylight.yangtools.yang.data.codec.gson.JsonWriterFactory) Objects.requireNonNull(java.util.Objects.requireNonNull) OutputStreamWriter(java.io.OutputStreamWriter) SystemMapNode(org.opendaylight.yangtools.yang.data.api.schema.SystemMapNode) XMLConstants(javax.xml.XMLConstants) JsonWriter(com.google.gson.stream.JsonWriter) Status(javax.ws.rs.core.Response.Status) SchemaAwareBuilders(org.opendaylight.yangtools.yang.data.impl.schema.SchemaAwareBuilders) Logger(org.slf4j.Logger) DataContainerNodeBuilder(org.opendaylight.yangtools.yang.data.api.schema.builder.DataContainerNodeBuilder) IOException(java.io.IOException) NodeIdentifierWithPredicates(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates) RestconfError(org.opendaylight.restconf.common.errors.RestconfError) QName(org.opendaylight.yangtools.yang.common.QName) FactoryConfigurationError(javax.xml.stream.FactoryConfigurationError) XMLOutputFactory(javax.xml.stream.XMLOutputFactory) DataNodeContainer(org.opendaylight.yangtools.yang.model.api.DataNodeContainer) NormalizedNodeStreamWriter(org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter) DataSchemaNode(org.opendaylight.yangtools.yang.model.api.DataSchemaNode) ControllerContext(org.opendaylight.netconf.sal.restconf.impl.ControllerContext) RestconfDocumentedException(org.opendaylight.restconf.common.errors.RestconfDocumentedException) AugmentationIdentifier(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier) NormalizedNode(org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode) LeafSchemaNode(org.opendaylight.yangtools.yang.model.api.LeafSchemaNode) RestconfDocumentedException(org.opendaylight.restconf.common.errors.RestconfDocumentedException) AugmentationIdentifier(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier) DataSchemaNode(org.opendaylight.yangtools.yang.model.api.DataSchemaNode) NormalizedNodeWriter(org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter) QName(org.opendaylight.yangtools.yang.common.QName) JSONNormalizedNodeStreamWriter(org.opendaylight.yangtools.yang.data.codec.gson.JSONNormalizedNodeStreamWriter) ForwardingNormalizedNodeStreamWriter(org.opendaylight.yangtools.yang.data.api.schema.stream.ForwardingNormalizedNodeStreamWriter) XMLStreamNormalizedNodeStreamWriter(org.opendaylight.yangtools.yang.data.codec.xml.XMLStreamNormalizedNodeStreamWriter) NormalizedNodeStreamWriter(org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) NodeIdentifierWithPredicates(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates) MapEntryNode(org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode) JsonWriter(com.google.gson.stream.JsonWriter) SchemaPath(org.opendaylight.yangtools.yang.model.api.SchemaPath) NodeIdentifier(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier) XMLNamespace(org.opendaylight.yangtools.yang.common.XMLNamespace) ForwardingNormalizedNodeStreamWriter(org.opendaylight.yangtools.yang.data.api.schema.stream.ForwardingNormalizedNodeStreamWriter) OutputStreamWriter(java.io.OutputStreamWriter) SchemaContext(org.opendaylight.yangtools.yang.model.api.SchemaContext) NormalizedNode(org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode)

Example 4 with InstanceIdentifierContext

use of org.opendaylight.restconf.common.context.InstanceIdentifierContext in project netconf by opendaylight.

the class XmlNormalizedNodeBodyReader method parse.

private NormalizedNodeContext parse(final InstanceIdentifierContext<?> pathContext, final Document doc) throws XMLStreamException, IOException, ParserConfigurationException, SAXException, URISyntaxException {
    final SchemaNode schemaNodeContext = pathContext.getSchemaNode();
    DataSchemaNode schemaNode;
    boolean isRpc = false;
    if (schemaNodeContext instanceof RpcDefinition) {
        schemaNode = ((RpcDefinition) schemaNodeContext).getInput();
        isRpc = true;
    } else if (schemaNodeContext instanceof DataSchemaNode) {
        schemaNode = (DataSchemaNode) schemaNodeContext;
    } else {
        throw new IllegalStateException("Unknown SchemaNode");
    }
    final String docRootElm = doc.getDocumentElement().getLocalName();
    final String docRootNamespace = doc.getDocumentElement().getNamespaceURI();
    final List<YangInstanceIdentifier.PathArgument> iiToDataList = new ArrayList<>();
    if (isPost() && !isRpc) {
        final Deque<Object> foundSchemaNodes = findPathToSchemaNodeByName(schemaNode, docRootElm, docRootNamespace);
        if (foundSchemaNodes.isEmpty()) {
            throw new IllegalStateException(String.format("Child \"%s\" was not found in parent schema node \"%s\"", docRootElm, schemaNode.getQName()));
        }
        while (!foundSchemaNodes.isEmpty()) {
            final Object child = foundSchemaNodes.pop();
            if (child instanceof AugmentationSchemaNode) {
                final AugmentationSchemaNode augmentSchemaNode = (AugmentationSchemaNode) child;
                iiToDataList.add(DataSchemaContextNode.augmentationIdentifierFrom(augmentSchemaNode));
            } else if (child instanceof DataSchemaNode) {
                schemaNode = (DataSchemaNode) child;
                iiToDataList.add(new YangInstanceIdentifier.NodeIdentifier(schemaNode.getQName()));
            }
        }
    // PUT
    } else if (!isRpc) {
        final QName scQName = schemaNode.getQName();
        Preconditions.checkState(docRootElm.equals(scQName.getLocalName()) && docRootNamespace.equals(scQName.getNamespace().toString()), String.format("Not correct message root element \"%s\", should be \"%s\"", docRootElm, scQName));
    }
    NormalizedNode parsed;
    final NormalizedNodeResult resultHolder = new NormalizedNodeResult();
    final NormalizedNodeStreamWriter writer = ImmutableNormalizedNodeStreamWriter.from(resultHolder);
    if (schemaNode instanceof ContainerLike || schemaNode instanceof ListSchemaNode || schemaNode instanceof LeafSchemaNode) {
        final XmlParserStream xmlParser = XmlParserStream.create(writer, SchemaInferenceStack.ofSchemaPath(pathContext.getSchemaContext(), schemaNode.getPath()).toInference());
        xmlParser.traverse(new DOMSource(doc.getDocumentElement()));
        parsed = resultHolder.getResult();
        // Therefore we now have to extract the MapEntryNode from the parsed MapNode.
        if (parsed instanceof MapNode) {
            final MapNode mapNode = (MapNode) parsed;
            // extracting the MapEntryNode
            parsed = mapNode.body().iterator().next();
        }
        if (schemaNode instanceof ListSchemaNode && isPost()) {
            iiToDataList.add(parsed.getIdentifier());
        }
    } else {
        LOG.warn("Unknown schema node extension {} was not parsed", schemaNode.getClass());
        parsed = null;
    }
    final YangInstanceIdentifier fullIIToData = YangInstanceIdentifier.create(Iterables.concat(pathContext.getInstanceIdentifier().getPathArguments(), iiToDataList));
    final InstanceIdentifierContext<? extends SchemaNode> outIIContext = new InstanceIdentifierContext<>(fullIIToData, pathContext.getSchemaNode(), pathContext.getMountPoint(), pathContext.getSchemaContext());
    return new NormalizedNodeContext(outIIContext, parsed);
}
Also used : ContainerLike(org.opendaylight.yangtools.yang.model.api.ContainerLike) XmlParserStream(org.opendaylight.yangtools.yang.data.codec.xml.XmlParserStream) DOMSource(javax.xml.transform.dom.DOMSource) RpcDefinition(org.opendaylight.yangtools.yang.model.api.RpcDefinition) ArrayList(java.util.ArrayList) MapNode(org.opendaylight.yangtools.yang.data.api.schema.MapNode) NormalizedNodeResult(org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeResult) NormalizedNode(org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode) AugmentationSchemaNode(org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode) DataSchemaNode(org.opendaylight.yangtools.yang.model.api.DataSchemaNode) QName(org.opendaylight.yangtools.yang.common.QName) ImmutableNormalizedNodeStreamWriter(org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter) NormalizedNodeStreamWriter(org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter) InstanceIdentifierContext(org.opendaylight.restconf.common.context.InstanceIdentifierContext) LeafSchemaNode(org.opendaylight.yangtools.yang.model.api.LeafSchemaNode) YangInstanceIdentifier(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier) AugmentationSchemaNode(org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode) ListSchemaNode(org.opendaylight.yangtools.yang.model.api.ListSchemaNode) CaseSchemaNode(org.opendaylight.yangtools.yang.model.api.CaseSchemaNode) ChoiceSchemaNode(org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode) SchemaNode(org.opendaylight.yangtools.yang.model.api.SchemaNode) DataSchemaNode(org.opendaylight.yangtools.yang.model.api.DataSchemaNode) LeafSchemaNode(org.opendaylight.yangtools.yang.model.api.LeafSchemaNode) ListSchemaNode(org.opendaylight.yangtools.yang.model.api.ListSchemaNode)

Example 5 with InstanceIdentifierContext

use of org.opendaylight.restconf.common.context.InstanceIdentifierContext in project netconf by opendaylight.

the class XmlToPatchBodyReader method parse.

private static PatchContext parse(final InstanceIdentifierContext<?> pathContext, final Document doc) throws XMLStreamException, IOException, ParserConfigurationException, SAXException, URISyntaxException {
    final List<PatchEntity> resultCollection = new ArrayList<>();
    final String patchId = doc.getElementsByTagName("patch-id").item(0).getFirstChild().getNodeValue();
    final NodeList editNodes = doc.getElementsByTagName("edit");
    for (int i = 0; i < editNodes.getLength(); i++) {
        DataSchemaNode schemaNode = (DataSchemaNode) pathContext.getSchemaNode();
        final Element element = (Element) editNodes.item(i);
        final String operation = element.getElementsByTagName("operation").item(0).getFirstChild().getNodeValue();
        final PatchEditOperation oper = PatchEditOperation.valueOf(operation.toUpperCase(Locale.ROOT));
        final String editId = element.getElementsByTagName("edit-id").item(0).getFirstChild().getNodeValue();
        final String target = element.getElementsByTagName("target").item(0).getFirstChild().getNodeValue();
        final List<Element> values = readValueNodes(element, oper);
        final Element firstValueElement = values != null ? values.get(0) : null;
        // get namespace according to schema node from path context or value
        final String namespace = firstValueElement == null ? schemaNode.getQName().getNamespace().toString() : firstValueElement.getNamespaceURI();
        // find module according to namespace
        final Module module = pathContext.getSchemaContext().findModules(XMLNamespace.of(namespace)).iterator().next();
        // initialize codec + set default prefix derived from module name
        final StringModuleInstanceIdentifierCodec codec = new StringModuleInstanceIdentifierCodec(pathContext.getSchemaContext(), module.getName());
        // find complete path to target and target schema node
        // target can be also empty (only slash)
        YangInstanceIdentifier targetII;
        final SchemaNode targetNode;
        final Inference inference;
        if (target.equals("/")) {
            targetII = pathContext.getInstanceIdentifier();
            targetNode = pathContext.getSchemaContext();
            inference = Inference.ofDataTreePath(pathContext.getSchemaContext(), schemaNode.getQName());
        } else {
            targetII = codec.deserialize(codec.serialize(pathContext.getInstanceIdentifier()).concat(prepareNonCondXpath(schemaNode, target.replaceFirst("/", ""), firstValueElement, namespace, module.getQNameModule().getRevision().map(Revision::toString).orElse(null))));
            // move schema node
            schemaNode = verifyNotNull(codec.getDataContextTree().findChild(targetII).orElseThrow().getDataSchemaNode());
            final SchemaInferenceStack stack = SchemaInferenceStack.of(pathContext.getSchemaContext());
            targetII.getPathArguments().stream().filter(arg -> !(arg instanceof YangInstanceIdentifier.NodeIdentifierWithPredicates)).filter(arg -> !(arg instanceof YangInstanceIdentifier.AugmentationIdentifier)).forEach(p -> stack.enterSchemaTree(p.getNodeType()));
            final EffectiveStatement<?, ?> parentStmt = stack.exit();
            verify(parentStmt instanceof SchemaNode, "Unexpected parent %s", parentStmt);
            targetNode = (SchemaNode) parentStmt;
            inference = stack.toInference();
        }
        if (targetNode == null) {
            LOG.debug("Target node {} not found in path {} ", target, pathContext.getSchemaNode());
            throw new RestconfDocumentedException("Error parsing input", ErrorType.PROTOCOL, ErrorTag.MALFORMED_MESSAGE);
        }
        if (oper.isWithValue()) {
            final NormalizedNode parsed;
            if (schemaNode instanceof ContainerSchemaNode || schemaNode instanceof ListSchemaNode) {
                final NormalizedNodeResult resultHolder = new NormalizedNodeResult();
                final NormalizedNodeStreamWriter writer = ImmutableNormalizedNodeStreamWriter.from(resultHolder);
                final XmlParserStream xmlParser = XmlParserStream.create(writer, inference);
                xmlParser.traverse(new DOMSource(firstValueElement));
                parsed = resultHolder.getResult();
            } else {
                parsed = null;
            }
            // for lists allow to manipulate with list items through their parent
            if (targetII.getLastPathArgument() instanceof NodeIdentifierWithPredicates) {
                targetII = targetII.getParent();
            }
            resultCollection.add(new PatchEntity(editId, oper, targetII, parsed));
        } else {
            resultCollection.add(new PatchEntity(editId, oper, targetII));
        }
    }
    return new PatchContext(pathContext, ImmutableList.copyOf(resultCollection), patchId);
}
Also used : SchemaInferenceStack(org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack) Provider(javax.ws.rs.ext.Provider) ImmutableNormalizedNodeStreamWriter(org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter) URISyntaxException(java.net.URISyntaxException) Draft02(org.opendaylight.netconf.sal.rest.api.Draft02) LoggerFactory(org.slf4j.LoggerFactory) UntrustedXML(org.opendaylight.yangtools.util.xml.UntrustedXML) XMLNamespace(org.opendaylight.yangtools.yang.common.XMLNamespace) MediaType(javax.ws.rs.core.MediaType) Consumes(javax.ws.rs.Consumes) PatchContext(org.opendaylight.restconf.common.patch.PatchContext) NormalizedNodeResult(org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeResult) Locale(java.util.Locale) Document(org.w3c.dom.Document) XMLStreamException(javax.xml.stream.XMLStreamException) YangInstanceIdentifier(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier) RestconfService(org.opendaylight.netconf.sal.rest.api.RestconfService) Splitter(com.google.common.base.Splitter) ListSchemaNode(org.opendaylight.yangtools.yang.model.api.ListSchemaNode) Module(org.opendaylight.yangtools.yang.model.api.Module) ContainerSchemaNode(org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode) Inference(org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack.Inference) List(java.util.List) Revision(org.opendaylight.yangtools.yang.common.Revision) Type(java.lang.reflect.Type) SAXException(org.xml.sax.SAXException) Annotation(java.lang.annotation.Annotation) Optional(java.util.Optional) WebApplicationException(javax.ws.rs.WebApplicationException) NonNull(org.eclipse.jdt.annotation.NonNull) Verify.verifyNotNull(com.google.common.base.Verify.verifyNotNull) DOMSource(javax.xml.transform.dom.DOMSource) InstanceIdentifierContext(org.opendaylight.restconf.common.context.InstanceIdentifierContext) PatchEntity(org.opendaylight.restconf.common.patch.PatchEntity) ArrayList(java.util.ArrayList) ErrorType(org.opendaylight.yangtools.yang.common.ErrorType) ImmutableList(com.google.common.collect.ImmutableList) Verify.verify(com.google.common.base.Verify.verify) XmlParserStream(org.opendaylight.yangtools.yang.data.codec.xml.XmlParserStream) Node(org.w3c.dom.Node) EffectiveStatement(org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement) RestUtil(org.opendaylight.restconf.common.util.RestUtil) Logger(org.slf4j.Logger) NodeList(org.w3c.dom.NodeList) Iterator(java.util.Iterator) SchemaInferenceStack(org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack) ErrorTag(org.opendaylight.yangtools.yang.common.ErrorTag) IOException(java.io.IOException) NodeIdentifierWithPredicates(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates) QName(org.opendaylight.yangtools.yang.common.QName) SchemaNode(org.opendaylight.yangtools.yang.model.api.SchemaNode) MultivaluedMap(javax.ws.rs.core.MultivaluedMap) Element(org.w3c.dom.Element) DataNodeContainer(org.opendaylight.yangtools.yang.model.api.DataNodeContainer) ParserConfigurationException(javax.xml.parsers.ParserConfigurationException) NormalizedNodeStreamWriter(org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter) DataSchemaNode(org.opendaylight.yangtools.yang.model.api.DataSchemaNode) ControllerContext(org.opendaylight.netconf.sal.restconf.impl.ControllerContext) RestconfDocumentedException(org.opendaylight.restconf.common.errors.RestconfDocumentedException) NormalizedNode(org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode) InputStream(java.io.InputStream) MessageBodyReader(javax.ws.rs.ext.MessageBodyReader) PatchEditOperation(org.opendaylight.restconf.common.patch.PatchEditOperation) XmlParserStream(org.opendaylight.yangtools.yang.data.codec.xml.XmlParserStream) RestconfDocumentedException(org.opendaylight.restconf.common.errors.RestconfDocumentedException) DOMSource(javax.xml.transform.dom.DOMSource) PatchEntity(org.opendaylight.restconf.common.patch.PatchEntity) Element(org.w3c.dom.Element) ArrayList(java.util.ArrayList) ContainerSchemaNode(org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode) NormalizedNodeResult(org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeResult) NormalizedNode(org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode) PatchEditOperation(org.opendaylight.restconf.common.patch.PatchEditOperation) DataSchemaNode(org.opendaylight.yangtools.yang.model.api.DataSchemaNode) NodeList(org.w3c.dom.NodeList) Inference(org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack.Inference) ImmutableNormalizedNodeStreamWriter(org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter) NormalizedNodeStreamWriter(org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter) NodeIdentifierWithPredicates(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates) YangInstanceIdentifier(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier) ListSchemaNode(org.opendaylight.yangtools.yang.model.api.ListSchemaNode) ContainerSchemaNode(org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode) SchemaNode(org.opendaylight.yangtools.yang.model.api.SchemaNode) DataSchemaNode(org.opendaylight.yangtools.yang.model.api.DataSchemaNode) PatchContext(org.opendaylight.restconf.common.patch.PatchContext) ListSchemaNode(org.opendaylight.yangtools.yang.model.api.ListSchemaNode) Module(org.opendaylight.yangtools.yang.model.api.Module) NodeIdentifierWithPredicates(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates)

Aggregations

InstanceIdentifierContext (org.opendaylight.restconf.common.context.InstanceIdentifierContext)50 Test (org.junit.Test)29 DataSchemaNode (org.opendaylight.yangtools.yang.model.api.DataSchemaNode)28 NormalizedNodePayload (org.opendaylight.restconf.nb.rfc8040.legacy.NormalizedNodePayload)26 YangInstanceIdentifier (org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier)24 NormalizedNode (org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode)20 ArrayList (java.util.ArrayList)18 NetconfRestconfStrategy (org.opendaylight.restconf.nb.rfc8040.rests.transactions.NetconfRestconfStrategy)16 DefaultDOMRpcResult (org.opendaylight.mdsal.dom.spi.DefaultDOMRpcResult)15 List (java.util.List)14 MdsalRestconfStrategy (org.opendaylight.restconf.nb.rfc8040.rests.transactions.MdsalRestconfStrategy)14 QName (org.opendaylight.yangtools.yang.common.QName)14 NormalizedNodeStreamWriter (org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter)14 Provider (javax.ws.rs.ext.Provider)13 IOException (java.io.IOException)12 RestconfDocumentedException (org.opendaylight.restconf.common.errors.RestconfDocumentedException)12 PatchContext (org.opendaylight.restconf.common.patch.PatchContext)12 MapEntryNode (org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode)12 StandardCharsets (java.nio.charset.StandardCharsets)11 WebApplicationException (javax.ws.rs.WebApplicationException)11