Search in sources :

Example 1 with PatchContext

use of org.opendaylight.restconf.common.patch.PatchContext in project netconf by opendaylight.

the class JsonPatchBodyReader method readFrom.

private PatchContext readFrom(final InstanceIdentifierContext<?> path, final InputStream entityStream) throws IOException {
    final JsonReader jsonReader = new JsonReader(new InputStreamReader(entityStream, StandardCharsets.UTF_8));
    AtomicReference<String> patchId = new AtomicReference<>();
    final List<PatchEntity> resultList = read(jsonReader, path, patchId);
    jsonReader.close();
    return new PatchContext(path, resultList, patchId.get());
}
Also used : InputStreamReader(java.io.InputStreamReader) PatchContext(org.opendaylight.restconf.common.patch.PatchContext) PatchEntity(org.opendaylight.restconf.common.patch.PatchEntity) JsonReader(com.google.gson.stream.JsonReader) AtomicReference(java.util.concurrent.atomic.AtomicReference)

Example 2 with PatchContext

use of org.opendaylight.restconf.common.patch.PatchContext in project netconf by opendaylight.

the class XmlToPatchBodyReader method readFrom.

@SuppressWarnings("checkstyle:IllegalCatch")
@Override
public PatchContext readFrom(final Class<PatchContext> type, final Type genericType, final Annotation[] annotations, final MediaType mediaType, final MultivaluedMap<String, String> httpHeaders, final InputStream entityStream) throws WebApplicationException {
    try {
        final InstanceIdentifierContext<?> path = getInstanceIdentifierContext();
        final Optional<InputStream> nonEmptyInputStreamOptional = RestUtil.isInputStreamEmpty(entityStream);
        if (nonEmptyInputStreamOptional.isEmpty()) {
            // represent empty nopayload input
            return new PatchContext(path, null, null);
        }
        final Document doc = UntrustedXML.newDocumentBuilder().parse(nonEmptyInputStreamOptional.get());
        return parse(path, doc);
    } catch (final RestconfDocumentedException e) {
        throw e;
    } catch (final Exception e) {
        LOG.debug("Error parsing xml input", e);
        RestconfDocumentedException.throwIfYangError(e);
        throw new RestconfDocumentedException("Error parsing input: " + e.getMessage(), ErrorType.PROTOCOL, ErrorTag.MALFORMED_MESSAGE, e);
    }
}
Also used : RestconfDocumentedException(org.opendaylight.restconf.common.errors.RestconfDocumentedException) PatchContext(org.opendaylight.restconf.common.patch.PatchContext) InputStream(java.io.InputStream) Document(org.w3c.dom.Document) URISyntaxException(java.net.URISyntaxException) XMLStreamException(javax.xml.stream.XMLStreamException) SAXException(org.xml.sax.SAXException) WebApplicationException(javax.ws.rs.WebApplicationException) IOException(java.io.IOException) ParserConfigurationException(javax.xml.parsers.ParserConfigurationException) RestconfDocumentedException(org.opendaylight.restconf.common.errors.RestconfDocumentedException)

Example 3 with PatchContext

use of org.opendaylight.restconf.common.patch.PatchContext 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)

Example 4 with PatchContext

use of org.opendaylight.restconf.common.patch.PatchContext in project netconf by opendaylight.

the class JSONRestconfServiceImpl method patch.

@SuppressWarnings("checkstyle:IllegalCatch")
@Override
public Optional<String> patch(final String uriPath, final String payload) throws OperationFailedException {
    String output = null;
    requireNonNull(payload, "payload can't be null");
    LOG.debug("patch: uriPath: {}, payload: {}", uriPath, payload);
    final InputStream entityStream = new ByteArrayInputStream(payload.getBytes(StandardCharsets.UTF_8));
    JsonToPatchBodyReader jsonToPatchBodyReader = new JsonToPatchBodyReader(controllerContext);
    final PatchContext context = jsonToPatchBodyReader.readFrom(uriPath, entityStream);
    LOG.debug("Parsed YangInstanceIdentifier: {}", context.getInstanceIdentifierContext().getInstanceIdentifier());
    LOG.debug("Parsed NormalizedNode: {}", context.getData());
    try {
        PatchStatusContext patchStatusContext = restconfService.patchConfigurationData(context, new SimpleUriInfo(uriPath));
        output = toJson(patchStatusContext);
    } catch (final Exception e) {
        propagateExceptionAs(uriPath, e, "PATCH");
    }
    return Optional.ofNullable(output);
}
Also used : JsonToPatchBodyReader(org.opendaylight.netconf.sal.rest.impl.JsonToPatchBodyReader) PatchStatusContext(org.opendaylight.restconf.common.patch.PatchStatusContext) PatchContext(org.opendaylight.restconf.common.patch.PatchContext) ByteArrayInputStream(java.io.ByteArrayInputStream) ByteArrayInputStream(java.io.ByteArrayInputStream) InputStream(java.io.InputStream) SimpleUriInfo(org.opendaylight.restconf.common.util.SimpleUriInfo) IOException(java.io.IOException) OperationFailedException(org.opendaylight.yangtools.yang.common.OperationFailedException) RestconfDocumentedException(org.opendaylight.restconf.common.errors.RestconfDocumentedException)

Example 5 with PatchContext

use of org.opendaylight.restconf.common.patch.PatchContext in project netconf by opendaylight.

the class TestXmlPatchBodyReader method moduleDataAbsoluteTargetPathTest.

/**
 * Test of Yang Patch with absolute target path.
 */
@Test
public void moduleDataAbsoluteTargetPathTest() throws Exception {
    final String uri = "";
    mockBodyReader(uri, xmlToPatchBodyReader, false);
    final InputStream inputStream = TestXmlBodyReader.class.getResourceAsStream("/instanceidentifier/xml/xmlPATCHdataAbsoluteTargetPath.xml");
    final PatchContext returnValue = xmlToPatchBodyReader.readFrom(null, null, null, mediaType, null, inputStream);
    checkPatchContext(returnValue);
}
Also used : PatchContext(org.opendaylight.restconf.common.patch.PatchContext) InputStream(java.io.InputStream) Test(org.junit.Test)

Aggregations

PatchContext (org.opendaylight.restconf.common.patch.PatchContext)42 Test (org.junit.Test)36 InputStream (java.io.InputStream)31 PatchEntity (org.opendaylight.restconf.common.patch.PatchEntity)11 ArrayList (java.util.ArrayList)9 InstanceIdentifierContext (org.opendaylight.restconf.common.context.InstanceIdentifierContext)9 PatchStatusContext (org.opendaylight.restconf.common.patch.PatchStatusContext)7 AbstractBodyReaderTest (org.opendaylight.restconf.nb.rfc8040.jersey.providers.test.AbstractBodyReaderTest)7 JsonBodyReaderTest (org.opendaylight.restconf.nb.rfc8040.jersey.providers.test.JsonBodyReaderTest)6 YangInstanceIdentifier (org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier)5 IOException (java.io.IOException)4 RestconfDocumentedException (org.opendaylight.restconf.common.errors.RestconfDocumentedException)4 MdsalRestconfStrategy (org.opendaylight.restconf.nb.rfc8040.rests.transactions.MdsalRestconfStrategy)4 NetconfRestconfStrategy (org.opendaylight.restconf.nb.rfc8040.rests.transactions.NetconfRestconfStrategy)4 URISyntaxException (java.net.URISyntaxException)3 WebApplicationException (javax.ws.rs.WebApplicationException)3 ParserConfigurationException (javax.xml.parsers.ParserConfigurationException)3 XMLStreamException (javax.xml.stream.XMLStreamException)3 DefaultDOMRpcResult (org.opendaylight.mdsal.dom.spi.DefaultDOMRpcResult)3 Verify.verify (com.google.common.base.Verify.verify)2