Bug 6848 - repackage providers for jersey+create xml 49/46549/12
authorJakub Toth <jatoth@cisco.com>
Wed, 5 Oct 2016 12:56:08 +0000 (14:56 +0200)
committerJakub Toth <jatoth@cisco.com>
Tue, 11 Oct 2016 14:22:24 +0000 (14:22 +0000)
and json reader for restconf draft17

  *fix tests
  *rename tests part from draft11 to draft17

Change-Id: I1315bb693eccc34c78f07ea0acbf45f6ff972455
Signed-off-by: Jakub Toth <jatoth@cisco.com>
22 files changed:
restconf/sal-rest-connector/src/main/java/org/opendaylight/netconf/sal/rest/impl/AbstractIdentifierAwareJaxRsProvider.java
restconf/sal-rest-connector/src/main/java/org/opendaylight/netconf/sal/rest/impl/JsonNormalizedNodeBodyReader.java
restconf/sal-rest-connector/src/main/java/org/opendaylight/netconf/sal/rest/impl/JsonToPATCHBodyReader.java
restconf/sal-rest-connector/src/main/java/org/opendaylight/netconf/sal/rest/impl/StringModuleInstanceIdentifierCodec.java
restconf/sal-rest-connector/src/main/java/org/opendaylight/netconf/sal/rest/impl/XmlNormalizedNodeBodyReader.java
restconf/sal-rest-connector/src/main/java/org/opendaylight/netconf/sal/rest/impl/XmlToPATCHBodyReader.java
restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/RestconfApplication.java
restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/jersey/providers/AbstractIdentifierAwareJaxRsProvider.java [moved from restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/utils/patch/AbstractIdentifierAwareJaxRsProvider.java with 86% similarity]
restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/jersey/providers/JsonNormalizedNodeBodyReader.java [new file with mode: 0644]
restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/jersey/providers/JsonToPATCHBodyReader.java [moved from restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/utils/patch/JsonToPATCHBodyReader.java with 99% similarity]
restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/jersey/providers/StringModuleInstanceIdentifierCodec.java [moved from restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/utils/patch/StringModuleInstanceIdentifierCodec.java with 97% similarity]
restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/jersey/providers/XmlNormalizedNodeBodyReader.java [new file with mode: 0644]
restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/jersey/providers/XmlToPATCHBodyReader.java [moved from restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/utils/patch/XmlToPATCHBodyReader.java with 99% similarity]
restconf/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/rest/impl/test/providers/AbstractBodyReaderTest.java
restconf/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/rest/impl/test/providers/Draft17AbstractBodyReaderTest.java [moved from restconf/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/rest/impl/test/providers/Draft11AbstractBodyReaderTest.java with 95% similarity]
restconf/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/rest/impl/test/providers/Draft17JsonBodyReaderTest.java [new file with mode: 0644]
restconf/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/rest/impl/test/providers/Draft17XmlBodyReaderTest.java [new file with mode: 0644]
restconf/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/rest/impl/test/providers/TestDraft17JsonPATCHBodyReader.java [moved from restconf/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/rest/impl/test/providers/TestDraft11JsonPATCHBodyReader.java with 97% similarity]
restconf/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/rest/impl/test/providers/TestDraft17XmlPATCHBodyReader.java [moved from restconf/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/rest/impl/test/providers/TestDraft11XmlPATCHBodyReader.java with 97% similarity]
restconf/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/nn/test/JsonIdentityrefToNnTest.java
restconf/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/nn/test/JsonLeafrefToNnTest.java
restconf/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/nn/test/JsonToNnTest.java

index caa4726d5c0ac8ba822ad8c249373e95ea786be9..49072d83395cb683d21f9508b59349dc760e32f0 100644 (file)
@@ -17,7 +17,7 @@ import org.opendaylight.netconf.sal.restconf.impl.InstanceIdentifierContext;
 
 /**
  * @deprecated This class will be replaced by
- *             {@link org.opendaylight.restconf.utils.patch.AbstractIdentifierAwareJaxRsProvider}
+ *             {@link org.opendaylight.restconf.jersey.providers.AbstractIdentifierAwareJaxRsProvider}
  */
 @Deprecated
 public class AbstractIdentifierAwareJaxRsProvider {
@@ -45,4 +45,8 @@ public class AbstractIdentifierAwareJaxRsProvider {
     protected boolean isPost() {
         return POST.equals(this.request.getMethod());
     }
+
+    Request getRequest() {
+        return this.request;
+    }
 }
index ea51998d9f06d2199054f23dcadae0e7010c0ca8..373dbb5adc3bbf5d95d3365d17efefc96af33b65 100644 (file)
@@ -70,7 +70,14 @@ public class JsonNormalizedNodeBodyReader extends AbstractIdentifierAwareJaxRsPr
             final MultivaluedMap<String, String> httpHeaders, final InputStream entityStream) throws IOException,
             WebApplicationException {
         try {
-            return readFrom(getInstanceIdentifierContext(), entityStream, isPost());
+            if(getUriInfo().getAbsolutePath().getPath().contains("restconf/16")){
+                final org.opendaylight.restconf.jersey.providers.JsonNormalizedNodeBodyReader jsonReaderNewRest =
+                        new org.opendaylight.restconf.jersey.providers.JsonNormalizedNodeBodyReader();
+                jsonReaderNewRest.injectParams(getUriInfo(), getRequest());
+                return jsonReaderNewRest.readFrom(type, genericType, annotations, mediaType, httpHeaders, entityStream);
+            } else {
+                return readFrom(getInstanceIdentifierContext(), entityStream, isPost());
+            }
         } catch (final Exception e) {
             propagateExceptionAs(e);
             return null; // no-op
index 75240378cb99c6e174ac99523a6d670310c23ba1..ffb47bd352159540e3ca24c960d6263898977f82 100644 (file)
@@ -52,7 +52,7 @@ import org.slf4j.LoggerFactory;
 
 /**
  * @deprecated This class will be replaced by
- *             {@link org.opendaylight.restconf.utils.patch.JsonToPATCHBodyReader}
+ *             {@link org.opendaylight.restconf.jersey.providers.JsonToPATCHBodyReader}
  */
 @Deprecated
 @Provider
index 63fe1a6ffb50236af95b812ac0c76e72a5874893..083090492403096fe35adbf21dbf66b9139b8713 100644 (file)
@@ -19,7 +19,7 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
 /**
  * @deprecated This class will be replaced by
- *             {@link org.opendaylight.restconf.utils.patch.StringModuleInstanceIdentifierCodec}
+ *             {@link org.opendaylight.restconf.jersey.providers.StringModuleInstanceIdentifierCodec}
  */
 @Deprecated
 public final class StringModuleInstanceIdentifierCodec extends AbstractModuleStringInstanceIdentifierCodec {
index 72f86c6d058c61a02de47f2d257d7df1db285918..37baa231e71fb96c753e03983d9e22189dedc510 100644 (file)
@@ -34,8 +34,6 @@ import org.opendaylight.netconf.sal.restconf.impl.NormalizedNodeContext;
 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.restconf.Draft17;
-import org.opendaylight.restconf.utils.RestconfConstants;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlUtils;
@@ -55,10 +53,11 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
+import org.xml.sax.SAXException;
 
 @Provider
 @Consumes({ Draft02.MediaTypes.DATA + RestconfService.XML, Draft02.MediaTypes.OPERATION + RestconfService.XML,
-        Draft17.MediaTypes.DATA + RestconfConstants.XML, MediaType.APPLICATION_XML, MediaType.TEXT_XML })
+        MediaType.APPLICATION_XML, MediaType.TEXT_XML })
 public class XmlNormalizedNodeBodyReader extends AbstractIdentifierAwareJaxRsProvider implements MessageBodyReader<NormalizedNodeContext> {
 
     private final static Logger LOG = LoggerFactory.getLogger(XmlNormalizedNodeBodyReader.class);
@@ -94,22 +93,14 @@ public class XmlNormalizedNodeBodyReader extends AbstractIdentifierAwareJaxRsPro
             final MultivaluedMap<String, String> httpHeaders, final InputStream entityStream) throws IOException,
             WebApplicationException {
         try {
-            final InstanceIdentifierContext<?> path = getInstanceIdentifierContext();
-
-            if (entityStream.available() < 1) {
-                // represent empty nopayload input
-                return new NormalizedNodeContext(path, null);
-            }
-
-            final DocumentBuilder dBuilder;
-            try {
-                dBuilder = BUILDERFACTORY.newDocumentBuilder();
-            } catch (final ParserConfigurationException e) {
-                throw new RuntimeException("Failed to parse XML document", e);
+            if (getUriInfo().getAbsolutePath().getPath().contains("restconf/16")) {
+                final org.opendaylight.restconf.jersey.providers.XmlNormalizedNodeBodyReader xmlReaderNewRest =
+                        new org.opendaylight.restconf.jersey.providers.XmlNormalizedNodeBodyReader();
+                xmlReaderNewRest.injectParams(getUriInfo(), getRequest());
+                return xmlReaderNewRest.readFrom(type, genericType, annotations, mediaType, httpHeaders, entityStream);
+            } else {
+                return readFrom(entityStream);
             }
-            final Document doc = dBuilder.parse(entityStream);
-
-            return parse(path,doc);
         } catch (final RestconfDocumentedException e){
             throw e;
         } catch (final Exception e) {
@@ -120,6 +111,25 @@ public class XmlNormalizedNodeBodyReader extends AbstractIdentifierAwareJaxRsPro
         }
     }
 
+    private NormalizedNodeContext readFrom(final InputStream entityStream) throws IOException, SAXException {
+        final InstanceIdentifierContext<?> path = getInstanceIdentifierContext();
+
+        if (entityStream.available() < 1) {
+            // represent empty nopayload input
+            return new NormalizedNodeContext(path, null);
+        }
+
+        final DocumentBuilder dBuilder;
+        try {
+            dBuilder = BUILDERFACTORY.newDocumentBuilder();
+        } catch (final ParserConfigurationException e) {
+            throw new RuntimeException("Failed to parse XML document", e);
+        }
+        final Document doc = dBuilder.parse(entityStream);
+
+        return parse(path,doc);
+    }
+
     private NormalizedNodeContext parse(final InstanceIdentifierContext<?> pathContext,final Document doc) {
 
         final List<Element> elements = Collections.singletonList(doc.getDocumentElement());
index 7c82d01d9aab2f280a552fc0f02113b982d5be63..d203de59edda5f23f88742c4d82e32a6a58e295f 100644 (file)
@@ -59,7 +59,7 @@ import org.w3c.dom.NodeList;
 
 /**
  * @deprecated This class will be replaced by
- *             {@link org.opendaylight.restconf.utils.patch.XmlToPATCHBodyReader}
+ *             {@link org.opendaylight.restconf.jersey.providers.XmlToPATCHBodyReader}
  */
 @Deprecated
 @Provider
index e9585f4c4aceed9f3ed22c415c13cb34cd38ef3d..14b808205594a29aa48fef707d29fffcfa92fdeb 100644 (file)
@@ -21,8 +21,8 @@ import org.opendaylight.netconf.sal.rest.impl.PATCHXmlBodyWriter;
 import org.opendaylight.netconf.sal.rest.impl.RestconfDocumentedExceptionMapper;
 import org.opendaylight.netconf.sal.rest.impl.XmlNormalizedNodeBodyReader;
 import org.opendaylight.restconf.common.wrapper.services.ServicesWrapperImpl;
-import org.opendaylight.restconf.utils.patch.JsonToPATCHBodyReader;
-import org.opendaylight.restconf.utils.patch.XmlToPATCHBodyReader;
+import org.opendaylight.restconf.jersey.providers.JsonToPATCHBodyReader;
+import org.opendaylight.restconf.jersey.providers.XmlToPATCHBodyReader;
 
 public class RestconfApplication extends Application {
 
@@ -6,7 +6,7 @@
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
 
-package org.opendaylight.restconf.utils.patch;
+package org.opendaylight.restconf.jersey.providers;
 
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.Request;
@@ -42,4 +42,12 @@ public class AbstractIdentifierAwareJaxRsProvider {
     protected boolean isPost() {
         return POST.equals(this.request.getMethod());
     }
+
+    void setUriInfo(final UriInfo uriInfo) {
+        this.uriInfo = uriInfo;
+    }
+
+    void setRequest(final Request request) {
+        this.request = request;
+    }
 }
diff --git a/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/jersey/providers/JsonNormalizedNodeBodyReader.java b/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/jersey/providers/JsonNormalizedNodeBodyReader.java
new file mode 100644 (file)
index 0000000..4fa9576
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.restconf.jersey.providers;
+
+import com.google.common.collect.Iterables;
+import com.google.gson.stream.JsonReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.List;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Request;
+import javax.ws.rs.core.UriInfo;
+import javax.ws.rs.ext.MessageBodyReader;
+import javax.ws.rs.ext.Provider;
+import org.opendaylight.netconf.sal.restconf.impl.InstanceIdentifierContext;
+import org.opendaylight.netconf.sal.restconf.impl.NormalizedNodeContext;
+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.restconf.Draft17;
+import org.opendaylight.restconf.utils.RestconfConstants;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
+import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+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.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Provider
+@Consumes({ Draft17.MediaTypes.DATA + RestconfConstants.JSON, MediaType.APPLICATION_JSON })
+public class JsonNormalizedNodeBodyReader extends AbstractIdentifierAwareJaxRsProvider implements MessageBodyReader<NormalizedNodeContext> {
+
+    private final static Logger LOG = LoggerFactory.getLogger(JsonNormalizedNodeBodyReader.class);
+
+    @Override
+    public boolean isReadable(final Class<?> type, final Type genericType, final Annotation[] annotations,
+            final MediaType mediaType) {
+        return true;
+    }
+
+    @Override
+    public NormalizedNodeContext readFrom(final Class<NormalizedNodeContext> type, final Type genericType,
+            final Annotation[] annotations, final MediaType mediaType,
+            final MultivaluedMap<String, String> httpHeaders, final InputStream entityStream) throws IOException,
+            WebApplicationException {
+        try {
+            return readFrom(getInstanceIdentifierContext(), entityStream, isPost());
+        } catch (final Exception e) {
+            propagateExceptionAs(e);
+            return null;
+        }
+    }
+
+    private static void propagateExceptionAs(final Exception e) throws RestconfDocumentedException {
+        if(e instanceof RestconfDocumentedException) {
+            throw (RestconfDocumentedException)e;
+        }
+
+        if(e instanceof ResultAlreadySetException) {
+            LOG.debug("Error parsing json input:", e);
+
+            throw new RestconfDocumentedException("Error parsing json input: Failed to create new parse result data. " +
+                    "Are you creating multiple resources/subresources in POST request?");
+        }
+
+        LOG.debug("Error parsing json input", e);
+
+        throw new RestconfDocumentedException("Error parsing input: " + e.getMessage(), ErrorType.PROTOCOL,
+                ErrorTag.MALFORMED_MESSAGE, e);
+    }
+
+    private static NormalizedNodeContext readFrom(final InstanceIdentifierContext<?> path, final InputStream entityStream,
+            final boolean isPost) throws IOException {
+        if (entityStream.available() < 1) {
+            return new NormalizedNodeContext(path, null);
+        }
+        final NormalizedNodeResult resultHolder = new NormalizedNodeResult();
+        final NormalizedNodeStreamWriter writer = ImmutableNormalizedNodeStreamWriter.from(resultHolder);
+
+        final SchemaNode parentSchema;
+        if(isPost) {
+            parentSchema = path.getSchemaNode();
+        } else if(path.getSchemaNode() instanceof SchemaContext) {
+            parentSchema = path.getSchemaContext();
+        } else {
+            if (SchemaPath.ROOT.equals(path.getSchemaNode().getPath().getParent())) {
+                parentSchema = path.getSchemaContext();
+            } else {
+                parentSchema = SchemaContextUtil.findDataSchemaNode(path.getSchemaContext(), path.getSchemaNode().getPath().getParent());
+            }
+        }
+
+        final JsonParserStream jsonParser = JsonParserStream.create(writer, path.getSchemaContext(), parentSchema);
+        final JsonReader reader = new JsonReader(new InputStreamReader(entityStream));
+        jsonParser.parse(reader);
+
+        NormalizedNode<?, ?> result = resultHolder.getResult();
+        final List<YangInstanceIdentifier.PathArgument> iiToDataList = new ArrayList<>();
+        InstanceIdentifierContext<? extends SchemaNode> newIIContext;
+
+        while ((result instanceof AugmentationNode) || (result instanceof ChoiceNode)) {
+            final Object childNode = ((DataContainerNode) result).getValue().iterator().next();
+            if (isPost) {
+                iiToDataList.add(result.getIdentifier());
+            }
+            result = (NormalizedNode<?, ?>) childNode;
+        }
+
+        if (isPost) {
+            if (result instanceof MapEntryNode) {
+                iiToDataList.add(new YangInstanceIdentifier.NodeIdentifier(result.getNodeType()));
+                iiToDataList.add(result.getIdentifier());
+            } else {
+                iiToDataList.add(result.getIdentifier());
+            }
+        } else {
+            if (result instanceof MapNode) {
+                result = Iterables.getOnlyElement(((MapNode) result).getValue());
+            }
+        }
+
+        final YangInstanceIdentifier fullIIToData = YangInstanceIdentifier.create(Iterables.concat(
+                path.getInstanceIdentifier().getPathArguments(), iiToDataList));
+
+        newIIContext = new InstanceIdentifierContext<>(fullIIToData, path.getSchemaNode(), path.getMountPoint(),
+                path.getSchemaContext());
+
+        return new NormalizedNodeContext(newIIContext, result);
+    }
+
+    public void injectParams(final UriInfo uriInfo, final Request request) {
+        setUriInfo(uriInfo);
+        setRequest(request);
+    }
+}
+
similarity index 99%
rename from restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/utils/patch/JsonToPATCHBodyReader.java
rename to restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/jersey/providers/JsonToPATCHBodyReader.java
index ac50c47ce0b531fbf9551769ce757c6c45cf6041..b0f50a6aa046a188903dc183ae57c8af788b1362 100644 (file)
@@ -6,7 +6,7 @@
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
 
-package org.opendaylight.restconf.utils.patch;
+package org.opendaylight.restconf.jersey.providers;
 
 import static org.opendaylight.netconf.sal.restconf.impl.PATCHEditOperation.isPatchOperationWithValue;
 
diff --git a/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/jersey/providers/XmlNormalizedNodeBodyReader.java b/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/jersey/providers/XmlNormalizedNodeBodyReader.java
new file mode 100644 (file)
index 0000000..8ea2f92
--- /dev/null
@@ -0,0 +1,246 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.restconf.jersey.providers;
+
+import com.google.common.collect.Iterables;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Deque;
+import java.util.List;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Request;
+import javax.ws.rs.core.UriInfo;
+import javax.ws.rs.ext.MessageBodyReader;
+import javax.ws.rs.ext.Provider;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import org.opendaylight.netconf.sal.restconf.impl.InstanceIdentifierContext;
+import org.opendaylight.netconf.sal.restconf.impl.NormalizedNodeContext;
+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.restconf.Draft17;
+import org.opendaylight.restconf.utils.RestconfConstants;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlUtils;
+import org.opendaylight.yangtools.yang.data.impl.schema.SchemaUtils;
+import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser.DomToNormalizedNodeParserFactory;
+import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
+import org.opendaylight.yangtools.yang.model.api.AugmentationTarget;
+import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
+import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
+import org.opendaylight.yangtools.yang.model.api.SchemaNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+@Provider
+@Consumes({ Draft17.MediaTypes.DATA + RestconfConstants.XML, MediaType.APPLICATION_XML, MediaType.TEXT_XML })
+public class XmlNormalizedNodeBodyReader extends AbstractIdentifierAwareJaxRsProvider implements MessageBodyReader<NormalizedNodeContext> {
+
+    private final static Logger LOG = LoggerFactory.getLogger(XmlNormalizedNodeBodyReader.class);
+    private static final DocumentBuilderFactory BUILDERFACTORY;
+
+    static {
+        final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        try {
+            factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
+            factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
+            factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
+            factory.setXIncludeAware(false);
+            factory.setExpandEntityReferences(false);
+        } catch (final ParserConfigurationException e) {
+            throw new ExceptionInInitializerError(e);
+        }
+        factory.setNamespaceAware(true);
+        factory.setCoalescing(true);
+        factory.setIgnoringElementContentWhitespace(true);
+        factory.setIgnoringComments(true);
+        BUILDERFACTORY = factory;
+    }
+
+    @Override
+    public boolean isReadable(final Class<?> type, final Type genericType, final Annotation[] annotations,
+            final MediaType mediaType) {
+        return true;
+    }
+
+    @Override
+    public NormalizedNodeContext readFrom(final Class<NormalizedNodeContext> type, final Type genericType,
+            final Annotation[] annotations, final MediaType mediaType,
+            final MultivaluedMap<String, String> httpHeaders, final InputStream entityStream) throws IOException,
+            WebApplicationException {
+        try {
+            final InstanceIdentifierContext<?> path = getInstanceIdentifierContext();
+
+            if (entityStream.available() < 1) {
+                // represent empty nopayload input
+                return new NormalizedNodeContext(path, null);
+            }
+
+            final DocumentBuilder dBuilder;
+            try {
+                dBuilder = BUILDERFACTORY.newDocumentBuilder();
+            } catch (final ParserConfigurationException e) {
+                throw new RuntimeException("Failed to parse XML document", e);
+            }
+            final Document doc = dBuilder.parse(entityStream);
+
+            return parse(path,doc);
+        } catch (final RestconfDocumentedException e){
+            throw e;
+        } catch (final Exception e) {
+            LOG.debug("Error parsing xml input", e);
+
+            throw new RestconfDocumentedException("Error parsing input: " + e.getMessage(), ErrorType.PROTOCOL,
+                    ErrorTag.MALFORMED_MESSAGE);
+        }
+    }
+
+    private NormalizedNodeContext parse(final InstanceIdentifierContext<?> pathContext,final Document doc) {
+
+        final List<Element> elements = Collections.singletonList(doc.getDocumentElement());
+        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<>();
+        InstanceIdentifierContext<? extends SchemaNode> outIIContext;
+
+
+        final DomToNormalizedNodeParserFactory parserFactory =
+                DomToNormalizedNodeParserFactory.getInstance(XmlUtils.DEFAULT_XML_CODEC_PROVIDER, pathContext.getSchemaContext());
+
+        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 AugmentationSchema) {
+                    final AugmentationSchema augmentSchemaNode = (AugmentationSchema) child;
+                    iiToDataList.add(SchemaUtils.getNodeIdentifierForAugmentation(augmentSchemaNode));
+                } else if (child instanceof DataSchemaNode) {
+                    schemaNode = (DataSchemaNode) child;
+                    iiToDataList.add(new YangInstanceIdentifier.NodeIdentifier(schemaNode.getQName()));
+                }
+            }
+        }
+
+        NormalizedNode<?, ?> parsed = null;
+
+        if (schemaNode instanceof ContainerSchemaNode) {
+            parsed = parserFactory.getContainerNodeParser().parse(Collections.singletonList(doc.getDocumentElement()), (ContainerSchemaNode) schemaNode);
+        } else if(schemaNode instanceof ListSchemaNode) {
+            final ListSchemaNode casted = (ListSchemaNode) schemaNode;
+            parsed = parserFactory.getMapEntryNodeParser().parse(elements, casted);
+            if (isPost()) {
+                iiToDataList.add(parsed.getIdentifier());
+            }
+        }
+
+        final YangInstanceIdentifier fullIIToData = YangInstanceIdentifier.create(Iterables.concat(
+                pathContext.getInstanceIdentifier().getPathArguments(), iiToDataList));
+
+        outIIContext = new InstanceIdentifierContext<>(fullIIToData, pathContext.getSchemaNode(), pathContext.getMountPoint(),
+                pathContext.getSchemaContext());
+
+        return new NormalizedNodeContext(outIIContext, parsed);
+    }
+
+    private static Deque<Object> findPathToSchemaNodeByName(final DataSchemaNode schemaNode, final String elementName,
+                                                            final String namespace) {
+        final Deque<Object> result = new ArrayDeque<>();
+        final ArrayList<ChoiceSchemaNode> choiceSchemaNodes = new ArrayList<>();
+        final Collection<DataSchemaNode> children = ((DataNodeContainer) schemaNode).getChildNodes();
+        for (final DataSchemaNode child : children) {
+            if (child instanceof ChoiceSchemaNode) {
+                choiceSchemaNodes.add((ChoiceSchemaNode) child);
+            } else if (child.getQName().getLocalName().equalsIgnoreCase(elementName)
+                    && child.getQName().getNamespace().toString().equalsIgnoreCase(namespace)) {
+                // add child to result
+                result.push(child);
+
+                // find augmentation
+                if (child.isAugmenting()) {
+                    final AugmentationSchema augment = findCorrespondingAugment(schemaNode, child);
+                    if (augment != null) {
+                        result.push(augment);
+                    }
+                }
+
+                // return result
+                return result;
+            }
+        }
+
+        for (final ChoiceSchemaNode choiceNode : choiceSchemaNodes) {
+            for (final ChoiceCaseNode caseNode : choiceNode.getCases()) {
+                final Deque<Object> resultFromRecursion = findPathToSchemaNodeByName(caseNode, elementName, namespace);
+                if (!resultFromRecursion.isEmpty()) {
+                    resultFromRecursion.push(choiceNode);
+                    if (choiceNode.isAugmenting()) {
+                        final AugmentationSchema augment = findCorrespondingAugment(schemaNode, choiceNode);
+                        if (augment != null) {
+                            resultFromRecursion.push(augment);
+                        }
+                    }
+                    return resultFromRecursion;
+                }
+            }
+        }
+        return result;
+    }
+
+    private static AugmentationSchema findCorrespondingAugment(final DataSchemaNode parent, final DataSchemaNode child) {
+        if ((parent instanceof AugmentationTarget) && !(parent instanceof ChoiceSchemaNode)) {
+            for (final AugmentationSchema augmentation : ((AugmentationTarget) parent).getAvailableAugmentations()) {
+                final DataSchemaNode childInAugmentation = augmentation.getDataChildByName(child.getQName());
+                if (childInAugmentation != null) {
+                    return augmentation;
+                }
+            }
+        }
+        return null;
+    }
+
+    public void injectParams(final UriInfo uriInfo, final Request request) {
+        setRequest(request);
+        setUriInfo(uriInfo);
+    }
+}
+
similarity index 99%
rename from restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/utils/patch/XmlToPATCHBodyReader.java
rename to restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/jersey/providers/XmlToPATCHBodyReader.java
index 599f7c1a942b389573d689dbf199538f2fb8c265..1f6d5632a9d7e60ba55847e0b4788324ccc625b0 100644 (file)
@@ -6,7 +6,7 @@
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
 
-package org.opendaylight.restconf.utils.patch;
+package org.opendaylight.restconf.jersey.providers;
 
 import com.google.common.base.Splitter;
 import com.google.common.collect.ImmutableList;
index 5184d38e58d82c076d3dc531dae52c882bbf3e37..22c667b35e450753289ec52c255d607da0a921e0 100644 (file)
@@ -11,8 +11,8 @@ package org.opendaylight.controller.sal.rest.impl.test.providers;
 import static org.junit.Assert.assertNotNull;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
-
 import java.lang.reflect.Field;
+import java.net.URI;
 import java.util.Collections;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.MultivaluedHashMap;
@@ -42,7 +42,7 @@ public abstract class AbstractBodyReaderTest {
         requestField = AbstractIdentifierAwareJaxRsProvider.class
                 .getDeclaredField("request");
         requestField.setAccessible(true);
-        mediaType = getMediaType();
+        this.mediaType = getMediaType();
     }
 
     protected abstract MediaType getMediaType();
@@ -52,10 +52,8 @@ public abstract class AbstractBodyReaderTest {
         return TestRestconfUtils.loadSchemaContext(yangPath, schemaContext);
     }
 
-    protected static <T extends AbstractIdentifierAwareJaxRsProvider> void mockBodyReader(
-            final String identifier, final T normalizedNodeProvider,
-            final boolean isPost) throws NoSuchFieldException,
-            SecurityException, IllegalArgumentException, IllegalAccessException {
+    protected static <T extends AbstractIdentifierAwareJaxRsProvider> void mockBodyReader(final String identifier,
+            final T normalizedNodeProvider, final boolean isPost) throws Exception {
         final UriInfo uriInfoMock = mock(UriInfo.class);
         final MultivaluedMap<String, String> pathParm = new MultivaluedHashMap<>(1);
 
@@ -66,6 +64,7 @@ public abstract class AbstractBodyReaderTest {
         when(uriInfoMock.getPathParameters()).thenReturn(pathParm);
         when(uriInfoMock.getPathParameters(false)).thenReturn(pathParm);
         when(uriInfoMock.getPathParameters(true)).thenReturn(pathParm);
+        when(uriInfoMock.getAbsolutePath()).thenReturn(new URI("restconf"));
         uriField.set(normalizedNodeProvider, uriInfoMock);
 
         final Request request = mock(Request.class);
@@ -24,17 +24,17 @@ import org.opendaylight.netconf.sal.rest.api.RestconfConstants;
 import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
 import org.opendaylight.netconf.sal.restconf.impl.NormalizedNodeContext;
 import org.opendaylight.netconf.sal.restconf.impl.PATCHContext;
-import org.opendaylight.restconf.utils.patch.AbstractIdentifierAwareJaxRsProvider;
+import org.opendaylight.restconf.jersey.providers.AbstractIdentifierAwareJaxRsProvider;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
-public abstract class Draft11AbstractBodyReaderTest {
+public abstract class Draft17AbstractBodyReaderTest {
 
     protected final static ControllerContext controllerContext = ControllerContext.getInstance();
     protected final MediaType mediaType;
     private static Field uriField;
     private static Field requestField;
 
-    public Draft11AbstractBodyReaderTest() throws NoSuchFieldException,
+    public Draft17AbstractBodyReaderTest() throws NoSuchFieldException,
             SecurityException {
         uriField = AbstractIdentifierAwareJaxRsProvider.class
                 .getDeclaredField("uriInfo");
diff --git a/restconf/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/rest/impl/test/providers/Draft17JsonBodyReaderTest.java b/restconf/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/rest/impl/test/providers/Draft17JsonBodyReaderTest.java
new file mode 100644 (file)
index 0000000..e49f1e8
--- /dev/null
@@ -0,0 +1,173 @@
+/**
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.rest.impl.test.providers;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.net.URI;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Collection;
+import javax.ws.rs.core.MediaType;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.controller.md.sal.rest.common.TestRestconfUtils;
+import org.opendaylight.netconf.sal.restconf.impl.NormalizedNodeContext;
+import org.opendaylight.restconf.jersey.providers.JsonNormalizedNodeBodyReader;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.QNameModule;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodes;
+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.parser.spi.meta.ReactorException;
+import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
+import com.google.common.collect.Sets;
+
+public class Draft17JsonBodyReaderTest extends Draft17AbstractBodyReaderTest {
+
+    private final JsonNormalizedNodeBodyReader jsonBodyReader;
+    private static SchemaContext schemaContext;
+
+    private static final QNameModule INSTANCE_IDENTIFIER_MODULE_QNAME = initializeInstanceIdentifierModule();
+
+    private static QNameModule initializeInstanceIdentifierModule() {
+        try {
+            return QNameModule.create(URI.create("instance:identifier:module"),
+                    new SimpleDateFormat("yyyy-MM-dd").parse("2014-01-17"));
+        } catch (final ParseException e) {
+            throw new Error(e);
+        }
+    }
+
+    public Draft17JsonBodyReaderTest() throws NoSuchFieldException, SecurityException {
+        super();
+        this.jsonBodyReader = new JsonNormalizedNodeBodyReader();
+    }
+
+    @Override
+    protected MediaType getMediaType() {
+        return new MediaType(MediaType.APPLICATION_XML, null);
+    }
+
+    @BeforeClass
+    public static void initialization()
+            throws NoSuchFieldException, SecurityException, FileNotFoundException, SourceException, ReactorException {
+        final Collection<File> testFiles = TestRestconfUtils.loadFiles("/instanceidentifier/yang");
+        testFiles.addAll(TestRestconfUtils.loadFiles("/modules"));
+        testFiles.addAll(TestRestconfUtils.loadFiles("/invoke-rpc"));
+        schemaContext = TestRestconfUtils.parseYangSources(testFiles);
+        controllerContext.setSchemas(schemaContext);
+    }
+
+    @Test
+    public void moduleDataTest() throws Exception {
+        final DataSchemaNode dataSchemaNode = schemaContext
+                .getDataChildByName(QName.create(INSTANCE_IDENTIFIER_MODULE_QNAME, "cont"));
+        final YangInstanceIdentifier dataII = YangInstanceIdentifier.of(dataSchemaNode.getQName());
+        final String uri = "instance-identifier-module:cont";
+        mockBodyReader(uri, this.jsonBodyReader, false);
+        final InputStream inputStream = Draft17JsonBodyReaderTest.class
+                .getResourceAsStream("/instanceidentifier/json/jsondata.json");
+        final NormalizedNodeContext returnValue = this.jsonBodyReader.readFrom(null, null, null, this.mediaType, null,
+                inputStream);
+        checkNormalizedNodeContext(returnValue);
+        checkExpectValueNormalizeNodeContext(dataSchemaNode, returnValue, dataII);
+    }
+
+    @Test
+    public void moduleSubContainerDataPutTest() throws Exception {
+        final DataSchemaNode dataSchemaNode = schemaContext
+                .getDataChildByName(QName.create(INSTANCE_IDENTIFIER_MODULE_QNAME, "cont"));
+        final QName cont1QName = QName.create(dataSchemaNode.getQName(), "cont1");
+        final YangInstanceIdentifier dataII = YangInstanceIdentifier.of(dataSchemaNode.getQName()).node(cont1QName);
+        final DataSchemaNode dataSchemaNodeOnPath = ((DataNodeContainer) dataSchemaNode).getDataChildByName(cont1QName);
+        final String uri = "instance-identifier-module:cont/cont1";
+        mockBodyReader(uri, this.jsonBodyReader, false);
+        final InputStream inputStream = Draft17JsonBodyReaderTest.class
+                .getResourceAsStream("/instanceidentifier/json/json_sub_container.json");
+        final NormalizedNodeContext returnValue = this.jsonBodyReader.readFrom(null, null, null, this.mediaType, null,
+                inputStream);
+        checkNormalizedNodeContext(returnValue);
+        checkExpectValueNormalizeNodeContext(dataSchemaNodeOnPath, returnValue, dataII);
+    }
+
+    @Test
+    public void moduleSubContainerDataPostTest() throws Exception {
+        final DataSchemaNode dataSchemaNode = schemaContext
+                .getDataChildByName(QName.create(INSTANCE_IDENTIFIER_MODULE_QNAME, "cont"));
+        final QName cont1QName = QName.create(dataSchemaNode.getQName(), "cont1");
+        final YangInstanceIdentifier dataII = YangInstanceIdentifier.of(dataSchemaNode.getQName()).node(cont1QName);
+        final String uri = "instance-identifier-module:cont";
+        mockBodyReader(uri, this.jsonBodyReader, true);
+        final InputStream inputStream = Draft17JsonBodyReaderTest.class
+                .getResourceAsStream("/instanceidentifier/json/json_sub_container.json");
+        final NormalizedNodeContext returnValue = this.jsonBodyReader.readFrom(null, null, null, this.mediaType, null,
+                inputStream);
+        checkNormalizedNodeContext(returnValue);
+        checkExpectValueNormalizeNodeContext(dataSchemaNode, returnValue, dataII);
+    }
+
+    @Test
+    public void moduleSubContainerAugmentDataPostTest() throws Exception {
+        final DataSchemaNode dataSchemaNode = schemaContext
+                .getDataChildByName(QName.create(INSTANCE_IDENTIFIER_MODULE_QNAME, "cont"));
+        final Module augmentModule = schemaContext.findModuleByNamespace(new URI("augment:module")).iterator().next();
+        final QName contAugmentQName = QName.create(augmentModule.getQNameModule(), "cont-augment");
+        final YangInstanceIdentifier.AugmentationIdentifier augII = new YangInstanceIdentifier.AugmentationIdentifier(
+                Sets.newHashSet(contAugmentQName));
+        final YangInstanceIdentifier dataII = YangInstanceIdentifier.of(dataSchemaNode.getQName()).node(augII)
+                .node(contAugmentQName);
+        final String uri = "instance-identifier-module:cont";
+        mockBodyReader(uri, this.jsonBodyReader, true);
+        final InputStream inputStream = TestXmlBodyReader.class
+                .getResourceAsStream("/instanceidentifier/json/json_augment_container.json");
+        final NormalizedNodeContext returnValue = this.jsonBodyReader.readFrom(null, null, null, this.mediaType, null,
+                inputStream);
+        checkNormalizedNodeContext(returnValue);
+        checkExpectValueNormalizeNodeContext(dataSchemaNode, returnValue, dataII);
+    }
+
+    @Test
+    public void moduleSubContainerChoiceAugmentDataPostTest() throws Exception {
+        final DataSchemaNode dataSchemaNode = schemaContext
+                .getDataChildByName(QName.create(INSTANCE_IDENTIFIER_MODULE_QNAME, "cont"));
+        final Module augmentModule = schemaContext.findModuleByNamespace(new URI("augment:module")).iterator().next();
+        final QName augmentChoice1QName = QName.create(augmentModule.getQNameModule(), "augment-choice1");
+        final QName augmentChoice2QName = QName.create(augmentChoice1QName, "augment-choice2");
+        final QName containerQName = QName.create(augmentChoice1QName, "case-choice-case-container1");
+        final YangInstanceIdentifier.AugmentationIdentifier augChoice1II = new YangInstanceIdentifier.AugmentationIdentifier(
+                Sets.newHashSet(augmentChoice1QName));
+        final YangInstanceIdentifier.AugmentationIdentifier augChoice2II = new YangInstanceIdentifier.AugmentationIdentifier(
+                Sets.newHashSet(augmentChoice2QName));
+        final YangInstanceIdentifier dataII = YangInstanceIdentifier.of(dataSchemaNode.getQName()).node(augChoice1II)
+                .node(augmentChoice1QName).node(augChoice2II).node(augmentChoice2QName).node(containerQName);
+        final String uri = "instance-identifier-module:cont";
+        mockBodyReader(uri, this.jsonBodyReader, true);
+        final InputStream inputStream = TestXmlBodyReader.class
+                .getResourceAsStream("/instanceidentifier/json/json_augment_choice_container.json");
+        final NormalizedNodeContext returnValue = this.jsonBodyReader.readFrom(null, null, null, this.mediaType, null,
+                inputStream);
+        checkNormalizedNodeContext(returnValue);
+        checkExpectValueNormalizeNodeContext(dataSchemaNode, returnValue, dataII);
+    }
+
+    private void checkExpectValueNormalizeNodeContext(final DataSchemaNode dataSchemaNode,
+            final NormalizedNodeContext nnContext, final YangInstanceIdentifier dataNodeIdent) {
+        assertEquals(dataSchemaNode, nnContext.getInstanceIdentifierContext().getSchemaNode());
+        assertEquals(dataNodeIdent, nnContext.getInstanceIdentifierContext().getInstanceIdentifier());
+        assertNotNull(NormalizedNodes.findNode(nnContext.getData(), dataNodeIdent));
+    }
+}
\ No newline at end of file
diff --git a/restconf/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/rest/impl/test/providers/Draft17XmlBodyReaderTest.java b/restconf/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/rest/impl/test/providers/Draft17XmlBodyReaderTest.java
new file mode 100644 (file)
index 0000000..a183ead
--- /dev/null
@@ -0,0 +1,214 @@
+/**
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.rest.impl.test.providers;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.File;
+import java.io.InputStream;
+import java.net.URI;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Collection;
+import javax.ws.rs.core.MediaType;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.controller.md.sal.rest.common.TestRestconfUtils;
+import org.opendaylight.netconf.sal.restconf.impl.NormalizedNodeContext;
+import org.opendaylight.restconf.jersey.providers.XmlNormalizedNodeBodyReader;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.QNameModule;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodes;
+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 com.google.common.collect.Sets;
+
+public class Draft17XmlBodyReaderTest extends Draft17AbstractBodyReaderTest {
+
+    private final XmlNormalizedNodeBodyReader xmlBodyReader;
+    private static SchemaContext schemaContext;
+    private static final QNameModule INSTANCE_IDENTIFIER_MODULE_QNAME = initializeInstanceIdentifierModule();
+
+    private static QNameModule initializeInstanceIdentifierModule() {
+        try {
+            return QNameModule.create(URI.create("instance:identifier:module"),
+                    new SimpleDateFormat("yyyy-MM-dd").parse("2014-01-17"));
+        } catch (final ParseException e) {
+            throw new Error(e);
+        }
+    }
+
+    public Draft17XmlBodyReaderTest() throws NoSuchFieldException, SecurityException {
+        super();
+        this.xmlBodyReader = new XmlNormalizedNodeBodyReader();
+    }
+
+    @Override
+    protected MediaType getMediaType() {
+        return new MediaType(MediaType.APPLICATION_XML, null);
+    }
+
+    @BeforeClass
+    public static void initialization() throws Exception {
+        final Collection<File> testFiles = TestRestconfUtils.loadFiles("/instanceidentifier/yang");
+        testFiles.addAll(TestRestconfUtils.loadFiles("/modules"));
+        testFiles.addAll(TestRestconfUtils.loadFiles("/invoke-rpc"));
+        schemaContext = TestRestconfUtils.parseYangSources(testFiles);
+        controllerContext.setSchemas(schemaContext);
+    }
+
+    @Test
+    public void moduleDataTest() throws Exception {
+        final DataSchemaNode dataSchemaNode = schemaContext
+                .getDataChildByName(QName.create(INSTANCE_IDENTIFIER_MODULE_QNAME, "cont"));
+        final YangInstanceIdentifier dataII = YangInstanceIdentifier.of(dataSchemaNode.getQName());
+        final String uri = "instance-identifier-module:cont";
+        mockBodyReader(uri, this.xmlBodyReader, false);
+        final InputStream inputStream = Draft17XmlBodyReaderTest.class
+                .getResourceAsStream("/instanceidentifier/xml/xmldata.xml");
+        final NormalizedNodeContext returnValue = this.xmlBodyReader.readFrom(null, null, null, this.mediaType, null,
+                inputStream);
+        checkNormalizedNodeContext(returnValue);
+        checkExpectValueNormalizeNodeContext(dataSchemaNode, returnValue, dataII);
+    }
+
+    @Test
+    public void moduleSubContainerDataPutTest() throws Exception {
+        final DataSchemaNode dataSchemaNode = schemaContext
+                .getDataChildByName(QName.create(INSTANCE_IDENTIFIER_MODULE_QNAME, "cont"));
+        final QName cont1QName = QName.create(dataSchemaNode.getQName(), "cont1");
+        final YangInstanceIdentifier dataII = YangInstanceIdentifier.of(dataSchemaNode.getQName()).node(cont1QName);
+        final DataSchemaNode dataSchemaNodeOnPath = ((DataNodeContainer) dataSchemaNode).getDataChildByName(cont1QName);
+        final String uri = "instance-identifier-module:cont/cont1";
+        mockBodyReader(uri, this.xmlBodyReader, false);
+        final InputStream inputStream = Draft17XmlBodyReaderTest.class
+                .getResourceAsStream("/instanceidentifier/xml/xml_sub_container.xml");
+        final NormalizedNodeContext returnValue = this.xmlBodyReader.readFrom(null, null, null, this.mediaType, null,
+                inputStream);
+        checkNormalizedNodeContext(returnValue);
+        checkExpectValueNormalizeNodeContext(dataSchemaNodeOnPath, returnValue, dataII);
+    }
+
+    @Test
+    public void moduleSubContainerDataPostTest() throws Exception {
+        final DataSchemaNode dataSchemaNode = schemaContext
+                .getDataChildByName(QName.create(INSTANCE_IDENTIFIER_MODULE_QNAME, "cont"));
+        final QName cont1QName = QName.create(dataSchemaNode.getQName(), "cont1");
+        final YangInstanceIdentifier dataII = YangInstanceIdentifier.of(dataSchemaNode.getQName()).node(cont1QName);
+        final String uri = "instance-identifier-module:cont";
+        mockBodyReader(uri, this.xmlBodyReader, true);
+        final InputStream inputStream = Draft17XmlBodyReaderTest.class
+                .getResourceAsStream("/instanceidentifier/xml/xml_sub_container.xml");
+        final NormalizedNodeContext returnValue = this.xmlBodyReader.readFrom(null, null, null, this.mediaType, null,
+                inputStream);
+        checkNormalizedNodeContext(returnValue);
+        checkExpectValueNormalizeNodeContext(dataSchemaNode, returnValue, dataII);
+    }
+
+    @Test
+    public void moduleSubContainerAugmentDataPostTest() throws Exception {
+        final DataSchemaNode dataSchemaNode = schemaContext
+                .getDataChildByName(QName.create(INSTANCE_IDENTIFIER_MODULE_QNAME, "cont"));
+        final Module augmentModule = schemaContext.findModuleByNamespace(new URI("augment:module")).iterator().next();
+        final QName contAugmentQName = QName.create(augmentModule.getQNameModule(), "cont-augment");
+        final YangInstanceIdentifier.AugmentationIdentifier augII = new YangInstanceIdentifier.AugmentationIdentifier(
+                Sets.newHashSet(contAugmentQName));
+        final YangInstanceIdentifier dataII = YangInstanceIdentifier.of(dataSchemaNode.getQName()).node(augII)
+                .node(contAugmentQName);
+        final String uri = "instance-identifier-module:cont";
+        mockBodyReader(uri, this.xmlBodyReader, true);
+        final InputStream inputStream = Draft17XmlBodyReaderTest.class
+                .getResourceAsStream("/instanceidentifier/xml/xml_augment_container.xml");
+        final NormalizedNodeContext returnValue = this.xmlBodyReader.readFrom(null, null, null, this.mediaType, null,
+                inputStream);
+        checkNormalizedNodeContext(returnValue);
+        checkExpectValueNormalizeNodeContext(dataSchemaNode, returnValue, dataII);
+    }
+
+    @Test
+    public void moduleSubContainerChoiceAugmentDataPostTest() throws Exception {
+        final DataSchemaNode dataSchemaNode = schemaContext
+                .getDataChildByName(QName.create(INSTANCE_IDENTIFIER_MODULE_QNAME, "cont"));
+        final Module augmentModule = schemaContext.findModuleByNamespace(new URI("augment:module")).iterator().next();
+        final QName augmentChoice1QName = QName.create(augmentModule.getQNameModule(), "augment-choice1");
+        final QName augmentChoice2QName = QName.create(augmentChoice1QName, "augment-choice2");
+        final QName containerQName = QName.create(augmentChoice1QName, "case-choice-case-container1");
+        final YangInstanceIdentifier.AugmentationIdentifier augChoice1II = new YangInstanceIdentifier.AugmentationIdentifier(
+                Sets.newHashSet(augmentChoice1QName));
+        final YangInstanceIdentifier.AugmentationIdentifier augChoice2II = new YangInstanceIdentifier.AugmentationIdentifier(
+                Sets.newHashSet(augmentChoice2QName));
+        final YangInstanceIdentifier dataII = YangInstanceIdentifier.of(dataSchemaNode.getQName()).node(augChoice1II)
+                .node(augmentChoice1QName).node(augChoice2II).node(augmentChoice2QName).node(containerQName);
+        final String uri = "instance-identifier-module:cont";
+        mockBodyReader(uri, this.xmlBodyReader, true);
+        final InputStream inputStream = Draft17XmlBodyReaderTest.class
+                .getResourceAsStream("/instanceidentifier/xml/xml_augment_choice_container.xml");
+        final NormalizedNodeContext returnValue = this.xmlBodyReader.readFrom(null, null, null, this.mediaType, null,
+                inputStream);
+        checkNormalizedNodeContext(returnValue);
+        checkExpectValueNormalizeNodeContext(dataSchemaNode, returnValue, dataII);
+    }
+
+    private void checkExpectValueNormalizeNodeContext(final DataSchemaNode dataSchemaNode,
+            final NormalizedNodeContext nnContext, final YangInstanceIdentifier dataNodeIdent) {
+        assertEquals(dataSchemaNode, nnContext.getInstanceIdentifierContext().getSchemaNode());
+        assertEquals(dataNodeIdent, nnContext.getInstanceIdentifierContext().getInstanceIdentifier());
+        assertNotNull(NormalizedNodes.findNode(nnContext.getData(), dataNodeIdent));
+    }
+
+    /**
+     * Test when container with the same name is placed in two modules
+     * (foo-module and bar-module). Namespace must be used to distinguish
+     * between them to find correct one. Check if container was found not only
+     * according to its name but also by correct namespace used in payload.
+     */
+    @Test
+    public void findFooContainerUsingNamespaceTest() throws Exception {
+        mockBodyReader("", this.xmlBodyReader, true);
+        final InputStream inputStream = Draft17XmlBodyReaderTest.class
+                .getResourceAsStream("/instanceidentifier/xml/xmlDataFindFooContainer.xml");
+        final NormalizedNodeContext returnValue = this.xmlBodyReader.readFrom(null, null, null, this.mediaType, null,
+                inputStream);
+
+        // check return value
+        checkNormalizedNodeContext(returnValue);
+        // check if container was found both according to its name and namespace
+        assertEquals("Not correct container found, name was ignored", "foo-bar-container",
+                returnValue.getData().getNodeType().getLocalName());
+        assertEquals("Not correct container found, namespace was ignored", "foo:module",
+                returnValue.getData().getNodeType().getNamespace().toString());
+    }
+
+    /**
+     * Test when container with the same name is placed in two modules
+     * (foo-module and bar-module). Namespace must be used to distinguish
+     * between them to find correct one. Check if container was found not only
+     * according to its name but also by correct namespace used in payload.
+     */
+    @Test
+    public void findBarContainerUsingNamespaceTest() throws Exception {
+        mockBodyReader("", this.xmlBodyReader, true);
+        final InputStream inputStream = Draft17XmlBodyReaderTest.class
+                .getResourceAsStream("/instanceidentifier/xml/xmlDataFindBarContainer.xml");
+        final NormalizedNodeContext returnValue = this.xmlBodyReader.readFrom(null, null, null, this.mediaType, null,
+                inputStream);
+
+        // check return value
+        checkNormalizedNodeContext(returnValue);
+        // check if container was found both according to its name and namespace
+        assertEquals("Not correct container found, name was ignored", "foo-bar-container",
+                returnValue.getData().getNodeType().getLocalName());
+        assertEquals("Not correct container found, namespace was ignored", "bar:module",
+                returnValue.getData().getNodeType().getNamespace().toString());
+    }
+}
@@ -18,15 +18,15 @@ import org.junit.BeforeClass;
 import org.junit.Test;
 import org.opendaylight.netconf.sal.restconf.impl.PATCHContext;
 import org.opendaylight.netconf.sal.restconf.impl.RestconfDocumentedException;
-import org.opendaylight.restconf.utils.patch.JsonToPATCHBodyReader;
+import org.opendaylight.restconf.jersey.providers.JsonToPATCHBodyReader;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
-public class TestDraft11JsonPATCHBodyReader extends Draft11AbstractBodyReaderTest {
+public class TestDraft17JsonPATCHBodyReader extends Draft17AbstractBodyReaderTest {
 
     private final JsonToPATCHBodyReader jsonPATCHBodyReader;
     private static SchemaContext schemaContext;
 
-    public TestDraft11JsonPATCHBodyReader() throws NoSuchFieldException, SecurityException {
+    public TestDraft17JsonPATCHBodyReader() throws NoSuchFieldException, SecurityException {
         super();
         jsonPATCHBodyReader = new JsonToPATCHBodyReader();
     }
@@ -17,15 +17,15 @@ import org.junit.BeforeClass;
 import org.junit.Test;
 import org.opendaylight.netconf.sal.restconf.impl.PATCHContext;
 import org.opendaylight.netconf.sal.restconf.impl.RestconfDocumentedException;
-import org.opendaylight.restconf.utils.patch.XmlToPATCHBodyReader;
+import org.opendaylight.restconf.jersey.providers.XmlToPATCHBodyReader;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
-public class TestDraft11XmlPATCHBodyReader extends Draft11AbstractBodyReaderTest {
+public class TestDraft17XmlPATCHBodyReader extends Draft17AbstractBodyReaderTest {
 
     private final XmlToPATCHBodyReader xmlPATCHBodyReader;
     private static SchemaContext schemaContext;
 
-    public TestDraft11XmlPATCHBodyReader() throws NoSuchFieldException, SecurityException {
+    public TestDraft17XmlPATCHBodyReader() throws NoSuchFieldException, SecurityException {
         super();
         xmlPATCHBodyReader = new XmlToPATCHBodyReader();
     }
index 7649c833d25db8236d81b91c7081854af60048c8..a639fef4a44d8f534127d9bd72ec447a6a2947a9 100644 (file)
@@ -10,16 +10,12 @@ package org.opendaylight.controller.sal.restconf.impl.json.to.nn.test;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
-import java.io.IOException;
 import java.io.InputStream;
-
-import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.core.MediaType;
-
 import org.junit.BeforeClass;
 import org.junit.Test;
-import org.opendaylight.netconf.sal.rest.impl.JsonNormalizedNodeBodyReader;
 import org.opendaylight.controller.sal.rest.impl.test.providers.AbstractBodyReaderTest;
+import org.opendaylight.netconf.sal.rest.impl.JsonNormalizedNodeBodyReader;
 import org.opendaylight.netconf.sal.restconf.impl.NormalizedNodeContext;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodes;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
@@ -32,7 +28,7 @@ public class JsonIdentityrefToNnTest extends AbstractBodyReaderTest {
     public JsonIdentityrefToNnTest() throws NoSuchFieldException,
             SecurityException {
         super();
-        jsonBodyReader = new JsonNormalizedNodeBodyReader();
+        this.jsonBodyReader = new JsonNormalizedNodeBodyReader();
     }
 
     @BeforeClass
@@ -43,22 +39,20 @@ public class JsonIdentityrefToNnTest extends AbstractBodyReaderTest {
     }
 
     @Test
-    public void jsonIdentityrefToNn() throws NoSuchFieldException,
-            SecurityException, IllegalArgumentException,
-            IllegalAccessException, WebApplicationException, IOException {
+    public void jsonIdentityrefToNn() throws Exception {
 
-        String uri = "identityref-module:cont";
-        mockBodyReader(uri, jsonBodyReader, false);
-        InputStream inputStream = this.getClass().getResourceAsStream(
+        final String uri = "identityref-module:cont";
+        mockBodyReader(uri, this.jsonBodyReader, false);
+        final InputStream inputStream = this.getClass().getResourceAsStream(
                 "/json-to-nn/identityref/json/data.json");
 
-        NormalizedNodeContext normalizedNodeContext = jsonBodyReader.readFrom(
-                null, null, null, mediaType, null, inputStream);
+        final NormalizedNodeContext normalizedNodeContext = this.jsonBodyReader.readFrom(
+                null, null, null, this.mediaType, null, inputStream);
 
         assertEquals("cont", normalizedNodeContext.getData().getNodeType()
                 .getLocalName());
 
-        String dataTree = NormalizedNodes.toStringTree(normalizedNodeContext
+        final String dataTree = NormalizedNodes.toStringTree(normalizedNodeContext
                 .getData());
 
         assertTrue(dataTree.contains("cont1"));
@@ -74,7 +68,6 @@ public class JsonIdentityrefToNnTest extends AbstractBodyReaderTest {
 
     @Override
     protected MediaType getMediaType() {
-        // TODO Auto-generated method stub
         return null;
     }
 
index d3b65350edfe780050084c96a06a441e20a194d9..d44cb15945c1efd9c52e046cf2f365ce8a61c1e4 100644 (file)
@@ -9,17 +9,12 @@ package org.opendaylight.controller.sal.restconf.impl.json.to.nn.test;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
-
-import java.io.IOException;
 import java.io.InputStream;
-
-import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.core.MediaType;
-
 import org.junit.BeforeClass;
 import org.junit.Test;
-import org.opendaylight.netconf.sal.rest.impl.JsonNormalizedNodeBodyReader;
 import org.opendaylight.controller.sal.rest.impl.test.providers.AbstractBodyReaderTest;
+import org.opendaylight.netconf.sal.rest.impl.JsonNormalizedNodeBodyReader;
 import org.opendaylight.netconf.sal.restconf.impl.NormalizedNodeContext;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodes;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
@@ -31,7 +26,7 @@ public class JsonLeafrefToNnTest extends AbstractBodyReaderTest {
 
     public JsonLeafrefToNnTest() throws NoSuchFieldException, SecurityException {
         super();
-        jsonBodyReader = new JsonNormalizedNodeBodyReader();
+        this.jsonBodyReader = new JsonNormalizedNodeBodyReader();
     }
 
     @BeforeClass
@@ -42,28 +37,25 @@ public class JsonLeafrefToNnTest extends AbstractBodyReaderTest {
     }
 
     @Test
-    public void jsonIdentityrefToNormalizeNode() throws NoSuchFieldException,
-            SecurityException, IllegalArgumentException,
-            IllegalAccessException, WebApplicationException, IOException {
+    public void jsonIdentityrefToNormalizeNode() throws Exception {
 
-        String uri = "leafref-module:cont";
-        mockBodyReader(uri, jsonBodyReader, false);
-        InputStream inputStream = this.getClass().getResourceAsStream(
+        final String uri = "leafref-module:cont";
+        mockBodyReader(uri, this.jsonBodyReader, false);
+        final InputStream inputStream = this.getClass().getResourceAsStream(
                 "/json-to-nn/leafref/json/data.json");
 
-        NormalizedNodeContext normalizedNodeContext = jsonBodyReader.readFrom(
-                null, null, null, mediaType, null, inputStream);
+        final NormalizedNodeContext normalizedNodeContext = this.jsonBodyReader.readFrom(
+                null, null, null, this.mediaType, null, inputStream);
 
         assertEquals("cont", normalizedNodeContext.getData().getNodeType()
                 .getLocalName());
-        String dataTree = NormalizedNodes.toStringTree(normalizedNodeContext
+        final String dataTree = NormalizedNodes.toStringTree(normalizedNodeContext
                 .getData());
         assertTrue(dataTree.contains("lf2 121"));
     }
 
     @Override
     protected MediaType getMediaType() {
-        // TODO Auto-generated method stub
         return null;
     }
 
index a5fd92375f01209048c6a03fab6939da44136e55..3672a3c13003e7f750d4bdf9b952b761fc4fbf8b 100644 (file)
@@ -12,17 +12,13 @@ import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
-
 import java.io.IOException;
 import java.io.InputStream;
-
 import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.core.MediaType;
-
-import org.junit.Ignore;
 import org.junit.Test;
-import org.opendaylight.netconf.sal.rest.impl.JsonNormalizedNodeBodyReader;
 import org.opendaylight.controller.sal.rest.impl.test.providers.AbstractBodyReaderTest;
+import org.opendaylight.netconf.sal.rest.impl.JsonNormalizedNodeBodyReader;
 import org.opendaylight.netconf.sal.restconf.impl.NormalizedNodeContext;
 import org.opendaylight.netconf.sal.restconf.impl.RestconfDocumentedException;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodes;
@@ -42,25 +38,23 @@ public class JsonToNnTest extends AbstractBodyReaderTest {
         controllerContext.setSchemas(schemaContext);
     }
 
-    //TODO unignore once yangtools bug is fixed
     @Test
-    @Ignore
-    public void simpleListTest() {
+    public void simpleListTest() throws Exception {
         simpleTest("/json-to-nn/simple-list.json",
                 "/json-to-nn/simple-list-yang/1", "lst", "simple-list-yang1");
     }
 
     @Test
-    public void simpleContainerTest() {
+    public void simpleContainerTest() throws Exception {
         simpleTest("/json-to-nn/simple-container.json",
                 "/json-to-nn/simple-container-yang", "cont",
                 "simple-container-yang");
     }
 
     @Test
-    public void multipleItemsInLeafListTest() {
+    public void multipleItemsInLeafListTest() throws Exception {
 
-        initialize("/json-to-nn/simple-list-yang/1", schemaContext);
+        initialize("/json-to-nn/simple-list-yang/1", this.schemaContext);
 
         final NormalizedNodeContext normalizedNodeContext = prepareNNC(
                 "/json-to-nn/multiple-leaflist-items.json",
@@ -75,8 +69,8 @@ public class JsonToNnTest extends AbstractBodyReaderTest {
     }
 
     @Test
-    public void multipleItemsInListTest() {
-        initialize("/json-to-nn/simple-list-yang/3", schemaContext);
+    public void multipleItemsInListTest() throws Exception {
+        initialize("/json-to-nn/simple-list-yang/3", this.schemaContext);
 
         final NormalizedNodeContext normalizedNodeContext = prepareNNC(
                 "/json-to-nn/multiple-items-in-list.json",
@@ -90,8 +84,8 @@ public class JsonToNnTest extends AbstractBodyReaderTest {
     }
 
     @Test
-    public void nullArrayToSimpleNodeWithNullValueTest() {
-        initialize("/json-to-nn/simple-list-yang/4", schemaContext);
+    public void nullArrayToSimpleNodeWithNullValueTest() throws Exception {
+        initialize("/json-to-nn/simple-list-yang/4", this.schemaContext);
 
         final NormalizedNodeContext normalizedNodeContext = prepareNNC(
                 "/json-to-nn/array-with-null.json", "array-with-null-yang:cont");
@@ -107,13 +101,11 @@ public class JsonToNnTest extends AbstractBodyReaderTest {
     }
 
     @Test
-    public void incorrectTopLevelElementsTest() throws WebApplicationException,
-            IOException, NoSuchFieldException, SecurityException,
-            IllegalArgumentException, IllegalAccessException {
+    public void incorrectTopLevelElementsTest() throws Exception {
 
-        jsonBodyReader = new JsonNormalizedNodeBodyReader();
-        initialize("/json-to-nn/simple-list-yang/1", schemaContext);
-        mockBodyReader("simple-list-yang1:lst", jsonBodyReader, false);
+        this.jsonBodyReader = new JsonNormalizedNodeBodyReader();
+        initialize("/json-to-nn/simple-list-yang/1", this.schemaContext);
+        mockBodyReader("simple-list-yang1:lst", this.jsonBodyReader, false);
 
         InputStream inputStream = this.getClass().getResourceAsStream(
                 "/json-to-nn/wrong-top-level1.json");
@@ -122,7 +114,7 @@ public class JsonToNnTest extends AbstractBodyReaderTest {
         RestconfDocumentedException exception = null;
 
         try {
-            jsonBodyReader.readFrom(null, null, null, mediaType, null,
+            this.jsonBodyReader.readFrom(null, null, null, this.mediaType, null,
                     inputStream);
         } catch (final RestconfDocumentedException e) {
             exception = e;
@@ -137,7 +129,7 @@ public class JsonToNnTest extends AbstractBodyReaderTest {
                 "/json-to-nn/wrong-top-level2.json");
         exception = null;
         try {
-            jsonBodyReader.readFrom(null, null, null, mediaType, null,
+            this.jsonBodyReader.readFrom(null, null, null, this.mediaType, null,
                     inputStream);
         } catch (final RestconfDocumentedException e) {
             exception = e;
@@ -152,7 +144,7 @@ public class JsonToNnTest extends AbstractBodyReaderTest {
                 "/json-to-nn/wrong-top-level3.json");
         exception = null;
         try {
-            jsonBodyReader.readFrom(null, null, null, mediaType, null,
+            this.jsonBodyReader.readFrom(null, null, null, this.mediaType, null,
                     inputStream);
         } catch (final RestconfDocumentedException e) {
             exception = e;
@@ -166,11 +158,9 @@ public class JsonToNnTest extends AbstractBodyReaderTest {
     }
 
     @Test
-    public void emptyDataReadTest() throws WebApplicationException,
-            IOException, NoSuchFieldException, SecurityException,
-            IllegalArgumentException, IllegalAccessException {
+    public void emptyDataReadTest() throws Exception {
 
-        initialize("/json-to-nn/simple-list-yang/4", schemaContext);
+        initialize("/json-to-nn/simple-list-yang/4", this.schemaContext);
 
         final NormalizedNodeContext normalizedNodeContext = prepareNNC(
                 "/json-to-nn/empty-data.json", "array-with-null-yang:cont");
@@ -186,14 +176,14 @@ public class JsonToNnTest extends AbstractBodyReaderTest {
 
         assertTrue(dataTree.contains("lflst2 45"));
 
-        jsonBodyReader = new JsonNormalizedNodeBodyReader();
+        this.jsonBodyReader = new JsonNormalizedNodeBodyReader();
         RestconfDocumentedException exception = null;
-        mockBodyReader("array-with-null-yang:cont", jsonBodyReader, false);
+        mockBodyReader("array-with-null-yang:cont", this.jsonBodyReader, false);
         final InputStream inputStream = this.getClass().getResourceAsStream(
                 "/json-to-nn/empty-data.json1");
 
         try {
-            jsonBodyReader.readFrom(null, null, null, mediaType, null,
+            this.jsonBodyReader.readFrom(null, null, null, this.mediaType, null,
                     inputStream);
         } catch (final RestconfDocumentedException e) {
             exception = e;
@@ -204,23 +194,17 @@ public class JsonToNnTest extends AbstractBodyReaderTest {
     }
 
     @Test
-    public void testJsonBlankInput() throws NoSuchFieldException,
-            SecurityException, IllegalArgumentException,
-            IllegalAccessException, WebApplicationException, IOException {
-        initialize("/json-to-nn/simple-list-yang/4", schemaContext);
+    public void testJsonBlankInput() throws Exception {
+        initialize("/json-to-nn/simple-list-yang/4", this.schemaContext);
         final NormalizedNodeContext normalizedNodeContext = prepareNNC("",
                 "array-with-null-yang:cont");
         assertNull(normalizedNodeContext);
     }
 
-    //TODO unignore once yangtools bug is fixed
     @Test
-    @Ignore
-    public void notSupplyNamespaceIfAlreadySupplied()
-            throws WebApplicationException, IOException, NoSuchFieldException,
-            SecurityException, IllegalArgumentException, IllegalAccessException {
+    public void notSupplyNamespaceIfAlreadySupplied()throws Exception {
 
-        initialize("/json-to-nn/simple-list-yang/1", schemaContext);
+        initialize("/json-to-nn/simple-list-yang/1", this.schemaContext);
 
         final String uri = "simple-list-yang1" + ":" + "lst";
 
@@ -230,12 +214,12 @@ public class JsonToNnTest extends AbstractBodyReaderTest {
 
         verifyNormaluizedNodeContext(normalizedNodeContext, "lst");
 
-        mockBodyReader("simple-list-yang2:lst", jsonBodyReader, false);
+        mockBodyReader("simple-list-yang2:lst", this.jsonBodyReader, false);
         final InputStream inputStream = this.getClass().getResourceAsStream(
                 "/json-to-nn/simple-list.json");
 
         try {
-            jsonBodyReader.readFrom(null, null, null, mediaType, null,
+            this.jsonBodyReader.readFrom(null, null, null, this.mediaType, null,
                     inputStream);
             fail("NormalizedNodeContext should not be create because of different namespace");
         } catch (final RestconfDocumentedException e) {
@@ -245,9 +229,9 @@ public class JsonToNnTest extends AbstractBodyReaderTest {
     }
 
     @Test
-    public void dataAugmentedTest() {
+    public void dataAugmentedTest() throws Exception {
 
-        initialize("/common/augment/yang", schemaContext);
+        initialize("/common/augment/yang", this.schemaContext);
 
         NormalizedNodeContext normalizedNodeContext = prepareNNC(
                 "/common/augment/json/dataa.json", "main:cont");
@@ -274,9 +258,9 @@ public class JsonToNnTest extends AbstractBodyReaderTest {
     }
 
     private void simpleTest(final String jsonPath, final String yangPath,
-            final String topLevelElementName, final String moduleName) {
+            final String topLevelElementName, final String moduleName) throws Exception {
 
-        initialize(yangPath, schemaContext);
+        initialize(yangPath, this.schemaContext);
 
         final String uri = moduleName + ":" + topLevelElementName;
 
@@ -286,10 +270,10 @@ public class JsonToNnTest extends AbstractBodyReaderTest {
         verifyNormaluizedNodeContext(normalizedNodeContext, topLevelElementName);
     }
 
-    private NormalizedNodeContext prepareNNC(final String jsonPath, final String uri) {
-        jsonBodyReader = new JsonNormalizedNodeBodyReader();
+    private NormalizedNodeContext prepareNNC(final String jsonPath, final String uri) throws Exception {
+        this.jsonBodyReader = new JsonNormalizedNodeBodyReader();
         try {
-            mockBodyReader(uri, jsonBodyReader, false);
+            mockBodyReader(uri, this.jsonBodyReader, false);
         } catch (NoSuchFieldException | SecurityException
                 | IllegalArgumentException | IllegalAccessException e) {
             // TODO Auto-generated catch block
@@ -300,8 +284,8 @@ public class JsonToNnTest extends AbstractBodyReaderTest {
         NormalizedNodeContext normalizedNodeContext = null;
 
         try {
-            normalizedNodeContext = jsonBodyReader.readFrom(null, null, null,
-                    mediaType, null, inputStream);
+            normalizedNodeContext = this.jsonBodyReader.readFrom(null, null, null,
+                    this.mediaType, null, inputStream);
         } catch (WebApplicationException | IOException e) {
             // TODO Auto-generated catch block
             e.printStackTrace();
@@ -340,12 +324,10 @@ public class JsonToNnTest extends AbstractBodyReaderTest {
     }
 
     @Test
-    public void unsupportedDataFormatTest() throws NoSuchFieldException,
-            SecurityException, IllegalArgumentException,
-            IllegalAccessException, WebApplicationException, IOException {
-        jsonBodyReader = new JsonNormalizedNodeBodyReader();
-        initialize("/json-to-nn/simple-list-yang/1", schemaContext);
-        mockBodyReader("simple-list-yang1:lst", jsonBodyReader, false);
+    public void unsupportedDataFormatTest() throws Exception {
+        this.jsonBodyReader = new JsonNormalizedNodeBodyReader();
+        initialize("/json-to-nn/simple-list-yang/1", this.schemaContext);
+        mockBodyReader("simple-list-yang1:lst", this.jsonBodyReader, false);
 
         final InputStream inputStream = this.getClass().getResourceAsStream(
                 "/json-to-nn/unsupported-json-format.json");
@@ -353,7 +335,7 @@ public class JsonToNnTest extends AbstractBodyReaderTest {
         RestconfDocumentedException exception = null;
 
         try {
-            jsonBodyReader.readFrom(null, null, null, mediaType, null,
+            this.jsonBodyReader.readFrom(null, null, null, this.mediaType, null,
                     inputStream);
         } catch (final RestconfDocumentedException e) {
             exception = e;
@@ -365,19 +347,17 @@ public class JsonToNnTest extends AbstractBodyReaderTest {
     }
 
     @Test
-    public void invalidUriCharacterInValue() throws NoSuchFieldException,
-            SecurityException, IllegalArgumentException,
-            IllegalAccessException, WebApplicationException, IOException {
+    public void invalidUriCharacterInValue() throws Exception {
 
-        jsonBodyReader = new JsonNormalizedNodeBodyReader();
-        initialize("/json-to-nn/simple-list-yang/4", schemaContext);
-        mockBodyReader("array-with-null-yang:cont", jsonBodyReader, false);
+        this.jsonBodyReader = new JsonNormalizedNodeBodyReader();
+        initialize("/json-to-nn/simple-list-yang/4", this.schemaContext);
+        mockBodyReader("array-with-null-yang:cont", this.jsonBodyReader, false);
 
         final InputStream inputStream = this.getClass().getResourceAsStream(
                 "/json-to-nn/invalid-uri-character-in-value.json");
 
-        final NormalizedNodeContext normalizedNodeContext = jsonBodyReader.readFrom(
-                null, null, null, mediaType, null, inputStream);
+        final NormalizedNodeContext normalizedNodeContext = this.jsonBodyReader.readFrom(
+                null, null, null, this.mediaType, null, inputStream);
         assertNotNull(normalizedNodeContext);
 
         assertEquals("cont", normalizedNodeContext.getData().getNodeType()
@@ -391,7 +371,6 @@ public class JsonToNnTest extends AbstractBodyReaderTest {
 
     @Override
     protected MediaType getMediaType() {
-        // TODO Auto-generated method stub
         return null;
     }