Bug 5509: HTTP Patch in Restconf doesn't support general absolute or relative target... 77/36177/6
authorMartin Ciglan <mciglan@cisco.com>
Mon, 14 Mar 2016 08:17:57 +0000 (09:17 +0100)
committerMartin Ciglan <mciglan@cisco.com>
Wed, 6 Apr 2016 09:14:10 +0000 (09:14 +0000)
Absolute or relative input URI and PATCH target JSON support

Change-Id: I86821e59581968cef5f11ec34ce98757909f7c36
Signed-off-by: Martin Ciglan <mciglan@cisco.com>
opendaylight/restconf/sal-rest-connector/src/main/java/org/opendaylight/netconf/sal/rest/impl/JsonToPATCHBodyReader.java
opendaylight/restconf/sal-rest-connector/src/test/resources/instanceidentifier/json/jsonPATCHdata.json

index 6d3f7ea34feab0c101cd7b6b08a98b4b79a34b24..721900ec55165f7c58ff6efd12c3b27e805599f9 100644 (file)
@@ -36,19 +36,18 @@ import org.opendaylight.netconf.sal.restconf.impl.PATCHEntity;
 import org.opendaylight.netconf.sal.restconf.impl.RestconfDocumentedException;
 import org.opendaylight.netconf.sal.restconf.impl.RestconfError.ErrorTag;
 import org.opendaylight.netconf.sal.restconf.impl.RestconfError.ErrorType;
-import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
 import org.opendaylight.yangtools.yang.data.codec.gson.JsonParserStream;
 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter;
 import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeResult;
 import org.opendaylight.yangtools.yang.data.impl.schema.ResultAlreadySetException;
-import org.opendaylight.yangtools.yang.data.util.AbstractStringInstanceIdentifierCodec;
+import org.opendaylight.yangtools.yang.data.util.AbstractModuleStringInstanceIdentifierCodec;
 import org.opendaylight.yangtools.yang.data.util.DataSchemaContextTree;
-import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaNode;
+import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -137,36 +136,27 @@ public class JsonToPATCHBodyReader extends AbstractIdentifierAwareJaxRsProvider
                     break;
                 case BEGIN_OBJECT:
                     if (inEdit && operation != null & target != null & inValue) {
-                        //let's do the stuff - find out target node
-//                      StringInstanceIdentifierCodec codec = new StringInstanceIdentifierCodec(path
-//                               .getSchemaContext());
-//                        if (path.getInstanceIdentifier().toString().equals("/")) {
-//                        final YangInstanceIdentifier deserialized = codec.deserialize(target);
-//                        }
-                        DataSchemaNode targetNode = ((DataNodeContainer)(path.getSchemaNode())).getDataChildByName
-                                (target.replace("/", ""));
-                        if (targetNode == null) {
-                            LOG.debug("Target node {} not found in path {} ", target, path.getSchemaNode());
-                            throw new RestconfDocumentedException("Error parsing input", ErrorType.PROTOCOL,
-                                    ErrorTag.MALFORMED_MESSAGE);
-                        } else {
-
-                            final NormalizedNodeResult resultHolder = new NormalizedNodeResult();
-                            final NormalizedNodeStreamWriter writer = ImmutableNormalizedNodeStreamWriter.from(resultHolder);
-
-                            //keep on parsing json from place where target points
-                            final JsonParserStream jsonParser = JsonParserStream.create(writer, path.getSchemaContext(),
-                                    path.getSchemaNode());
-                            jsonParser.parse(in);
-
-                            final YangInstanceIdentifier targetII = path.getInstanceIdentifier().node(targetNode.getQName());
-                            resultCollection.add(new PATCHEntity(editId, operation, targetII, resultHolder.getResult
-                                    ()));
-                            inValue = false;
-
-                            operation = null;
-                            target = null;
-                        }
+                        StringModuleInstanceIdentifierCodec codec = new StringModuleInstanceIdentifierCodec(path
+                              .getSchemaContext());
+
+                        YangInstanceIdentifier targetII = codec.deserialize(codec.serialize(path
+                                .getInstanceIdentifier()) + target);
+                        SchemaNode targetSchemaNode = SchemaContextUtil.findDataSchemaNode(path.getSchemaContext(),
+                                codec.getDataContextTree().getChild(targetII).getDataSchemaNode().getPath()
+                                        .getParent());
+
+                        final NormalizedNodeResult resultHolder = new NormalizedNodeResult();
+                        final NormalizedNodeStreamWriter writer = ImmutableNormalizedNodeStreamWriter.from(resultHolder);
+
+                        //keep on parsing json from place where target points
+                        final JsonParserStream jsonParser = JsonParserStream.create(writer, path.getSchemaContext(),
+                                targetSchemaNode);
+                        jsonParser.parse(in);
+                        resultCollection.add(new PATCHEntity(editId, operation, targetII.getParent(), resultHolder.getResult()));
+                        inValue = false;
+
+                        operation = null;
+                        target = null;
                         in.endObject();
                     } else {
                         in.beginObject();
@@ -207,16 +197,21 @@ public class JsonToPATCHBodyReader extends AbstractIdentifierAwareJaxRsProvider
         return ImmutableList.copyOf(resultCollection);
     }
 
-    private class StringInstanceIdentifierCodec extends AbstractStringInstanceIdentifierCodec {
+    private class StringModuleInstanceIdentifierCodec extends AbstractModuleStringInstanceIdentifierCodec {
 
         private final DataSchemaContextTree dataContextTree;
         private final SchemaContext context;
 
-        StringInstanceIdentifierCodec(SchemaContext context) {
+        StringModuleInstanceIdentifierCodec(SchemaContext context) {
             this.context = Preconditions.checkNotNull(context);
             this.dataContextTree = DataSchemaContextTree.from(context);
         }
 
+        @Override
+        protected Module moduleForPrefix(@Nonnull String prefix) {
+            return context.findModuleByName(prefix, null);
+        }
+
         @Nonnull
         @Override
         protected DataSchemaContextTree getDataContextTree() {
@@ -229,12 +224,5 @@ public class JsonToPATCHBodyReader extends AbstractIdentifierAwareJaxRsProvider
             final Module module = context.findModuleByNamespaceAndRevision(namespace, null);
             return module == null ? null : module.getName();
         }
-
-        @Nullable
-        @Override
-        protected QName createQName(@Nonnull String prefix, @Nonnull String localName) {
-            throw new UnsupportedOperationException("Not implemented");
-        }
-
     }
 }
index cf1530ec4c437e8d58ba4929409be70bb9f6ae1f..e254502ff8e73831bc56f5e2cc811221f794a5ca 100644 (file)
@@ -6,8 +6,8 @@
     "edit" : [
       {
         "edit-id": "edit1",
-        "operation": "create",
-        "target": "/my-list2",
+        "operation": "replace",
+        "target": "/instance-identifier-patch-module:my-list2[instance-identifier-patch-module:name='my-leaf20']",
         "value": {
           "my-list2": {
             "name": "my-leaf20",
 
       {
         "edit-id": "edit2",
-        "operation": "create",
-        "target": "/my-list2",
+        "operation": "replace",
+        "target": "/instance-identifier-patch-module:my-list2[instance-identifier-patch-module:name='my-leaf20']",
         "value": {
           "my-list2": {
-            "name": "my-leaf21",
+            "name": "my-leaf20",
             "my-leaf21": "I am leaf21-1",
             "my-leaf22": "I am leaf22-1"
           }
@@ -31,4 +31,4 @@
       }
     ]
   }
-}
+}
\ No newline at end of file