Search in sources :

Example 46 with InstanceIdentifierContext

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

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

the class JsonPatchBodyReader method readEditDefinition.

/**
 * Read one patch edit object from Json input.
 *
 * @param edit PatchEdit instance to be filled with read data
 * @param in JsonReader reader
 * @param path InstanceIdentifierContext path context
 * @throws IOException if operation fails
 */
private void readEditDefinition(@NonNull final PatchEdit edit, @NonNull final JsonReader in, @NonNull final InstanceIdentifierContext<?> path) throws IOException {
    String deferredValue = null;
    in.beginObject();
    while (in.hasNext()) {
        final String editDefinition = in.nextName();
        switch(editDefinition) {
            case "edit-id":
                edit.setId(in.nextString());
                break;
            case "operation":
                edit.setOperation(PatchEditOperation.valueOf(in.nextString().toUpperCase(Locale.ROOT)));
                break;
            case "target":
                // target can be specified completely in request URI
                final String target = in.nextString();
                final SchemaInferenceStack stack = SchemaInferenceStack.of(path.getSchemaContext());
                if (target.equals("/")) {
                    edit.setTarget(path.getInstanceIdentifier());
                    edit.setTargetInference(stack.toInference());
                } else {
                    edit.setTarget(ParserIdentifier.parserPatchTarget(path, target));
                    edit.getTarget().getPathArguments().stream().filter(arg -> !(arg instanceof YangInstanceIdentifier.NodeIdentifierWithPredicates)).filter(arg -> !(arg instanceof YangInstanceIdentifier.AugmentationIdentifier)).forEach(p -> stack.enterSchemaTree(p.getNodeType()));
                    stack.exit();
                    edit.setTargetInference(stack.toInference());
                }
                break;
            case "value":
                checkArgument(edit.getData() == null && deferredValue == null, "Multiple value entries found");
                if (edit.getTargetInference() == null) {
                    // save data defined in value node for next (later) processing, because target needs to be read
                    // always first and there is no ordering in Json input
                    deferredValue = readValueNode(in);
                } else {
                    // We have a target schema node, reuse this reader without buffering the value.
                    edit.setData(readEditData(in, edit.getTargetInference(), path));
                }
                break;
            default:
                // FIXME: this does not look right, as it can wreck our logic
                break;
        }
    }
    in.endObject();
    if (deferredValue != null) {
        // read saved data to normalized node when target schema is already known
        edit.setData(readEditData(new JsonReader(new StringReader(deferredValue)), edit.getTargetInference(), path));
    }
}
Also used : SchemaInferenceStack(org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack) JSONCodecFactorySupplier(org.opendaylight.yangtools.yang.data.codec.gson.JSONCodecFactorySupplier) Provider(javax.ws.rs.ext.Provider) ImmutableNormalizedNodeStreamWriter(org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter) InstanceIdentifierContext(org.opendaylight.restconf.common.context.InstanceIdentifierContext) LoggerFactory(org.slf4j.LoggerFactory) DOMMountPointService(org.opendaylight.mdsal.dom.api.DOMMountPointService) AtomicReference(java.util.concurrent.atomic.AtomicReference) JsonReader(com.google.gson.stream.JsonReader) PatchEntity(org.opendaylight.restconf.common.patch.PatchEntity) ArrayList(java.util.ArrayList) ErrorType(org.opendaylight.yangtools.yang.common.ErrorType) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) ResultAlreadySetException(org.opendaylight.yangtools.yang.data.impl.schema.ResultAlreadySetException) ImmutableList(com.google.common.collect.ImmutableList) 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) Objects.requireNonNull(java.util.Objects.requireNonNull) SchemaContextHandler(org.opendaylight.restconf.nb.rfc8040.handlers.SchemaContextHandler) YangInstanceIdentifier(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier) Logger(org.slf4j.Logger) SchemaInferenceStack(org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack) ErrorTag(org.opendaylight.yangtools.yang.common.ErrorTag) Inference(org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack.Inference) Throwables(com.google.common.base.Throwables) IOException(java.io.IOException) NodeIdentifierWithPredicates(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates) InputStreamReader(java.io.InputStreamReader) StandardCharsets(java.nio.charset.StandardCharsets) MediaTypes(org.opendaylight.restconf.nb.rfc8040.MediaTypes) ParserIdentifier(org.opendaylight.restconf.nb.rfc8040.utils.parser.ParserIdentifier) JsonToken(com.google.gson.stream.JsonToken) List(java.util.List) StringReader(java.io.StringReader) NormalizedNodeStreamWriter(org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter) JsonParserStream(org.opendaylight.yangtools.yang.data.codec.gson.JsonParserStream) Optional(java.util.Optional) WebApplicationException(javax.ws.rs.WebApplicationException) NonNull(org.eclipse.jdt.annotation.NonNull) RestconfDocumentedException(org.opendaylight.restconf.common.errors.RestconfDocumentedException) NormalizedNode(org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode) InputStream(java.io.InputStream) PatchEditOperation(org.opendaylight.restconf.common.patch.PatchEditOperation) StringReader(java.io.StringReader) JsonReader(com.google.gson.stream.JsonReader) NodeIdentifierWithPredicates(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates) YangInstanceIdentifier(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier)

Example 48 with InstanceIdentifierContext

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

the class XmlPatchBodyReader 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;
        // 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 {
            // interpret as simple context
            targetII = ParserIdentifier.parserPatchTarget(pathContext, target);
            // move schema node
            schemaNode = verifyNotNull(DataSchemaContextTree.from(pathContext.getSchemaContext()).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) LoggerFactory(org.slf4j.LoggerFactory) UntrustedXML(org.opendaylight.yangtools.util.xml.UntrustedXML) 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) ListSchemaNode(org.opendaylight.yangtools.yang.model.api.ListSchemaNode) ContainerSchemaNode(org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode) Inference(org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack.Inference) MediaTypes(org.opendaylight.restconf.nb.rfc8040.MediaTypes) ParserIdentifier(org.opendaylight.restconf.nb.rfc8040.utils.parser.ParserIdentifier) List(java.util.List) SAXException(org.xml.sax.SAXException) 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) DOMMountPointService(org.opendaylight.mdsal.dom.api.DOMMountPointService) 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) SchemaContextHandler(org.opendaylight.restconf.nb.rfc8040.handlers.SchemaContextHandler) XmlParserStream(org.opendaylight.yangtools.yang.data.codec.xml.XmlParserStream) Node(org.w3c.dom.Node) EffectiveStatement(org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement) Logger(org.slf4j.Logger) NodeList(org.w3c.dom.NodeList) 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) DataSchemaContextTree(org.opendaylight.yangtools.yang.data.util.DataSchemaContextTree) SchemaNode(org.opendaylight.yangtools.yang.model.api.SchemaNode) Element(org.w3c.dom.Element) ParserConfigurationException(javax.xml.parsers.ParserConfigurationException) NormalizedNodeStreamWriter(org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter) DataSchemaNode(org.opendaylight.yangtools.yang.model.api.DataSchemaNode) RestconfDocumentedException(org.opendaylight.restconf.common.errors.RestconfDocumentedException) NormalizedNode(org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode) InputStream(java.io.InputStream) 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) NodeIdentifierWithPredicates(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates)

Example 49 with InstanceIdentifierContext

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

the class RestconfStreamsSubscriptionServiceImpl method prepareIIDSubsStreamOutput.

/**
 * Prepare InstanceIdentifierContext for Location leaf.
 *
 * @param schemaHandler Schema context handler.
 * @return InstanceIdentifier of Location leaf.
 */
private static InstanceIdentifierContext<?> prepareIIDSubsStreamOutput(final SchemaContextHandler schemaHandler) {
    final Optional<Module> module = schemaHandler.get().findModule(NOTIFI_QNAME.getModule());
    checkState(module.isPresent());
    final DataSchemaNode notify = module.get().dataChildByName(NOTIFI_QNAME);
    checkState(notify instanceof ContainerSchemaNode, "Unexpected non-container %s", notify);
    final DataSchemaNode location = ((ContainerSchemaNode) notify).dataChildByName(LOCATION_QNAME);
    checkState(location != null, "Missing location");
    return new InstanceIdentifierContext<SchemaNode>(LOCATION_PATH, location, null, schemaHandler.get());
}
Also used : ContainerSchemaNode(org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode) DataSchemaNode(org.opendaylight.yangtools.yang.model.api.DataSchemaNode) InstanceIdentifierContext(org.opendaylight.restconf.common.context.InstanceIdentifierContext) Module(org.opendaylight.yangtools.yang.model.api.Module)

Example 50 with InstanceIdentifierContext

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

the class ControllerContext method collectPathArguments.

@SuppressFBWarnings(value = "RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE", justification = "Unrecognised NullableDecl")
private InstanceIdentifierContext<?> collectPathArguments(final InstanceIdentifierBuilder builder, final List<String> strings, final DataNodeContainer parentNode, final DOMMountPoint mountPoint, final boolean returnJustMountPoint) {
    requireNonNull(strings);
    if (parentNode == null) {
        return null;
    }
    if (strings.isEmpty()) {
        return createContext(builder.build(), (DataSchemaNode) parentNode, mountPoint, mountPoint != null ? getModelContext(mountPoint) : globalSchema);
    }
    final String head = strings.iterator().next();
    if (head.isEmpty()) {
        final List<String> remaining = strings.subList(1, strings.size());
        return collectPathArguments(builder, remaining, parentNode, mountPoint, returnJustMountPoint);
    }
    final String nodeName = toNodeName(head);
    final String moduleName = toModuleName(head);
    DataSchemaNode targetNode = null;
    if (!Strings.isNullOrEmpty(moduleName)) {
        if (MOUNT_MODULE.equals(moduleName) && MOUNT_NODE.equals(nodeName)) {
            if (mountPoint != null) {
                throw new RestconfDocumentedException("Restconf supports just one mount point in URI.", ErrorType.APPLICATION, ErrorTag.OPERATION_NOT_SUPPORTED);
            }
            if (mountService == null) {
                throw new RestconfDocumentedException("MountService was not found. Finding behind mount points does not work.", ErrorType.APPLICATION, ErrorTag.OPERATION_NOT_SUPPORTED);
            }
            final YangInstanceIdentifier partialPath = dataNormalizer.toNormalized(builder.build());
            final Optional<DOMMountPoint> mountOpt = mountService.getMountPoint(partialPath);
            if (mountOpt.isEmpty()) {
                LOG.debug("Instance identifier to missing mount point: {}", partialPath);
                throw new RestconfDocumentedException("Mount point does not exist.", ErrorType.PROTOCOL, ErrorTag.DATA_MISSING);
            }
            final DOMMountPoint mount = mountOpt.get();
            final EffectiveModelContext mountPointSchema = getModelContext(mount);
            if (mountPointSchema == null) {
                throw new RestconfDocumentedException("Mount point does not contain any schema with modules.", ErrorType.APPLICATION, ErrorTag.UNKNOWN_ELEMENT);
            }
            if (returnJustMountPoint || strings.size() == 1) {
                return new InstanceIdentifierContext<>(YangInstanceIdentifier.empty(), mountPointSchema, mount, mountPointSchema);
            }
            final String moduleNameBehindMountPoint = toModuleName(strings.get(1));
            if (moduleNameBehindMountPoint == null) {
                throw new RestconfDocumentedException("First node after mount point in URI has to be in format \"moduleName:nodeName\"", ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
            }
            final Iterator<? extends Module> it = mountPointSchema.findModules(moduleNameBehindMountPoint).iterator();
            if (!it.hasNext()) {
                throw new RestconfDocumentedException("\"" + moduleNameBehindMountPoint + "\" module does not exist in mount point.", ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT);
            }
            final List<String> subList = strings.subList(1, strings.size());
            return collectPathArguments(YangInstanceIdentifier.builder(), subList, it.next(), mount, returnJustMountPoint);
        }
        Module module = null;
        if (mountPoint == null) {
            checkPreconditions();
            module = globalSchema.findModules(moduleName).stream().findFirst().orElse(null);
            if (module == null) {
                throw new RestconfDocumentedException("\"" + moduleName + "\" module does not exist.", ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT);
            }
        } else {
            final EffectiveModelContext schemaContext = getModelContext(mountPoint);
            if (schemaContext != null) {
                module = schemaContext.findModules(moduleName).stream().findFirst().orElse(null);
            } else {
                module = null;
            }
            if (module == null) {
                throw new RestconfDocumentedException("\"" + moduleName + "\" module does not exist in mount point.", ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT);
            }
        }
        targetNode = findInstanceDataChildByNameAndNamespace(parentNode, nodeName, module.getNamespace());
        if (targetNode == null && parentNode instanceof Module) {
            final RpcDefinition rpc;
            if (mountPoint == null) {
                rpc = getRpcDefinition(head, module.getRevision());
            } else {
                final String rpcName = toNodeName(head);
                rpc = getRpcDefinition(module, rpcName);
            }
            if (rpc != null) {
                return new InstanceIdentifierContext<>(builder.build(), rpc, mountPoint, mountPoint != null ? getModelContext(mountPoint) : globalSchema);
            }
        }
        if (targetNode == null) {
            throw new RestconfDocumentedException("URI has bad format. Possible reasons:\n" + " 1. \"" + head + "\" was not found in parent data node.\n" + " 2. \"" + head + "\" is behind mount point. Then it should be in format \"/" + MOUNT + "/" + head + "\".", ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
        }
    } else {
        final List<DataSchemaNode> potentialSchemaNodes = findInstanceDataChildrenByName(parentNode, nodeName);
        if (potentialSchemaNodes.size() > 1) {
            final StringBuilder strBuilder = new StringBuilder();
            for (final DataSchemaNode potentialNodeSchema : potentialSchemaNodes) {
                strBuilder.append("   ").append(potentialNodeSchema.getQName().getNamespace()).append("\n");
            }
            throw new RestconfDocumentedException("URI has bad format. Node \"" + nodeName + "\" is added as augment from more than one module. " + "Therefore the node must have module name " + "and it has to be in format \"moduleName:nodeName\"." + "\nThe node is added as augment from modules with namespaces:\n" + strBuilder.toString(), ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
        }
        if (potentialSchemaNodes.isEmpty()) {
            throw new RestconfDocumentedException("\"" + nodeName + "\" in URI was not found in parent data node", ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT);
        }
        targetNode = potentialSchemaNodes.iterator().next();
    }
    if (!isListOrContainer(targetNode)) {
        throw new RestconfDocumentedException("URI has bad format. Node \"" + head + "\" must be Container or List yang type.", ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
    }
    int consumed = 1;
    if (targetNode instanceof ListSchemaNode) {
        final ListSchemaNode listNode = (ListSchemaNode) targetNode;
        final int keysSize = listNode.getKeyDefinition().size();
        if (strings.size() - consumed < keysSize) {
            throw new RestconfDocumentedException("Missing key for list \"" + listNode.getQName().getLocalName() + "\".", ErrorType.PROTOCOL, ErrorTag.DATA_MISSING);
        }
        final List<String> uriKeyValues = strings.subList(consumed, consumed + keysSize);
        final HashMap<QName, Object> keyValues = new HashMap<>();
        int index = 0;
        for (final QName key : listNode.getKeyDefinition()) {
            {
                final String uriKeyValue = uriKeyValues.get(index);
                if (uriKeyValue.equals(NULL_VALUE)) {
                    throw new RestconfDocumentedException("URI has bad format. List \"" + listNode.getQName().getLocalName() + "\" cannot contain \"null\" value as a key.", ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
                }
                addKeyValue(keyValues, listNode.getDataChildByName(key), uriKeyValue, mountPoint);
                index++;
            }
        }
        consumed = consumed + index;
        builder.nodeWithKey(targetNode.getQName(), keyValues);
    } else {
        builder.node(targetNode.getQName());
    }
    if (targetNode instanceof DataNodeContainer) {
        final List<String> remaining = strings.subList(consumed, strings.size());
        return collectPathArguments(builder, remaining, (DataNodeContainer) targetNode, mountPoint, returnJustMountPoint);
    }
    return createContext(builder.build(), targetNode, mountPoint, mountPoint != null ? getModelContext(mountPoint) : globalSchema);
}
Also used : RestconfDocumentedException(org.opendaylight.restconf.common.errors.RestconfDocumentedException) RpcDefinition(org.opendaylight.yangtools.yang.model.api.RpcDefinition) DataSchemaNode(org.opendaylight.yangtools.yang.model.api.DataSchemaNode) HashMap(java.util.HashMap) QName(org.opendaylight.yangtools.yang.common.QName) DOMMountPoint(org.opendaylight.mdsal.dom.api.DOMMountPoint) InstanceIdentifierContext(org.opendaylight.restconf.common.context.InstanceIdentifierContext) YangInstanceIdentifier(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier) DOMMountPoint(org.opendaylight.mdsal.dom.api.DOMMountPoint) ListSchemaNode(org.opendaylight.yangtools.yang.model.api.ListSchemaNode) LeafListSchemaNode(org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode) DataNodeContainer(org.opendaylight.yangtools.yang.model.api.DataNodeContainer) Module(org.opendaylight.yangtools.yang.model.api.Module) RestConfModule(org.opendaylight.netconf.sal.rest.api.Draft02.RestConfModule) EffectiveModelContext(org.opendaylight.yangtools.yang.model.api.EffectiveModelContext) SuppressFBWarnings(edu.umd.cs.findbugs.annotations.SuppressFBWarnings)

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