Do not attempt to construct invalid QNames 26/49526/3
authorRobert Varga <rovarga@cisco.com>
Sun, 18 Dec 2016 13:13:12 +0000 (14:13 +0100)
committerRobert Varga <rovarga@cisco.com>
Sun, 18 Dec 2016 19:16:04 +0000 (20:16 +0100)
This fixes an attempt to instantiate a QName with a colon
in its local name. Two of the failing tests are straightforward
fixes.

The RestconfOperationsServiceImpl is more involved, as it requires
faking module imports to keep encoding working.

Change-Id: Iceed2310e94a16189d80fe57b58510fbfc45e17a
Signed-off-by: Robert Varga <rovarga@cisco.com>
netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/NetconfDeviceTest.java
restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/rest/services/impl/FakeContainerSchemaNode.java [moved from restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/rest/services/impl/ContainerSchemaNodeImpl.java with 82% similarity]
restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/rest/services/impl/FakeImportedModule.java [new file with mode: 0644]
restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/rest/services/impl/FakeLeafSchemaNode.java [moved from restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/rest/services/impl/LeafSchemaNodeImpl.java with 88% similarity]
restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/rest/services/impl/FakeModuleImport.java [new file with mode: 0644]
restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/rest/services/impl/FakeRestconfModule.java [moved from restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/rest/services/impl/ModuleImpl.java with 82% similarity]
restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/rest/services/impl/RestconfOperationsServiceImpl.java
restconf/sal-rest-connector/src/test/java/org/opendaylight/restconf/rest/services/impl/RestconfOperationsServiceTest.java
restconf/sal-rest-connector/src/test/java/org/opendaylight/restconf/restful/utils/CreateStreamUtilTest.java

index 9708888f5d0c44fb24eab62ea88e101f21b0c8fe..909b370caf2eb52cad3d8b9efcc8051f68e6293f 100644 (file)
@@ -357,7 +357,7 @@ public class NetconfDeviceTest {
                 Lists.newArrayList(TEST_NAMESPACE + "?module=" + TEST_MODULE + "&amp;revision=" + TEST_REVISION));
         Map<QName, AvailableCapability.CapabilityOrigin> moduleBasedCaps = new HashMap<>();
         moduleBasedCaps.putAll(sessionCaps.getModuleBasedCapsOrigin());
-        moduleBasedCaps.put(QName.create("test:qname:side:loading"), AvailableCapability.CapabilityOrigin.UserDefined);
+        moduleBasedCaps.put(QName.create("(test:qname:side:loading)test"), AvailableCapability.CapabilityOrigin.UserDefined);
 
         netconfSpy.onRemoteSessionUp(sessionCaps.replaceModuleCaps(moduleBasedCaps), listener);
 
@@ -7,7 +7,7 @@
  */
 package org.opendaylight.restconf.rest.services.impl;
 
-import java.util.ArrayList;
+import com.google.common.collect.ImmutableList;
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.List;
@@ -19,6 +19,7 @@ import org.opendaylight.yangtools.yang.model.api.ConstraintDefinition;
 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
+import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
 import org.opendaylight.yangtools.yang.model.api.Status;
 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
@@ -28,14 +29,16 @@ import org.opendaylight.yangtools.yang.model.api.UsesNode;
 /**
  * Special case only use by GET restconf/operations (since moment of old Yang
  * parser and old yang model API removal) to build and use fake container for
- * module
- *
+ * module.
  */
-class ContainerSchemaNodeImpl implements ContainerSchemaNode {
+class FakeContainerSchemaNode implements ContainerSchemaNode {
+    static final SchemaPath PATH = SchemaPath.create(true, QName.create(FakeRestconfModule.QNAME, "operations").intern());
+
+    private final Collection<DataSchemaNode> children;
 
-    List<DataSchemaNode> child = new ArrayList<>();
-    private final QName qname = QName.create(ModuleImpl.moduleQName, "operations");
-    private final SchemaPath path = SchemaPath.create(true, this.qname);
+    FakeContainerSchemaNode(final Collection<LeafSchemaNode> children) {
+        this.children = ImmutableList.copyOf(children);
+    }
 
     @Override
     public Set<TypeDefinition<?>> getTypeDefinitions() {
@@ -44,7 +47,7 @@ class ContainerSchemaNodeImpl implements ContainerSchemaNode {
 
     @Override
     public Collection<DataSchemaNode> getChildNodes() {
-        return this.child;
+        return this.children;
     }
 
     @Override
@@ -54,12 +57,12 @@ class ContainerSchemaNodeImpl implements ContainerSchemaNode {
 
     @Override
     public DataSchemaNode getDataChildByName(final QName name) {
-        for (final DataSchemaNode node : this.child) {
+        for (final DataSchemaNode node : this.children) {
             if (node.getQName().equals(name)) {
                 return node;
             }
         }
-        throw new RestconfDocumentedException(name + " is not in child of " + this.qname);
+        throw new RestconfDocumentedException(name + " is not in child of " + PATH.getLastComponent());
     }
 
     @Override
@@ -94,12 +97,12 @@ class ContainerSchemaNodeImpl implements ContainerSchemaNode {
 
     @Override
     public QName getQName() {
-        return this.qname;
+        return PATH.getLastComponent();
     }
 
     @Override
     public SchemaPath getPath() {
-        return this.path;
+        return PATH;
     }
 
     @Override
@@ -126,14 +129,4 @@ class ContainerSchemaNodeImpl implements ContainerSchemaNode {
     public boolean isPresenceContainer() {
         throw new UnsupportedOperationException("Not supported.");
     }
-
-    /**
-     * Adding new schema node to this container
-     *
-     * @param fakeLeaf
-     *            - fake schema leaf node
-     */
-    public void addNodeChild(final DataSchemaNode fakeLeaf) {
-        this.child.add(fakeLeaf);
-    }
 }
diff --git a/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/rest/services/impl/FakeImportedModule.java b/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/rest/services/impl/FakeImportedModule.java
new file mode 100644 (file)
index 0000000..6fc3d2b
--- /dev/null
@@ -0,0 +1,177 @@
+/*
+ * 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.rest.services.impl;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ForwardingObject;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import java.net.URI;
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+import java.util.Set;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.QNameModule;
+import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Deviation;
+import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition;
+import org.opendaylight.yangtools.yang.model.api.FeatureDefinition;
+import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
+import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.ModuleImport;
+import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.UsesNode;
+
+final class FakeImportedModule extends ForwardingObject implements Module {
+
+    private final Module delegate;
+
+    FakeImportedModule(final Module delegate) {
+        this.delegate = Preconditions.checkNotNull(delegate);
+    }
+
+    @Override
+    protected Module delegate() {
+        return delegate;
+    }
+
+    @Override
+    public Set<TypeDefinition<?>> getTypeDefinitions() {
+        return ImmutableSet.of();
+    }
+
+    @Override
+    public Collection<DataSchemaNode> getChildNodes() {
+        return ImmutableList.of();
+    }
+
+    @Override
+    public Set<GroupingDefinition> getGroupings() {
+        return ImmutableSet.of();
+    }
+
+    @Override
+    public DataSchemaNode getDataChildByName(final QName name) {
+        return null;
+    }
+
+    @Override
+    public Set<UsesNode> getUses() {
+        return ImmutableSet.of();
+    }
+
+    @Override
+    public String getModuleSourcePath() {
+        return null;
+    }
+
+    @Override
+    public QNameModule getQNameModule() {
+        return delegate.getQNameModule();
+    }
+
+    @Override
+    public String getName() {
+        return delegate.getName();
+    }
+
+    @Override
+    public URI getNamespace() {
+        return delegate.getNamespace();
+    }
+
+    @Override
+    public Date getRevision() {
+        return delegate.getRevision();
+    }
+
+    @Override
+    public String getPrefix() {
+        return delegate.getPrefix();
+    }
+
+    @Override
+    public String getYangVersion() {
+        return delegate.getYangVersion();
+    }
+
+    @Override
+    public String getDescription() {
+        return delegate.getDescription();
+    }
+
+    @Override
+    public String getReference() {
+        return delegate.getReference();
+    }
+
+    @Override
+    public String getOrganization() {
+        return delegate.getOrganization();
+    }
+
+    @Override
+    public String getContact() {
+        return delegate.getContact();
+    }
+
+    @Override
+    public Set<ModuleImport> getImports() {
+        return ImmutableSet.of();
+    }
+
+    @Override
+    public Set<Module> getSubmodules() {
+        return ImmutableSet.of();
+    }
+
+    @Override
+    public Set<FeatureDefinition> getFeatures() {
+        return ImmutableSet.of();
+    }
+
+    @Override
+    public Set<AugmentationSchema> getAugmentations() {
+        return ImmutableSet.of();
+    }
+
+    @Override
+    public Set<RpcDefinition> getRpcs() {
+        return ImmutableSet.of();
+    }
+
+    @Override
+    public Set<Deviation> getDeviations() {
+        return ImmutableSet.of();
+    }
+
+    @Override
+    public Set<IdentitySchemaNode> getIdentities() {
+        return ImmutableSet.of();
+    }
+
+    @Override
+    public List<ExtensionDefinition> getExtensionSchemaNodes() {
+        return ImmutableList.of();
+    }
+
+    @Override
+    public List<UnknownSchemaNode> getUnknownSchemaNodes() {
+        return ImmutableList.of();
+    }
+
+    @Override
+    public String getSource() {
+        return null;
+    }
+}
similarity index 88%
rename from restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/rest/services/impl/LeafSchemaNodeImpl.java
rename to restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/rest/services/impl/FakeLeafSchemaNode.java
index 13a3190896babdfbbb34ad4616ad9f09f708c71d..81bbc47d8adeb8e4b853ee37a05d807a8286ce91 100644 (file)
@@ -21,24 +21,19 @@ import org.opendaylight.yangtools.yang.model.util.type.BaseTypes;
  * Special case only use by GET restconf/operations (since moment of old Yang
  * parser and old yang model API removal) to build and use fake leaf like child
  * in container
- *
  */
-class LeafSchemaNodeImpl implements LeafSchemaNode {
+final class FakeLeafSchemaNode implements LeafSchemaNode {
 
     private final SchemaPath path;
-    private final QName qname;
 
     /**
      * Base values for fake leaf schema node
      *
-     * @param basePath
-     *            - schema path
      * @param qname
      *            - qname
      */
-    LeafSchemaNodeImpl(final SchemaPath basePath, final QName qname) {
-        this.path = basePath.createChild(qname);
-        this.qname = qname;
+    FakeLeafSchemaNode(final QName qname) {
+        this.path = FakeContainerSchemaNode.PATH.createChild(qname);
     }
 
     @Override
@@ -63,12 +58,12 @@ class LeafSchemaNodeImpl implements LeafSchemaNode {
 
     @Override
     public QName getQName() {
-        return this.qname;
+        return path.getLastComponent();
     }
 
     @Override
     public SchemaPath getPath() {
-        return this.path;
+        return path;
     }
 
     @Override
diff --git a/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/rest/services/impl/FakeModuleImport.java b/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/rest/services/impl/FakeModuleImport.java
new file mode 100644 (file)
index 0000000..4ada5a7
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * 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.rest.services.impl;
+
+import com.google.common.base.Preconditions;
+import java.util.Date;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.ModuleImport;
+
+/**
+ * Fake {@link ModuleImport} implementation used to attach corrent prefix mapping to fake RPCs.
+ *
+ * @author Robert Varga
+ */
+final class FakeModuleImport implements ModuleImport {
+    private final Module module;
+
+    FakeModuleImport(final Module module) {
+        this.module = Preconditions.checkNotNull(module);
+    }
+
+    @Override
+    public String getModuleName() {
+        return module.getName();
+    }
+
+    @Override
+    public Date getRevision() {
+        return module.getRevision();
+    }
+
+    @Override
+    public String getPrefix() {
+        return module.getName();
+    }
+}
similarity index 82%
rename from restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/rest/services/impl/ModuleImpl.java
rename to restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/rest/services/impl/FakeRestconfModule.java
index 9857c4493ff68d25d6c6b6acb91d08a11125a4b1..a30b45463f5b34a2541a7775287b3997c97d5faf 100644 (file)
@@ -7,13 +7,13 @@
  */
 package org.opendaylight.restconf.rest.services.impl;
 
+import com.google.common.collect.Collections2;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
 import java.net.URI;
-import java.net.URISyntaxException;
 import java.text.ParseException;
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Date;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 import org.opendaylight.netconf.sal.restconf.impl.RestconfDocumentedException;
@@ -40,35 +40,32 @@ import org.opendaylight.yangtools.yang.model.api.UsesNode;
  * Special case only use by GET restconf/operations (since moment of old Yang
  * parser and old yang model API removal) to build and use fake module to create
  * new schema context
- *
  */
-class ModuleImpl implements Module {
+final class FakeRestconfModule implements Module {
 
-    private final List<DataSchemaNode> listChild = new ArrayList<>();
-    static QNameModule moduleQName;
+    static final QNameModule QNAME;
     static {
-        Date date = null;
+        Date date;
         try {
             date = SimpleDateFormatUtil.getRevisionFormat().parse("2016-06-28");
         } catch (final ParseException e) {
-            throw new RestconfDocumentedException("Problem while parsing revision.", e);
-        }
-        try {
-            moduleQName = QNameModule.create(new URI("urn:ietf:params:xml:ns:yang:ietf-restconf"), date);
-        } catch (final URISyntaxException e) {
-            throw new RestconfDocumentedException("Problem while creating URI.", e);
+            throw new ExceptionInInitializerError(e);
         }
+        QNAME = QNameModule.create(URI.create("urn:ietf:params:xml:ns:yang:ietf-restconf"), date).intern();
     }
 
+    private final Collection<DataSchemaNode> children;
+    private final ImmutableSet<ModuleImport> imports;
+
     /**
-     * Set container for this module
-     *
-     * @param fakeContSchNode
-     *            - fake container schema node
+     * Instantiate a new fake module
      *
+     * @param neededModules needed import statements
+     * @param child fake child container
      */
-    public ModuleImpl(final ContainerSchemaNode fakeContSchNode) {
-        this.listChild.add(fakeContSchNode);
+    public FakeRestconfModule(final Collection<Module> neededModules, final ContainerSchemaNode child) {
+        this.children = ImmutableList.of(child);
+        this.imports = ImmutableSet.copyOf(Collections2.transform(neededModules, FakeModuleImport::new));
     }
 
     @Override
@@ -78,7 +75,7 @@ class ModuleImpl implements Module {
 
     @Override
     public Collection<DataSchemaNode> getChildNodes() {
-        return this.listChild;
+        return this.children;
     }
 
     @Override
@@ -88,12 +85,12 @@ class ModuleImpl implements Module {
 
     @Override
     public DataSchemaNode getDataChildByName(final QName name) {
-        for (final DataSchemaNode node : this.listChild) {
+        for (final DataSchemaNode node : this.children) {
             if (node.getQName().equals(name)) {
                 return node;
             }
         }
-        throw new RestconfDocumentedException(name + " is not in child of " + ModuleImpl.moduleQName);
+        throw new RestconfDocumentedException(name + " is not in child of " + FakeRestconfModule.QNAME);
     }
 
     @Override
@@ -108,7 +105,7 @@ class ModuleImpl implements Module {
 
     @Override
     public QNameModule getQNameModule() {
-        return moduleQName;
+        return QNAME;
     }
 
     @Override
@@ -118,12 +115,12 @@ class ModuleImpl implements Module {
 
     @Override
     public URI getNamespace() {
-        return moduleQName.getNamespace();
+        return QNAME.getNamespace();
     }
 
     @Override
     public Date getRevision() {
-        return moduleQName.getRevision();
+        return QNAME.getRevision();
     }
 
     @Override
@@ -158,12 +155,12 @@ class ModuleImpl implements Module {
 
     @Override
     public Set<ModuleImport> getImports() {
-        return new HashSet<>();
+        return imports;
     }
 
     @Override
     public Set<Module> getSubmodules() {
-        return new HashSet<>();
+        return ImmutableSet.of();
     }
 
     @Override
index e14fa8fe6bf8658199ca3750e31f21c04193aa2b..f6a70a9ace136b2a5cde731a909fec172e453c67 100644 (file)
@@ -8,9 +8,9 @@
 package org.opendaylight.restconf.rest.services.impl;
 
 import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableSet;
 import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
+import java.util.Collection;
 import java.util.Set;
 import javax.ws.rs.core.UriInfo;
 import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
@@ -26,10 +26,8 @@ import org.opendaylight.restconf.handlers.SchemaContextHandler;
 import org.opendaylight.restconf.rest.services.api.RestconfOperationsService;
 import org.opendaylight.restconf.utils.RestconfConstants;
 import org.opendaylight.restconf.utils.parser.ParserIdentifier;
-import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
@@ -106,32 +104,35 @@ public class RestconfOperationsServiceImpl implements RestconfOperationsService
      * @return {@link NormalizedNodeContext}
      */
     private static NormalizedNodeContext getOperations(final Set<Module> modules, final DOMMountPoint mountPoint) {
-        final ContainerSchemaNodeImpl fakeCont = new ContainerSchemaNodeImpl();
-        final List<LeafNode<Object>> listRpcNodes = new ArrayList<>();
+        final Collection<Module> neededModules = new ArrayList<>(modules.size());
+        final ArrayList<LeafSchemaNode> fakeRpcSchema = new ArrayList<>();
+
         for (final Module m : modules) {
-            for (final RpcDefinition rpc : m.getRpcs()) {
+            final Set<RpcDefinition> rpcs = m.getRpcs();
+            if (!rpcs.isEmpty()) {
+                neededModules.add(m);
 
-                final LeafSchemaNode fakeLeaf = new LeafSchemaNodeImpl(fakeCont.getPath(),
-                        QName.create(ModuleImpl.moduleQName, m.getName() + ":" + rpc.getQName().getLocalName()));
-                fakeCont.addNodeChild(fakeLeaf);
-                listRpcNodes.add(Builders.leafBuilder(fakeLeaf).build());
+                fakeRpcSchema.ensureCapacity(fakeRpcSchema.size() + rpcs.size());
+                rpcs.forEach(rpc -> fakeRpcSchema.add(new FakeLeafSchemaNode(rpc.getQName())));
             }
         }
-        final ContainerSchemaNode fakeContSchNode = fakeCont;
+
+        final ContainerSchemaNode fakeCont = new FakeContainerSchemaNode(fakeRpcSchema);
         final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> containerBuilder = Builders
-                .containerBuilder(fakeContSchNode);
+                .containerBuilder(fakeCont);
 
-        for (final LeafNode<Object> rpcNode : listRpcNodes) {
-            containerBuilder.withChild(rpcNode);
+        for (final LeafSchemaNode leaf : fakeRpcSchema) {
+            containerBuilder.withChild(Builders.leafBuilder(leaf).build());
         }
 
-        final Module fakeModule = new ModuleImpl(fakeContSchNode);
+        final Collection<Module> fakeModules = new ArrayList<>(neededModules.size() + 1);
+        neededModules.forEach(imp -> fakeModules.add(new FakeImportedModule(imp)));
+        fakeModules.add(new FakeRestconfModule(neededModules, fakeCont));
 
-        final Set<Module> fakeModules = new HashSet<>();
-        fakeModules.add(fakeModule);
-        final SchemaContext fakeSchemaCtx = EffectiveSchemaContext.resolveSchemaContext(fakeModules);
+        final SchemaContext fakeSchemaCtx = EffectiveSchemaContext.resolveSchemaContext(
+            ImmutableSet.copyOf(fakeModules));
         final InstanceIdentifierContext<ContainerSchemaNode> instanceIdentifierContext = new InstanceIdentifierContext<>(
-                null, fakeContSchNode, mountPoint, fakeSchemaCtx);
+                null, fakeCont, mountPoint, fakeSchemaCtx);
         return new NormalizedNodeContext(instanceIdentifierContext, containerBuilder.build());
     }
 
index eea5db5d55283953ae9ebc8bcacf926bc2a08e07..6578d5114967320950f347f7f6b1f6d29b79f92e 100644 (file)
@@ -7,10 +7,14 @@
  */
 package org.opendaylight.restconf.rest.services.impl;
 
-import java.util.ArrayList;
-import java.util.List;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import com.google.common.collect.ImmutableSet;
+import java.net.URI;
+import java.util.Set;
 import javax.ws.rs.core.UriInfo;
-import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mock;
@@ -20,6 +24,8 @@ import org.opendaylight.controller.md.sal.rest.common.TestRestconfUtils;
 import org.opendaylight.netconf.sal.restconf.impl.NormalizedNodeContext;
 import org.opendaylight.restconf.handlers.DOMMountPointServiceHandler;
 import org.opendaylight.restconf.handlers.SchemaContextHandler;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.QNameModule;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
@@ -37,7 +43,7 @@ public class RestconfOperationsServiceTest {
     private SchemaContextHandler schemaContextHandler;
     private DOMMountPointServiceHandler domMountPointServiceHandler;
 
-    private static final List<String> listOfRpcsNames = new ArrayList<>();
+    private Set<QName> listOfRpcsNames;
 
     @Before
     public void init() throws Exception {
@@ -46,26 +52,31 @@ public class RestconfOperationsServiceTest {
         this.schemaContextHandler = new SchemaContextHandler();
         this.schemaContextHandler.onGlobalContextUpdated(this.schemaContext);
         this.domMountPointServiceHandler = new DOMMountPointServiceHandler(this.domMountPointService);
-        listOfRpcsNames.add("module2:dummy-rpc2-module2");
-        listOfRpcsNames.add("module2:dummy-rpc1-module2");
-        listOfRpcsNames.add("module1:dummy-rpc2-module1");
-        listOfRpcsNames.add("module1:dummy-rpc1-module1");
+
+        final QNameModule module1 = QNameModule.create(new URI("module:1"), null);
+        final QNameModule module2 = QNameModule.create(new URI("module:2"), null);
+
+        listOfRpcsNames = ImmutableSet.of(
+            QName.create(module1, "dummy-rpc1-module1"), QName.create(module1, "dummy-rpc2-module1"),
+            QName.create(module2, "dummy-rpc1-module2"), QName.create(module2, "dummy-rpc2-module2"));
     }
 
     @Test
     public void getOperationsTest() {
-        final RestconfOperationsServiceImpl oper = new RestconfOperationsServiceImpl(this.schemaContextHandler, this.domMountPointServiceHandler);
+        final RestconfOperationsServiceImpl oper = new RestconfOperationsServiceImpl(this.schemaContextHandler,
+            this.domMountPointServiceHandler);
         final NormalizedNodeContext operations = oper.getOperations(this.uriInfo);
         final ContainerNode data = (ContainerNode) operations.getData();
-        Assert.assertTrue(
-                data.getNodeType().getNamespace().toString().equals("urn:ietf:params:xml:ns:yang:ietf-restconf"));
-        Assert.assertTrue(data.getNodeType().getLocalName().equals("operations"));
-        for (final DataContainerChild<? extends PathArgument, ?> dataContainerChild : data.getValue()) {
-            Assert.assertTrue(dataContainerChild.getNodeType().getNamespace().toString()
-                    .equals("urn:ietf:params:xml:ns:yang:ietf-restconf"));
-            Assert.assertTrue(listOfRpcsNames.contains(dataContainerChild.getNodeType().getLocalName()));
-            Assert.assertTrue(dataContainerChild.getValue() == null);
-        }
+        assertEquals("urn:ietf:params:xml:ns:yang:ietf-restconf", data.getNodeType().getNamespace().toString());
+        assertEquals("operations", data.getNodeType().getLocalName());
 
+        assertEquals(4, data.getValue().size());
+
+        for (final DataContainerChild<? extends PathArgument, ?> child : data.getValue()) {
+            assertNull(child.getValue());
+
+            final QName qname = child.getNodeType().withoutRevision();
+            assertTrue(listOfRpcsNames.contains(qname));
+        }
     }
 }
index 4e8875789b2f22963c0835b6b2129b26efd79cc3..0ab186c3058129092b85bc8c916ecbc77cea01ff 100644 (file)
@@ -101,9 +101,9 @@ public class CreateStreamUtilTest {
 
         assertTrue(lfSchemaNode instanceof LeafSchemaNode);
 
-        final QName rpcQname = QName.create("http://netconfcentral.org/ns/toaster", "2009-11-20", toasterValue);
         final Object o;
         if ("toaster".equals(toasterValue)) {
+            final QName rpcQname = QName.create("http://netconfcentral.org/ns/toaster", "2009-11-20", toasterValue);
             o = YangInstanceIdentifier.builder().node(rpcQname).build();
         } else {
             o = toasterValue;