*/
package org.opendaylight.controller.config.manager.impl.dynamicmbean;
-import static java.lang.String.format;
-
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import org.opendaylight.controller.config.api.ModuleIdentifier;
+import org.opendaylight.controller.config.api.annotations.Description;
+import org.opendaylight.controller.config.api.annotations.RequireInterface;
+import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
+import org.opendaylight.controller.config.manager.impl.util.InterfacesHelper;
+import org.opendaylight.controller.config.spi.Module;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.NotificationListener;
import javax.management.ObjectName;
import javax.management.ReflectionException;
+import java.lang.reflect.Array;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
-import org.opendaylight.controller.config.api.ModuleIdentifier;
-import org.opendaylight.controller.config.api.annotations.Description;
-import org.opendaylight.controller.config.api.annotations.RequireInterface;
-import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
-import org.opendaylight.controller.config.manager.impl.util.InterfacesHelper;
-import org.opendaylight.controller.config.spi.Module;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import static java.lang.String.format;
/**
* Contains common code for readable/rw dynamic mbean wrappers. Routes all
} catch (InstanceNotFoundException e) {
new MBeanException(e);
}
+
if (obj instanceof ObjectName) {
AttributeHolder attributeHolder = attributeHolderMap
.get(attributeName);
}
return obj;
}
+
+
+ if(isDependencyListAttr(attributeName, obj)) {
+ obj = fixDependencyListAttribute(obj);
+ }
+
return obj;
+ }
+
+ private Object fixDependencyListAttribute(Object attribute) {
+ if(attribute.getClass().isArray() == false)
+ throw new IllegalArgumentException("Unexpected attribute type, should be an array, but was " + attribute.getClass());
+
+ for (int i = 0; i < Array.getLength(attribute); i++) {
+
+ Object on = Array.get(attribute, i);
+ if(on instanceof ObjectName == false)
+ throw new IllegalArgumentException("Unexpected attribute type, should be an ObjectName, but was " + on.getClass());
+ on = fixObjectName((ObjectName) on);
+
+ Array.set(attribute, i, on);
+ }
+
+ return attribute;
+ }
+
+ private boolean isDependencyListAttr(String attributeName, Object attribute) {
+ if (attributeHolderMap.containsKey(attributeName) == false)
+ return false;
+
+ AttributeHolder attributeHolder = attributeHolderMap.get(attributeName);
+ boolean isDepList = true;
+ isDepList &= attributeHolder.getRequireInterfaceOrNull() != null;
+ isDepList &= attribute instanceof ObjectName[];
+ return isDepList;
}
protected ObjectName fixObjectName(ObjectName on) {
*/
package org.opendaylight.controller.config.manager.impl.dynamicmbean;
-import java.lang.reflect.Method;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
+import org.opendaylight.controller.config.api.annotations.Description;
+import org.opendaylight.controller.config.api.annotations.RequireInterface;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
import javax.management.MBeanAttributeInfo;
import javax.management.ObjectName;
-
-import org.opendaylight.controller.config.api.annotations.Description;
-import org.opendaylight.controller.config.api.annotations.RequireInterface;
+import java.lang.reflect.Method;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
@Immutable
class AttributeHolder {
private final RequireInterface requireInterfaceAnnotation;
private final String attributeType;
+ public static final Set<Class<?>> PERMITTED_PARAMETER_TYPES_FOR_DEPENDENCY_SETTER = new HashSet<>();
+
+ static {
+ PERMITTED_PARAMETER_TYPES_FOR_DEPENDENCY_SETTER.add(ObjectName.class);
+ PERMITTED_PARAMETER_TYPES_FOR_DEPENDENCY_SETTER.add(ObjectName[].class);
+ PERMITTED_PARAMETER_TYPES_FOR_DEPENDENCY_SETTER.add(List.class);
+ }
+
public AttributeHolder(String name, Object object, String returnType,
boolean writable,
@Nullable RequireInterface requireInterfaceAnnotation,
static RequireInterface findRequireInterfaceAnnotation(final Method setter,
Set<Class<?>> inspectedInterfaces) {
- // only allow setX(ObjectName y) or setX(ObjectName[] y) to continue
- if (setter.getParameterTypes().length != 1
- || (setter.getParameterTypes()[0].equals(ObjectName.class) == false && setter
- .getParameterTypes()[0].equals(ObjectName[].class) == false)) {
+ // only allow setX(ObjectName y) or setX(ObjectName[] y) or setX(List<ObjectName> y) to continue
+
+ if (setter.getParameterTypes().length > 1)
+ return null;
+ if(PERMITTED_PARAMETER_TYPES_FOR_DEPENDENCY_SETTER.contains(setter.getParameterTypes()[0]) == false)
return null;
- }
List<RequireInterface> foundRequireInterfaces = AnnotationsHelper
.findMethodAnnotationInSuperClassesAndIfcs(setter, RequireInterface.class, inspectedInterfaces);
*/
package org.opendaylight.controller.config.manager.impl.dynamicmbean;
-import java.lang.reflect.Method;
+import org.opendaylight.controller.config.api.ModuleIdentifier;
+import org.opendaylight.controller.config.api.ValidationException;
+import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
+import org.opendaylight.controller.config.manager.impl.TransactionIdentifier;
+import org.opendaylight.controller.config.spi.Module;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import javax.annotation.concurrent.ThreadSafe;
import javax.management.Attribute;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.management.ReflectionException;
-
-import org.opendaylight.controller.config.api.ModuleIdentifier;
-import org.opendaylight.controller.config.api.ValidationException;
-import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
-import org.opendaylight.controller.config.manager.impl.TransactionIdentifier;
-import org.opendaylight.controller.config.spi.Module;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import java.lang.reflect.Method;
/**
* Wraps {@link org.opendaylight.controller.config.spi.Module} instance in a
try {
if (attribute.getValue() instanceof ObjectName) {
- AttributeHolder attributeHolder = attributeHolderMap
- .get(attribute.getName());
- if (attributeHolder.getRequireInterfaceOrNull() != null) {
- attribute = new Attribute(attribute.getName(),
- fixObjectName((ObjectName) attribute.getValue()));
- } else {
- attribute = new Attribute(attribute.getName(),
- attribute.getValue());
- }
+ attribute = fixDependencyAttribute(attribute);
+ } else if(attribute.getValue() instanceof ObjectName[]) {
+ attribute = fixDependencyListAttribute(attribute);
}
+
internalServer.setAttribute(objectNameInternal, attribute);
} catch (InstanceNotFoundException e) {
throw new MBeanException(e);
}
+ private Attribute fixDependencyListAttribute(Attribute attribute) {
+ AttributeHolder attributeHolder = attributeHolderMap
+ .get(attribute.getName());
+ if (attributeHolder.getRequireInterfaceOrNull() != null) {
+ attribute = new Attribute(attribute.getName(),
+ fixObjectNames((ObjectName[]) attribute.getValue()));
+ }
+ return attribute;
+ }
+
+ private Attribute fixDependencyAttribute(Attribute attribute) {
+ AttributeHolder attributeHolder = attributeHolderMap
+ .get(attribute.getName());
+ if (attributeHolder.getRequireInterfaceOrNull() != null) {
+ attribute = new Attribute(attribute.getName(),
+ fixObjectName((ObjectName) attribute.getValue()));
+ } else {
+ attribute = new Attribute(attribute.getName(),
+ attribute.getValue());
+ }
+ return attribute;
+ }
+
+ private ObjectName[] fixObjectNames(ObjectName[] dependencies) {
+ int i = 0;
+
+ for (ObjectName dependencyOn : dependencies) {
+ dependencies[i++] = fixObjectName(dependencyOn);
+ }
+
+ return dependencies;
+ }
+
@Override
public AttributeList setAttributes(AttributeList attributes) {
AttributeList result = new AttributeList();
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
- <groupId>org.opendaylight.yangtools.model</groupId>
- <artifactId>ietf-inet-types</artifactId>
+ <groupId>org.opendaylight.yangtools.model</groupId>
+ <artifactId>ietf-inet-types</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.bgpcep</groupId>
+ <artifactId>mockito-configuration</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>config-manager</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>config-manager</artifactId>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>config-util</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
</dependency>
</dependencies>
--- /dev/null
+package org.opendaylight.controller.config.yang.test.impl;
+
+import com.google.common.collect.Lists;
+import junit.framework.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.controller.config.api.ConflictingVersionException;
+import org.opendaylight.controller.config.api.ValidationException;
+import org.opendaylight.controller.config.api.jmx.CommitStatus;
+import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
+import org.opendaylight.controller.config.manager.impl.AbstractConfigTest;
+import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
+import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
+
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.ObjectName;
+import java.util.ArrayList;
+import java.util.List;
+
+public class NetconfTestImplModuleTest extends AbstractConfigTest {
+
+ public static final String TESTING_DEP_PREFIX = "testing-dep";
+ private NetconfTestImplModuleFactory factory;
+ private final String instanceName = "n1";
+
+ @Before
+ public void setUp() {
+
+ factory = new NetconfTestImplModuleFactory();
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory,
+ new DepTestImplModuleFactory()));
+ }
+
+ @Test
+ public void testDependencyList() throws InstanceAlreadyExistsException, ValidationException,
+ ConflictingVersionException {
+ ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
+
+ ObjectName on = createInstance(transaction, instanceName, 4);
+ transaction.validateConfig();
+ CommitStatus status = transaction.commit();
+
+ assertBeanCount(1, factory.getImplementationName());
+ assertBeanCount(4 + 1, DepTestImplModuleFactory.NAME);
+ assertStatus(status, 1 + 4 + 1, 0, 0);
+
+ transaction = configRegistryClient.createTransaction();
+
+ NetconfTestImplModuleMXBean proxy = transaction.newMXBeanProxy(ObjectNameUtil.withoutTransactionName(on),
+ NetconfTestImplModuleMXBean.class);
+ proxy.getComplexList();
+ List<ObjectName> testingDeps = proxy.getTestingDeps();
+ ObjectName testingDep = proxy.getTestingDep();
+
+ Assert.assertEquals(TESTING_DEP_PREFIX, ObjectNameUtil.getInstanceName(testingDep));
+ assertTestingDeps(testingDeps, 4);
+
+ transaction.abortConfig();
+ }
+
+ private void assertTestingDeps(List<ObjectName> testingDeps, int i) {
+ Assert.assertEquals(i, testingDeps.size());
+
+ int c = 1;
+ for (ObjectName testingDep : testingDeps) {
+ Assert.assertEquals(TESTING_DEP_PREFIX + Integer.toString(c++), ObjectNameUtil.getInstanceName(testingDep));
+ }
+ }
+
+
+ private ObjectName createInstance(ConfigTransactionJMXClient transaction, String instanceName, int depsCount)
+ throws InstanceAlreadyExistsException {
+ ObjectName nameCreated = transaction.createModule(factory.getImplementationName(), instanceName);
+ NetconfTestImplModuleMXBean mxBean = transaction.newMXBeanProxy(nameCreated, NetconfTestImplModuleMXBean.class);
+
+ ObjectName dep = transaction.createModule(DepTestImplModuleFactory.NAME, TESTING_DEP_PREFIX);
+ mxBean.setTestingDep(dep);
+
+ ArrayList<ObjectName> testingDeps = Lists.newArrayList();
+ for (int i = 0; i < depsCount; i++) {
+ dep = transaction.createModule(DepTestImplModuleFactory.NAME, TESTING_DEP_PREFIX + Integer.toString(i + 1));
+ testingDeps.add(dep);
+ }
+ mxBean.setTestingDeps(testingDeps);
+
+ return nameCreated;
+ }
+
+}
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>
- zeromq-routingtable.implementation
+ remoterpc-routingtable.implementation
</artifactId>
<version>0.4.1-SNAPSHOT</version>
</dependency>
<logger name="org.opendaylight.controller.sal.implementation" level="INFO"/>
<logger name="org.opendaylight.controller.sal.implementation.internal.Inventory" level="INFO"/>
<logger name="org.opendaylight.controller.sal.implementation.internal.Topology" level="INFO"/>
- <!-- zeromq router and zeromq routing table -->
+ <!-- remoterpc router and remoterpc routing table -->
<logger name="org.opendaylight.controller.sal.connector.remoterpc" level="INFO" />
<!-- Functional Modules -->
<logger name="org.opendaylight.controller.arphandler" level="INFO"/>
}
if (target != null) {
// Update Configuration database
- target.toggleInstallation();
- target.setStatus(StatusCode.SUCCESS.toString());
+ if (target.getHardTimeout() != null || target.getIdleTimeout() != null) {
+ /*
+ * No need for checking if actual values: these strings were
+ * validated at configuration creation. Also, after a switch
+ * down scenario, no use to reinstall a timed flow. Mark it as
+ * "do not install". User can manually toggle it.
+ */
+ target.toggleInstallation();
+ }
+ target.setStatus(StatusCode.GONE.toString());
staticFlows.put(key, target);
}
<module>sal-rest-connector</module>
<module>sal-netconf-connector</module>
- <module>zeromq-routingtable/implementation</module>
+ <module>remoterpc-routingtable/implementation</module>
<module>sal-remoterpc-connector/implementation</module>
<!-- Clustered Data Store -->
<module>clustered-data-store/implementation</module>
<tag>HEAD</tag>
</scm>
- <artifactId>zeromq-routingtable.implementation</artifactId>
+ <artifactId>remoterpc-routingtable.implementation</artifactId>
<version>0.4.1-SNAPSHOT</version>
<packaging>bundle</packaging>
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashSet;
+import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentMap;
return this.routingTableCache;
}
+ /**
+ * This is used from integration test NP rest API to check out the result of the
+ * cache population
+ * <Note> For testing purpose only-- use it wisely</Note>
+ * @return
+ */
+ public String dumpRoutingTableCache(){
+ Set<Map.Entry<I, R>> cacheEntrySet = this.routingTableCache.entrySet();
+ StringBuilder sb = new StringBuilder();
+ for(Map.Entry<I,R> entry:cacheEntrySet){
+ sb.append("Key:").append(entry.getKey()).append("---->Value:")
+ .append((entry.getValue() != null)?entry.getValue():"null")
+ .append("\n");
+ }
+ return sb.toString();
+ }
+
/**
* Invoked when a new entry is available in the cache, the key is only
* provided, the value will come as an entryUpdate invocation
<tag>HEAD</tag>
</scm>
- <artifactId>zeromq-routingtable.integrationtest</artifactId>
+ <artifactId>remoterpc-routingtable.integrationtest</artifactId>
<version>0.4.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.opendaylight.controller</groupId>
- <artifactId>zeromq-routingtable.implementation</artifactId>
+ <artifactId>remoterpc-routingtable.implementation</artifactId>
<version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
.versionAsInProject(),
mavenBundle(ODL, "sal-connector-api")
.versionAsInProject(),
- mavenBundle(ODL, "zeromq-routingtable.implementation")
+ mavenBundle(ODL, "remoterpc-routingtable.implementation")
.versionAsInProject(),
mavenBundle("org.jboss.spec.javax.transaction",
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>sal-remoterpc-connector-test-parent</artifactId>
+ <groupId>org.opendaylight.controller.tests</groupId>
+ <version>1.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>remoterpc-routingtable-nb-it</artifactId>
+ <packaging>bundle</packaging>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <version>${bundle.plugin.version}</version>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Export-Package>
+ org.opendaylight.controller.tests.zmqroutingtable.rest
+ </Export-Package>
+ <Import-Package>
+ com.sun.jersey.spi.container.servlet,
+ org.codehaus.jackson.annotate,
+ javax.ws.rs,
+ javax.ws.rs.core,
+ javax.xml.bind,
+ javax.xml.bind.annotation,
+ org.slf4j,
+ org.apache.catalina.filters,
+ org.codehaus.jackson.jaxrs,
+ org.opendaylight.controller.sal.utils,
+ org.opendaylight.yangtools.yang.common,
+ org.opendaylight.controller.sal.connector.api,
+ org.opendaylight.controller.sal.connector.remoterpc.api,
+ org.opendaylight.controller.sal.connector.remoterpc.impl,
+ org.osgi.framework,
+ com.google.common.base,
+ org.opendaylight.yangtools.yang.data.api,
+ !org.codehaus.enunciate.jaxrs
+
+ </Import-Package>
+ <Web-ContextPath>/controller/nb/v2/zmqnbrt</Web-ContextPath>
+ <Jaxrs-Resources>,${classes;ANNOTATION;javax.ws.rs.Path}</Jaxrs-Resources>
+ </instructions>
+ <manifestLocation>${project.basedir}/src/main/resources/META-INF</manifestLocation>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <dependencies>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>containermanager</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>commons.northbound</artifactId>
+ <version>0.4.1-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ <version>5.0.0</version>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>remoterpc-routingtable.implementation</artifactId>
+ <version>0.4.1-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ </dependency>
+ </dependencies>
+
+ </project>
--- /dev/null
+package org.opendaylight.controller.tests.zmqroutingtable.rest;
+
+import org.opendaylight.controller.sal.connector.api.RpcRouter;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+
+import java.io.Serializable;
+import java.net.URI;
+
+/**
+ * @author: syedbahm
+ * Date: 12/10/13
+ */
+public class RouteIdentifierImpl implements RpcRouter.RouteIdentifier, Serializable {
+
+ private final URI namespace;
+ private final QName QNAME;
+ private final QName instance;
+
+ public RouteIdentifierImpl() {
+ namespace = URI.create("http://cisco.com/example");
+ QNAME = new QName(namespace, "global");
+ instance = new QName(URI.create("127.0.0.1"), "local");
+ }
+
+ public RouteIdentifierImpl(String url,String instanceIP){
+ namespace = URI.create(url);
+ QNAME = new QName(namespace,"global");
+ instance = new QName(URI.create(instanceIP), "local");
+ }
+
+
+ @Override
+ public QName getContext() {
+ return QNAME;
+ }
+
+ @Override
+ public QName getType() {
+ return QNAME;
+ }
+
+ @Override
+ public org.opendaylight.yangtools.yang.data.api.InstanceIdentifier getRoute() {
+ return InstanceIdentifier.of(instance);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ RouteIdentifierImpl that = (RouteIdentifierImpl) o;
+
+ if (!QNAME.equals(that.QNAME)) return false;
+ if (!instance.equals(that.instance)) return false;
+ if (!namespace.equals(that.namespace)) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = namespace.hashCode();
+ result = 31 * result + QNAME.hashCode();
+ result = 31 * result + instance.hashCode();
+ return result;
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.opendaylight.controller.tests.zmqroutingtable.rest;
+
+import org.opendaylight.controller.sal.connector.remoterpc.api.RoutingTable;
+import org.opendaylight.controller.sal.connector.remoterpc.api.RoutingTableException;
+import org.opendaylight.controller.sal.connector.remoterpc.api.SystemException;
+import org.opendaylight.controller.sal.connector.remoterpc.impl.RoutingTableImpl;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleReference;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.ServiceReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import java.io.Serializable;
+import java.net.URI;
+
+@Path("router")
+public class Router implements Serializable {
+ private Logger _logger = LoggerFactory.getLogger(Router.class);
+ private final URI namespace = URI.create("http://cisco.com/example");
+ private final QName QNAME = new QName(namespace, "heartbeat");
+
+
+ @GET
+ @Path("/hello")
+ @Produces(MediaType.TEXT_PLAIN)
+ public String hello() {
+ return "Hello";
+ }
+
+
+
+
+ @GET
+ @Path("/rtadd")
+ @Produces(MediaType.TEXT_PLAIN)
+ public String addToRoutingTable(@QueryParam("nsp") String namespace,@QueryParam("inst") String instance,@QueryParam("port") String port) {
+ _logger.info("Invoking adding an entry in routing table");
+
+ BundleContext ctx = getBundleContext();
+ ServiceReference routingTableServiceReference = ctx.getServiceReference(RoutingTable.class);
+ if (routingTableServiceReference == null) {
+ _logger.debug("Could not get routing table impl reference");
+ return "Could not get routingtable referen ";
+ }
+ RoutingTableImpl routingTable = (RoutingTableImpl) ctx.getService(routingTableServiceReference);
+ if (routingTable == null) {
+ _logger.info("Could not get routing table service");
+ return "Could not get routing table service";
+ }
+
+
+ RouteIdentifierImpl rii = new RouteIdentifierImpl(namespace,instance);
+ try {
+ routingTable.addGlobalRoute(rii, instance+":"+ port);
+ } catch (RoutingTableException e) {
+ _logger.error("error in adding routing identifier" + e.getMessage());
+
+ } catch (SystemException e) {
+ _logger.error("error in adding routing identifier" + e.getMessage());
+ }
+
+ StringBuilder stringBuilder = new StringBuilder();
+ stringBuilder.append("Result of adding route:").append("\n")
+ .append(routingTable.dumpRoutingTableCache());
+ return stringBuilder.toString();
+ }
+
+ @GET
+ @Path("/rtdelete")
+ @Produces(MediaType.TEXT_PLAIN)
+ public String invokeDeleteRoutingTable(@QueryParam("nsp") String namespace,@QueryParam("inst") String instance) {
+ _logger.info("Invoking delete an entry in routing table");
+
+ BundleContext ctx = getBundleContext();
+ ServiceReference routingTableServiceReference = ctx.getServiceReference(RoutingTable.class);
+ if (routingTableServiceReference == null) {
+ _logger.debug("Could not get routing table impl reference");
+ return "Could not get routingtable referen ";
+ }
+ RoutingTableImpl routingTable = (RoutingTableImpl) ctx.getService(routingTableServiceReference);
+ if (routingTable == null) {
+ _logger.info("Could not get routing table service");
+ return "Could not get routing table service";
+ }
+
+
+ RouteIdentifierImpl rii = new RouteIdentifierImpl(namespace,instance);
+ try {
+ routingTable.removeGlobalRoute(rii);
+ } catch (RoutingTableException e) {
+ _logger.error("error in adding routing identifier" + e.getMessage());
+
+ } catch (SystemException e) {
+ _logger.error("error in adding routing identifier" + e.getMessage());
+ }
+
+
+ StringBuilder stringBuilder = new StringBuilder();
+ stringBuilder.append("Result of deleting route:").append("\n")
+ .append(routingTable.dumpRoutingTableCache());
+
+ return stringBuilder.toString();
+ }
+
+ @GET
+ @Path("/routingtable")
+ @Produces(MediaType.TEXT_PLAIN)
+ public String invokeGetRoutingTable() {
+ _logger.info("Invoking getting of routing table");
+
+ BundleContext ctx = getBundleContext();
+ ServiceReference routingTableServiceReference = ctx.getServiceReference(RoutingTable.class);
+ if (routingTableServiceReference == null) {
+ _logger.debug("Could not get routing table impl reference");
+ return "Could not get routingtable referen ";
+ }
+ RoutingTableImpl routingTable = (RoutingTableImpl) ctx.getService(routingTableServiceReference);
+ if (routingTable == null) {
+ _logger.info("Could not get routing table service");
+ return "Could not get routing table service";
+ }
+
+
+ StringBuilder stringBuilder = new StringBuilder();
+ stringBuilder.append("Result of getting routetable:").append("\n")
+ .append(routingTable.dumpRoutingTableCache());
+
+ return stringBuilder.toString();
+ }
+
+
+
+ private BundleContext getBundleContext() {
+ ClassLoader tlcl = Thread.currentThread().getContextClassLoader();
+ Bundle bundle = null;
+
+ if (tlcl instanceof BundleReference) {
+ bundle = ((BundleReference) tlcl).getBundle();
+ } else {
+ _logger.info("Unable to determine the bundle context based on " +
+ "thread context classloader.");
+ bundle = FrameworkUtil.getBundle(this.getClass());
+ }
+ return (bundle == null ? null : bundle.getBundleContext());
+ }
+
+
+
+}
--- /dev/null
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
+ version="3.0">
+ <servlet>
+ <servlet-name>JAXRSZmqRT</servlet-name>
+ <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
+ <init-param>
+ <param-name>javax.ws.rs.Application</param-name>
+ <param-value>org.opendaylight.controller.northbound.commons.NorthboundApplication</param-value>
+ </init-param>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+
+ <servlet-mapping>
+ <servlet-name>JAXRSZmqRT</servlet-name>
+ <url-pattern>/*</url-pattern>
+ </servlet-mapping>
+
+
+
+ <security-constraint>
+ <web-resource-collection>
+ <web-resource-name>NB api</web-resource-name>
+ <url-pattern>/*</url-pattern>
+ <http-method>POST</http-method>
+ <http-method>GET</http-method>
+ <http-method>PUT</http-method>
+ <http-method>PATCH</http-method>
+ <http-method>DELETE</http-method>
+ <http-method>HEAD</http-method>
+ </web-resource-collection>
+ <auth-constraint>
+ <role-name>System-Admin</role-name>
+ <role-name>Network-Admin</role-name>
+ <role-name>Network-Operator</role-name>
+ <role-name>Container-User</role-name>
+ </auth-constraint>
+ </security-constraint>
+
+ <security-role>
+ <role-name>System-Admin</role-name>
+ </security-role>
+ <security-role>
+ <role-name>Network-Admin</role-name>
+ </security-role>
+ <security-role>
+ <role-name>Network-Operator</role-name>
+ </security-role>
+ <security-role>
+ <role-name>Container-User</role-name>
+ </security-role>
+
+ <login-config>
+ <auth-method>BASIC</auth-method>
+ <realm-name>opendaylight</realm-name>
+ </login-config>
+</web-app>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
- <artifactId>zeromq-routingtable.implementation</artifactId>
+ <artifactId>remoterpc-routingtable.implementation</artifactId>
<!-- TODO: fix the version. Why is it not MD Sal project version?-->
<version>0.4.1-SNAPSHOT</version>
</dependency>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
- <artifactId>zeromq-routingtable.implementation</artifactId>
+ <artifactId>remoterpc-routingtable.implementation</artifactId>
<version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
import static com.google.common.base.Preconditions.checkNotNull;
import java.io.IOException;
-import java.util.*;
+import java.net.URI;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
import javax.activation.UnsupportedDataTypeException;
import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
+import org.opendaylight.controller.sal.restconf.impl.IdentityValuesDTO;
+import org.opendaylight.controller.sal.restconf.impl.IdentityValuesDTO.IdentityValue;
+import org.opendaylight.controller.sal.restconf.impl.RestCodec;
import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.*;
-import org.opendaylight.yangtools.yang.model.api.*;
-import org.opendaylight.yangtools.yang.model.api.type.*;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.data.api.SimpleNode;
+import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
+import org.opendaylight.yangtools.yang.model.api.ChoiceNode;
+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.LeafListSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.BooleanTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.DecimalTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.EmptyTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.IntegerTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.UnsignedIntegerTypeDefinition;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.google.common.base.Preconditions;
import com.google.gson.stream.JsonWriter;
private final Set<LeafListSchemaNode> foundLeafLists = new HashSet<>();
private final Set<ListSchemaNode> foundLists = new HashSet<>();
+ private final Logger logger = LoggerFactory.getLogger(JsonMapper.class);
public void write(JsonWriter writer, CompositeNode data, DataNodeContainer schema) throws IOException {
Preconditions.checkNotNull(writer);
private void writeValueOfNodeByType(JsonWriter writer, SimpleNode<?> node, TypeDefinition<?> type,
DataSchemaNode schema) throws IOException {
- String value = String.valueOf(node.getValue());
- TypeDefinition<?> baseType = resolveBaseTypeFrom(type);
+ TypeDefinition<?> baseType = RestUtil.resolveBaseTypeFrom(type);
- // TODO check InstanceIdentifierTypeDefinition,
- // IdentityrefTypeDefinition
+ // TODO check InstanceIdentifierTypeDefinition
if (baseType instanceof IdentityrefTypeDefinition) {
if (node.getValue() instanceof QName) {
- QName qName = (QName) node.getValue();
-
- ControllerContext contContext = ControllerContext.getInstance();
- String moduleName = contContext.findModuleByNamespace(qName.getNamespace());
-
- writer.value(moduleName + ":" + qName.getLocalName());
- }
-
- } else if (baseType instanceof LeafrefTypeDefinition) {
- ControllerContext contContext = ControllerContext.getInstance();
- LeafSchemaNode lfSchemaNode = contContext.resolveTypeFromLeafref((LeafrefTypeDefinition) baseType, schema);
- if (lfSchemaNode != null) {
- writeValueOfNodeByType(writer, node, lfSchemaNode.getType(), lfSchemaNode);
+ IdentityValuesDTO valueDTO = (IdentityValuesDTO) RestCodec.from(baseType).serialize(node.getValue());
+ IdentityValue valueFromDTO = valueDTO.getValuesWithNamespaces().get(0);
+ String moduleName = ControllerContext.getInstance().findModuleByNamespace(URI.create(valueFromDTO.getNamespace()));
+ writer.value(moduleName + ":" + valueFromDTO.getValue());
} else {
- writer.value(value);
+ logger.debug("Value of " + baseType.getQName().getNamespace() + ":"
+ + baseType.getQName().getLocalName() + " is not instance of " + QName.class + " but is " + node.getValue().getClass());
+ writer.value(String.valueOf(node.getValue()));
}
- } else if (baseType instanceof InstanceIdentifierTypeDefinition) {
- writer.value(((InstanceIdentifierTypeDefinition) baseType).getPathStatement().toString());
- } else if (baseType instanceof UnionTypeDefinition) {
- processTypeIsUnionType(writer, (UnionTypeDefinition) baseType, value);
} else if (baseType instanceof DecimalTypeDefinition || baseType instanceof IntegerTypeDefinition
|| baseType instanceof UnsignedIntegerTypeDefinition) {
- writer.value(new NumberForJsonWriter(value));
+ writer.value(new NumberForJsonWriter((String) RestCodec.from(baseType).serialize(node.getValue())));
} else if (baseType instanceof BooleanTypeDefinition) {
- writer.value(Boolean.parseBoolean(value));
+ writer.value(Boolean.parseBoolean((String) RestCodec.from(baseType).serialize(node.getValue())));
} else if (baseType instanceof EmptyTypeDefinition) {
writeEmptyDataTypeToJson(writer);
} else {
+ String value = String.valueOf(RestCodec.from(baseType).serialize(node.getValue()));
+ if (value == null) {
+ value = String.valueOf(node.getValue());
+ }
writer.value(value.equals("null") ? "" : value);
}
}
- private void processTypeIsUnionType(JsonWriter writer, UnionTypeDefinition unionType, String value)
- throws IOException {
- if (value == null) {
- writeEmptyDataTypeToJson(writer);
- } else if ((isNumber(value))
- && containsType(unionType, UnsignedIntegerTypeDefinition.class, IntegerTypeDefinition.class,
- DecimalTypeDefinition.class)) {
- writer.value(new NumberForJsonWriter(value));
- } else if (isBoolean(value) && containsType(unionType, BooleanTypeDefinition.class)) {
- writer.value(Boolean.parseBoolean(value));
- } else {
- writer.value(value);
- }
- }
-
- private boolean isBoolean(String value) {
- if (value.equals("true") || value.equals("false")) {
- return true;
- }
- return false;
- }
-
private void writeEmptyDataTypeToJson(JsonWriter writer) throws IOException {
writer.beginArray();
writer.nullValue();
writer.endArray();
}
- private boolean isNumber(String value) {
- try {
- Double.valueOf(value);
- } catch (NumberFormatException e) {
- return false;
- }
- return true;
- }
-
- private boolean containsType(UnionTypeDefinition unionType, Class<?>... searchedTypes) {
- List<TypeDefinition<?>> allUnionSubtypes = resolveAllUnionSubtypesFrom(unionType);
-
- for (TypeDefinition<?> unionSubtype : allUnionSubtypes) {
- for (Class<?> searchedType : searchedTypes) {
- if (searchedType.isInstance(unionSubtype)) {
- return true;
- }
- }
- }
- return false;
- }
-
- private List<TypeDefinition<?>> resolveAllUnionSubtypesFrom(UnionTypeDefinition inputType) {
- List<TypeDefinition<?>> result = new ArrayList<>();
- for (TypeDefinition<?> subtype : inputType.getTypes()) {
- TypeDefinition<?> resolvedSubtype = subtype;
-
- resolvedSubtype = resolveBaseTypeFrom(subtype);
-
- if (resolvedSubtype instanceof UnionTypeDefinition) {
- List<TypeDefinition<?>> subtypesFromRecursion = resolveAllUnionSubtypesFrom((UnionTypeDefinition) resolvedSubtype);
- result.addAll(subtypesFromRecursion);
- } else {
- result.add(resolvedSubtype);
- }
- }
-
- return result;
- }
-
- private TypeDefinition<?> resolveBaseTypeFrom(TypeDefinition<?> type) {
- return type.getBaseType() != null ? resolveBaseTypeFrom(type.getBaseType()) : type;
- }
-
private void writeName(Node<?> node, DataSchemaNode schema, JsonWriter writer) throws IOException {
String nameForOutput = node.getNodeType().getLocalName();
if (schema.isAugmenting()) {
import org.opendaylight.controller.sal.restconf.impl.CompositeNodeWrapper;
import org.opendaylight.controller.sal.restconf.impl.EmptyNodeWrapper;
import org.opendaylight.controller.sal.restconf.impl.SimpleNodeWrapper;
+import org.opendaylight.controller.sal.restconf.impl.IdentityValuesDTO;
import com.google.common.collect.Lists;
import com.google.gson.JsonElement;
}
private CompositeNodeWrapper createStructureWithRoot(String rootObjectName, JsonObject rootObject) {
- CompositeNodeWrapper firstNode = new CompositeNodeWrapper(getNamespaceFrom(rootObjectName),
- getLocalNameFrom(rootObjectName));
+ CompositeNodeWrapper firstNode = new CompositeNodeWrapper(getNamespaceFor(rootObjectName),
+ getLocalNameFor(rootObjectName));
for (Entry<String, JsonElement> childOfFirstNode : rootObject.entrySet()) {
addChildToParent(childOfFirstNode.getKey(), childOfFirstNode.getValue(), firstNode);
}
private void addChildToParent(String childName, JsonElement childType, CompositeNodeWrapper parent) {
if (childType.isJsonObject()) {
- CompositeNodeWrapper child = new CompositeNodeWrapper(getNamespaceFrom(childName),
- getLocalNameFrom(childName));
+ CompositeNodeWrapper child = new CompositeNodeWrapper(getNamespaceFor(childName),
+ getLocalNameFor(childName));
parent.addValue(child);
for (Entry<String, JsonElement> childOfChild : childType.getAsJsonObject().entrySet()) {
addChildToParent(childOfChild.getKey(), childOfChild.getValue(), child);
}
} else if (childType.isJsonArray()) {
if (childType.getAsJsonArray().size() == 1 && childType.getAsJsonArray().get(0).isJsonNull()) {
- parent.addValue(new EmptyNodeWrapper(getNamespaceFrom(childName), getLocalNameFrom(childName)));
+ parent.addValue(new EmptyNodeWrapper(getNamespaceFor(childName), getLocalNameFor(childName)));
} else {
for (JsonElement childOfChildType : childType.getAsJsonArray()) {
} else if (childType.isJsonPrimitive()) {
JsonPrimitive childPrimitive = childType.getAsJsonPrimitive();
String value = childPrimitive.getAsString();
- parent.addValue(new SimpleNodeWrapper(getNamespaceFrom(childName), getLocalNameFrom(childName), value));
+ parent.addValue(new SimpleNodeWrapper(getNamespaceFor(childName), getLocalNameFor(childName),
+ resolveValueOfElement(value)));
}
}
- private URI getNamespaceFrom(String jsonElementName) {
- int indexOfDelimeter = jsonElementName.lastIndexOf(':');
- if (indexOfDelimeter == -1) {
+ private URI getNamespaceFor(String jsonElementName) {
+ String[] moduleNameAndLocalName = jsonElementName.split(":");
+ if (moduleNameAndLocalName.length != 2) { // it is not "moduleName:localName"
return null;
}
- return URI.create(jsonElementName.substring(0, indexOfDelimeter));
+ return URI.create(moduleNameAndLocalName[0]);
}
- private String getLocalNameFrom(String jsonElementName) {
- int indexOfDelimeter = jsonElementName.lastIndexOf(':');
- if (indexOfDelimeter == -1) {
+ private String getLocalNameFor(String jsonElementName) {
+ String[] moduleNameAndLocalName = jsonElementName.split(":");
+ if (moduleNameAndLocalName.length != 2) { // it is not "moduleName:localName"
return jsonElementName;
}
- return jsonElementName.substring(indexOfDelimeter + 1, jsonElementName.length());
+ return moduleNameAndLocalName[1];
+ }
+
+ /**
+ * @param value
+ * value of json element
+ * @return if value is "moduleName:localName" then {@link IdentityValuesDTO} else
+ * the same string as parameter "value"
+ */
+ private Object resolveValueOfElement(String value) {
+ URI namespace = getNamespaceFor(value);
+ return namespace == null ? value : new IdentityValuesDTO(namespace.toString(), getLocalNameFor(value), null);
}
}
--- /dev/null
+package org.opendaylight.controller.sal.rest.impl;
+
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+
+public final class RestUtil {
+
+ public final static TypeDefinition<?> resolveBaseTypeFrom(TypeDefinition<?> type) {
+ TypeDefinition<?> superType = type;
+ while (superType.getBaseType() != null) {
+ superType = superType.getBaseType();
+ }
+ return superType;
+ }
+
+}
public class RestconfProvider implements BundleActivator, Provider, ServiceTrackerCustomizer<Broker, Broker> {
- public final static String NOT_INITALIZED_MSG = "Restcof is not initialized yet. Please try again later";
+ public final static String NOT_INITALIZED_MSG = "Restconf is not initialized yet. Please try again later";
private ListenerRegistration<SchemaServiceListener> listenerRegistration;
private ServiceTracker<Broker, Broker> brokerServiceTrancker;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
+import org.opendaylight.controller.sal.restconf.impl.IdentityValuesDTO;
+import org.opendaylight.controller.sal.restconf.impl.IdentityValuesDTO.IdentityValue;
+import org.opendaylight.controller.sal.restconf.impl.RestCodec;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.CompositeNode;
import org.opendaylight.yangtools.yang.data.api.Node;
Element itemEl = doc.createElementNS(dataType.getNamespace().toString(), dataType.getLocalName());
if (data instanceof SimpleNode<?>) {
if (schema instanceof LeafListSchemaNode) {
- writeValueOfNodeByType(itemEl, (SimpleNode<?>) data, ((LeafListSchemaNode) schema).getType());
+ writeValueOfNodeByType(itemEl, (SimpleNode<?>) data, ((LeafListSchemaNode) schema).getType(), (DataSchemaNode) schema);
} else if (schema instanceof LeafSchemaNode) {
- writeValueOfNodeByType(itemEl, (SimpleNode<?>) data, ((LeafSchemaNode) schema).getType());
+ writeValueOfNodeByType(itemEl, (SimpleNode<?>) data, ((LeafSchemaNode) schema).getType(), (DataSchemaNode) schema);
} else {
Object value = data.getValue();
if (value != null) {
return itemEl;
}
- private void writeValueOfNodeByType(Element element, SimpleNode<?> node, TypeDefinition<?> type) {
+ private void writeValueOfNodeByType(Element element, SimpleNode<?> node, TypeDefinition<?> type, DataSchemaNode schema) {
- TypeDefinition<?> baseType = resolveBaseTypeFrom(type);
+ TypeDefinition<?> baseType = RestUtil.resolveBaseTypeFrom(type);
- if (baseType instanceof IdentityrefTypeDefinition && node.getValue() instanceof QName) {
- QName value = (QName) node.getValue();
- element.setAttribute("xmlns:x", value.getNamespace().toString());
- element.setTextContent("x:" + value.getLocalName());
+ if (baseType instanceof IdentityrefTypeDefinition) {
+ if (node.getValue() instanceof QName) {
+ IdentityValuesDTO valueDTO = (IdentityValuesDTO) RestCodec.from(type).serialize(node.getValue());
+ IdentityValue value = valueDTO.getValuesWithNamespaces().get(0);
+ String prefix = "x";
+ if (value.getPrefix() != null && !value.getPrefix().isEmpty()) {
+ prefix = value.getPrefix();
+ }
+ element.setAttribute("xmlns:" + prefix, value.getNamespace());
+ element.setTextContent(prefix + ":" + value.getValue());
+ } else {
+ logger.debug("Value of " + baseType.getQName().getNamespace() + ":"
+ + baseType.getQName().getLocalName() + " is not instance of " + QName.class + " but is " + node.getValue().getClass());
+ element.setTextContent(String.valueOf(node.getValue()));
+ }
} else {
- Object value = node.getValue();
- if (value != null) {
- element.setTextContent(String.valueOf(value));
+ if (node.getValue() != null) {
+ String value = String.valueOf(RestCodec.from(baseType).serialize(node.getValue()));
+ if (value.equals("null")) {
+ value = String.valueOf(node.getValue());
+ }
+ element.setTextContent(value);
}
}
}
return null;
}
- private TypeDefinition<?> resolveBaseTypeFrom(TypeDefinition<?> type) {
- return type.getBaseType() != null ? resolveBaseTypeFrom(type.getBaseType()) : type;
- }
-
}
import javax.xml.stream.events.XMLEvent;
import org.opendaylight.controller.sal.restconf.impl.CompositeNodeWrapper;
+import org.opendaylight.controller.sal.restconf.impl.IdentityValuesDTO;
import org.opendaylight.controller.sal.restconf.impl.EmptyNodeWrapper;
import org.opendaylight.controller.sal.restconf.impl.NodeWrapper;
import org.opendaylight.controller.sal.restconf.impl.SimpleNodeWrapper;
return false;
}
+ private CompositeNodeWrapper resolveCompositeNodeFromStartElement(final StartElement startElement) {
+ checkArgument(startElement != null, "Start Element cannot be NULL!");
+ return new CompositeNodeWrapper(getNamespaceFor(startElement), getLocalNameFor(startElement));
+ }
+
private NodeWrapper<? extends Node<?>> resolveSimpleNodeFromStartElement(final StartElement startElement)
throws XMLStreamException {
checkArgument(startElement != null, "Start Element cannot be NULL!");
- String data = null;
+ String data = getValueOf(startElement);
+ if (data == null) {
+ return new EmptyNodeWrapper(getNamespaceFor(startElement), getLocalNameFor(startElement));
+ }
+ return new SimpleNodeWrapper(getNamespaceFor(startElement), getLocalNameFor(startElement),
+ resolveValueOfElement(data, startElement));
+ }
+ private String getValueOf(StartElement startElement) throws XMLStreamException {
+ String data = null;
if (eventReader.hasNext()) {
final XMLEvent innerEvent = eventReader.peek();
if (innerEvent.isCharacters()) {
}
}
}
- if(data == null) {
- return new EmptyNodeWrapper(getNamespaceFrom(startElement), getLocalNameFrom(startElement));
- }
- return new SimpleNodeWrapper(getNamespaceFrom(startElement), getLocalNameFrom(startElement), data);
+ return data;
}
- private CompositeNodeWrapper resolveCompositeNodeFromStartElement(final StartElement startElement) {
- checkArgument(startElement != null, "Start Element cannot be NULL!");
- return new CompositeNodeWrapper(getNamespaceFrom(startElement), getLocalNameFrom(startElement));
- }
-
- private String getLocalNameFrom(StartElement startElement) {
+ private String getLocalNameFor(StartElement startElement) {
return startElement.getName().getLocalPart();
}
- private URI getNamespaceFrom(StartElement startElement) {
+ private URI getNamespaceFor(StartElement startElement) {
String namespaceURI = startElement.getName().getNamespaceURI();
return namespaceURI.isEmpty() ? null : URI.create(namespaceURI);
}
+ /**
+ * @param value
+ * value of startElement
+ * @param startElement
+ * element containing value
+ * @return if value is "prefix:value" then {@link IdentityValuesDTO} else the same
+ * string as parameter "value"
+ */
+ private Object resolveValueOfElement(String value, StartElement startElement) {
+ String[] namespaceAndValue = value.split(":");
+ if (namespaceAndValue.length != 2) { // it is not "prefix:value"
+ return value;
+ }
+ String namespace = startElement.getNamespaceContext().getNamespaceURI(namespaceAndValue[0]);
+ if (namespace != null && !namespace.isEmpty()) {
+ return new IdentityValuesDTO(namespace, namespaceAndValue[1], namespaceAndValue[0]);
+ }
+ return value;
+ }
+
}
package org.opendaylight.controller.sal.restconf.impl
import com.google.common.collect.BiMap
+import com.google.common.collect.FluentIterable
import com.google.common.collect.HashBiMap
import java.net.URI
import java.net.URLDecoder
import java.util.concurrent.ConcurrentHashMap
import javax.ws.rs.core.Response
import org.opendaylight.controller.sal.core.api.model.SchemaServiceListener
+import org.opendaylight.controller.sal.rest.impl.RestUtil
import org.opendaylight.controller.sal.rest.impl.RestconfProvider
import org.opendaylight.yangtools.yang.common.QName
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument
+import org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec
import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode
import org.opendaylight.yangtools.yang.model.api.ChoiceNode
import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode
import org.opendaylight.yangtools.yang.model.api.ListSchemaNode
import org.opendaylight.yangtools.yang.model.api.RpcDefinition
import org.opendaylight.yangtools.yang.model.api.SchemaContext
-import org.opendaylight.yangtools.yang.model.api.SchemaNode
-import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition
-import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil
-
-import static com.google.common.base.Preconditions.*
-import org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec
import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition
import org.slf4j.LoggerFactory
-import com.google.common.collect.FluentIterable
+
+import static com.google.common.base.Preconditions.*
class ControllerContext implements SchemaServiceListener {
val static LOG = LoggerFactory.getLogger(ControllerContext)
return getLatestModule(startModule)
}
- private def getLatestModule(String moduleName) {
+ def getLatestModule(String moduleName) {
checkPreconditions
checkArgument(moduleName !== null && !moduleName.empty)
val modules = schemas.modules.filter[m|m.name == moduleName]
var module = uriToModuleName.get(namespace)
if (module === null) {
val moduleSchemas = schemas.findModuleByNamespace(namespace);
- if(moduleSchemas === null) throw new IllegalArgumentException()
+ if(moduleSchemas === null) return null
var latestModule = moduleSchemas.head
for (m : moduleSchemas) {
if (m.revision.after(latestModule.revision)) {
latestModule = m
}
}
- if(latestModule === null) throw new IllegalArgumentException()
+ if(latestModule === null) return null
uriToModuleName.put(namespace, latestModule.name)
module = latestModule.name;
}
return module
}
+ def findNamespaceByModule(String module) {
+ var namespace = moduleNameToUri.get(module)
+ if (namespace === null) {
+ val moduleSchemas = schemas.modules.filter[it|it.name.equals(module)]
+ var latestModule = moduleSchemas.head
+ for (m : moduleSchemas) {
+ if (m.revision.after(latestModule.revision)) {
+ latestModule = m
+ }
+ }
+ if(latestModule === null) return null
+ namespace = latestModule.namespace
+ uriToModuleName.put(namespace, latestModule.name)
+ }
+ return namespace
+ }
+
def CharSequence toRestconfIdentifier(QName qname) {
checkPreconditions
var module = uriToModuleName.get(qname.namespace)
val typedef = (node as LeafSchemaNode).type;
var decoded = TypeDefinitionAwareCodec.from(typedef)?.deserialize(urlDecoded)
- if(decoded == null) {
- var baseType = typedef
- while (baseType.baseType != null) {
- baseType = baseType.baseType;
- }
+ if(decoded === null) {
+ var baseType = RestUtil.resolveBaseTypeFrom(typedef)
if(baseType instanceof IdentityrefTypeDefinition) {
decoded = toQName(urlDecoded)
}
}
}
- /**
- * Resolve target type from leafref type.
- *
- * According to RFC 6020 referenced element has to be leaf (chapter 9.9).
- * Therefore if other element is referenced then null value is returned.
- *
- * Currently only cases without path-predicate are supported.
- *
- * @param leafRef
- * @param schemaNode
- * data schema node which contains reference
- * @return type if leaf is referenced and it is possible to find referenced
- * node in schema context. In other cases null value is returned
- */
- def LeafSchemaNode resolveTypeFromLeafref(LeafrefTypeDefinition leafRef, DataSchemaNode schemaNode) {
- val xPath = leafRef.getPathStatement();
- val module = SchemaContextUtil.findParentModule(schemas, schemaNode);
-
- var SchemaNode foundSchemaNode
- if (xPath.isAbsolute()) {
- foundSchemaNode = SchemaContextUtil.findDataSchemaNode(schemas, module, xPath);
- } else {
- foundSchemaNode = SchemaContextUtil.findDataSchemaNodeForRelativeXPath(schemas, module, schemaNode, xPath);
- }
-
- if (foundSchemaNode instanceof LeafSchemaNode) {
- return foundSchemaNode as LeafSchemaNode;
- }
-
- return null;
- }
}
--- /dev/null
+package org.opendaylight.controller.sal.restconf.impl;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public final class IdentityValuesDTO {
+
+ private final List<IdentityValue> elementData = new ArrayList<>();
+
+ public IdentityValuesDTO(String namespace, String value, String prefix) {
+ elementData.add(new IdentityValue(namespace, value, prefix));
+ }
+
+ public void add(String namespace, String value, String prefix) {
+ elementData.add(new IdentityValue(namespace, value, prefix));
+ }
+
+ public List<IdentityValue> getValuesWithNamespaces() {
+ return Collections.unmodifiableList(elementData);
+ }
+
+ public static final class IdentityValue {
+
+ private String namespace;
+ private String value;
+ private String prefix;
+
+ public IdentityValue(String namespace, String value, String prefix) {
+ this.namespace = namespace;
+ this.value = value;
+ this.prefix = prefix;
+ }
+
+ public String getNamespace() {
+ return namespace;
+ }
+
+ public void setNamespace(String namespace) {
+ this.namespace = namespace;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+ public String getPrefix() {
+ return prefix;
+ }
+
+ public void setPrefix(String prefix) {
+ this.prefix = prefix;
+ }
+
+ }
+}
--- /dev/null
+package org.opendaylight.controller.sal.restconf.impl;
+
+import java.net.URI;
+
+import org.opendaylight.controller.sal.rest.impl.RestUtil;
+import org.opendaylight.controller.sal.restconf.impl.IdentityValuesDTO.IdentityValue;
+import org.opendaylight.yangtools.concepts.Codec;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.codec.IdentityrefCodec;
+import org.opendaylight.yangtools.yang.data.api.codec.LeafrefCodec;
+import org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class RestCodec {
+
+ private RestCodec() {
+ }
+
+ public static final Codec<Object, Object> from(TypeDefinition<?> typeDefinition) {
+ return new ObjectCodec(typeDefinition);
+ }
+
+ @SuppressWarnings("rawtypes")
+ public static final class ObjectCodec implements Codec<Object, Object> {
+
+ private final Logger logger = LoggerFactory.getLogger(RestCodec.class);
+
+ public static final Codec IDENTITYREF_DEFAULT_CODEC = new IdentityrefCodecImpl();
+ public static final Codec LEAFREF_DEFAULT_CODEC = new LeafrefCodecImpl();
+
+ private TypeDefinition<?> type;
+
+ private ObjectCodec(TypeDefinition<?> typeDefinition) {
+ type = RestUtil.resolveBaseTypeFrom(typeDefinition);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Object deserialize(Object input) {
+ try {
+ if (type instanceof IdentityrefTypeDefinition) {
+ return IDENTITYREF_DEFAULT_CODEC.deserialize(input);
+ } else if (type instanceof LeafrefTypeDefinition) {
+ return LEAFREF_DEFAULT_CODEC.deserialize(input);
+ } else {
+ TypeDefinitionAwareCodec<Object,? extends TypeDefinition<?>> typeAwarecodec = TypeDefinitionAwareCodec.from(type);
+ if (typeAwarecodec != null) {
+ return typeAwarecodec.deserialize(String.valueOf(input));
+ } else {
+ logger.debug("Codec for type \"" + type.getQName().getLocalName() + "\" is not implemented yet.");
+ return null;
+ }
+ }
+ } catch (ClassCastException e) { // TODO remove this catch when everyone use codecs
+ logger.error("ClassCastException was thrown when codec is invoked with parameter " + String.valueOf(input), e);
+ return input;
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Object serialize(Object input) {
+ try {
+ if (type instanceof IdentityrefTypeDefinition) {
+ return IDENTITYREF_DEFAULT_CODEC.serialize(input);
+ } else if (type instanceof LeafrefTypeDefinition) {
+ return LEAFREF_DEFAULT_CODEC.serialize(input);
+ } else {
+ TypeDefinitionAwareCodec<Object,? extends TypeDefinition<?>> typeAwarecodec = TypeDefinitionAwareCodec.from(type);
+ if (typeAwarecodec != null) {
+ return typeAwarecodec.serialize(input);
+ } else {
+ logger.debug("Codec for type \"" + type.getQName().getLocalName() + "\" is not implemented yet.");
+ return null;
+ }
+ }
+ } catch (ClassCastException e) { // TODO remove this catch when everyone use codecs
+ logger.error("ClassCastException was thrown when codec is invoked with parameter " + String.valueOf(input), e);
+ return input;
+ }
+ }
+
+ }
+
+ public static class IdentityrefCodecImpl implements IdentityrefCodec<IdentityValuesDTO> {
+
+ @Override
+ public IdentityValuesDTO serialize(QName data) {
+ return new IdentityValuesDTO(data.getNamespace().toString(), data.getLocalName(), data.getPrefix());
+ }
+
+ @Override
+ public QName deserialize(IdentityValuesDTO data) {
+ IdentityValue valueWithNamespace = data.getValuesWithNamespaces().get(0);
+ String namespace = valueWithNamespace.getNamespace();
+ URI validNamespace = ControllerContext.getInstance().findNamespaceByModule(namespace);
+ if (validNamespace == null) {
+ validNamespace = URI.create(namespace);
+ }
+ return QName.create(validNamespace, null, valueWithNamespace.getValue());
+ }
+
+ }
+
+ public static class LeafrefCodecImpl implements LeafrefCodec<String> {
+
+ @Override
+ public String serialize(Object data) {
+ return String.valueOf(data);
+ }
+
+ @Override
+ public Object deserialize(String data) {
+ return data;
+ }
+
+ }
+
+}
import javax.ws.rs.core.Response
import org.opendaylight.controller.md.sal.common.api.TransactionStatus
import org.opendaylight.controller.sal.rest.api.RestconfService
+import org.opendaylight.yangtools.yang.common.QName
import org.opendaylight.yangtools.yang.data.api.CompositeNode
import org.opendaylight.yangtools.yang.data.api.Node
import org.opendaylight.yangtools.yang.data.impl.NodeFactory
import org.opendaylight.yangtools.yang.model.api.ChoiceNode
+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.data.impl.codec.TypeDefinitionAwareCodec
-import org.opendaylight.yangtools.yang.model.api.TypeDefinition
-import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode
import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode
-import org.opendaylight.yangtools.yang.common.QName
-import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode
+import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode
+import org.opendaylight.yangtools.yang.model.api.ListSchemaNode
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition
+import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition
+
import static javax.ws.rs.core.Response.Status.*
class RestconfImpl implements RestconfService {
}
val moduleName = controllerContext.findModuleByNamespace(validQName.namespace);
if (nodeBuilder.namespace === null || nodeBuilder.namespace == validQName.namespace ||
- nodeBuilder.namespace.path == moduleName) {
+ nodeBuilder.namespace.toString == moduleName) {
nodeBuilder.qname = validQName
} else {
throw new ResponseException(BAD_REQUEST,
findFirstSchemaByLocalName(child.localName, (schema as DataNodeContainer).childNodes),
currentAugment)
}
+ if(schema instanceof ListSchemaNode) {
+ val listKeys = (schema as ListSchemaNode).keyDefinition
+ for (listKey : listKeys) {
+ var foundKey = false
+ for (child : children) {
+ if (child.unwrap.nodeType.localName == listKey.localName) {
+ foundKey = true;
+ }
+ }
+ if (!foundKey) {
+ throw new ResponseException(BAD_REQUEST,
+ "Missing key \"" + listKey.localName + "\" of list \"" + schema.QName.localName + "\"")
+ }
+ }
+ }
} else if (nodeBuilder instanceof SimpleNodeWrapper) {
val simpleNode = (nodeBuilder as SimpleNodeWrapper)
- val stringValue = simpleNode.value as String;
-
- val objectValue = TypeDefinitionAwareCodec.from(schema.typeDefinition)?.deserialize(stringValue);
- simpleNode.setValue(objectValue)
+ val value = simpleNode.value
+ var inputValue = value;
+
+ if (schema.typeDefinition instanceof IdentityrefTypeDefinition) {
+ if (value instanceof String) {
+ inputValue = new IdentityValuesDTO(validQName.namespace.toString, value as String, null)
+ } // else value is instance of ValuesDTO
+ }
+
+ val outputValue = RestCodec.from(schema.typeDefinition)?.deserialize(inputValue);
+ simpleNode.setValue(outputValue)
} else if (nodeBuilder instanceof EmptyNodeWrapper) {
val emptyNodeBuilder = nodeBuilder as EmptyNodeWrapper
if (schema instanceof LeafSchemaNode) {
}
private def dispatch TypeDefinition<?> typeDefinition(LeafSchemaNode node) {
- node.type
+ var baseType = node.type
+ while (baseType.baseType !== null) {
+ baseType = baseType.baseType;
+ }
+ baseType
}
private def dispatch TypeDefinition<?> typeDefinition(LeafListSchemaNode node) {
- node.type
+ var TypeDefinition<?> baseType = node.type
+ while (baseType.baseType !== null) {
+ baseType = baseType.baseType;
+ }
+ baseType
}
private def DataSchemaNode findFirstSchemaByLocalName(String localName, Set<DataSchemaNode> schemas) {
public final class SimpleNodeWrapper implements NodeWrapper<SimpleNode<?>>, SimpleNode<Object> {
- private SimpleNode<?> simpleNode;
+ private SimpleNode<Object> simpleNode;
private String localName;
private Object value;
this.value = value;
}
- public SimpleNodeWrapper(URI namespace, String localName, String value) {
+ public SimpleNodeWrapper(URI namespace, String localName, Object value) {
this(localName, value);
this.namespace = namespace;
}
--- /dev/null
+package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.test;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.math.BigDecimal;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.*;
+
+import javax.ws.rs.WebApplicationException;
+import javax.xml.bind.DatatypeConverter;
+
+import org.junit.Test;
+import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.*;
+import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
+
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonToken;
+
+public class ToJsonBasicDataTypesTest {
+
+ @Test
+ public void simpleYangDataTest() {
+ String jsonOutput = "";
+ CompositeNode compositeNode = TestUtils.loadCompositeNode("/cnsn-to-json/simple-data-types/xml/data.xml");
+
+ Set<Module> modules = TestUtils.resolveModules("/cnsn-to-json/simple-data-types");
+ assertEquals(1, modules.size());
+ Module module = TestUtils.resolveModule(null, modules);
+ assertNotNull(module);
+ DataSchemaNode dataSchemaNode = TestUtils.resolveDataSchemaNode(module, null);
+ assertNotNull(dataSchemaNode);
+
+ TestUtils.normalizeCompositeNode(compositeNode, modules, dataSchemaNode, "simple-data-types:cont");
+
+ try {
+ jsonOutput = TestUtils.writeCompNodeWithSchemaContextToJson(compositeNode, modules, dataSchemaNode);
+ } catch (WebApplicationException | IOException e) {
+ assertTrue(false); // shouldn't get here
+ }
+
+ System.out.println(jsonOutput);
+ verifyJsonOutput(jsonOutput);
+ }
+
+ private CompositeNode prepareData() {
+ MutableCompositeNode cont = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont"), null, null,
+ ModifyAction.CREATE, null);
+
+ List<Node<?>> childNodes = new ArrayList<>();
+ childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnint8Min"), cont, (byte) -128,
+ ModifyAction.CREATE, null));
+ childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnint8Max"), cont, (byte) 127,
+ ModifyAction.CREATE, null));
+ childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnint16Min"), cont, (short) -32768,
+ ModifyAction.CREATE, null));
+ childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnint16Max"), cont, (short) 32767,
+ ModifyAction.CREATE, null));
+ childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnint32Min"), cont,
+ (int) -2147483648, ModifyAction.CREATE, null));
+ childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnint32Max"), cont, (int) 2147483647,
+ ModifyAction.CREATE, null));
+ childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnint64Min"), cont, new Long(
+ "-9223372036854775807"), ModifyAction.CREATE, null));
+ childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnint64Max"), cont, new Long(
+ "9223372036854775807"), ModifyAction.CREATE, null));
+ childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnuint8Max"), cont, (short) 255,
+ ModifyAction.CREATE, null));
+ childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnuint16Max"), cont, (int) 65535,
+ ModifyAction.CREATE, null));
+ childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnuint32Max"), cont, new Long(
+ "4294967295"), ModifyAction.CREATE, null));
+ childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfstr"), cont, "lfstr",
+ ModifyAction.CREATE, null));
+ childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfstr1"), cont, "",
+ ModifyAction.CREATE, null));
+ childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfbool1"), cont, Boolean.TRUE,
+ ModifyAction.CREATE, null));
+ childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfbool2"), cont, Boolean.FALSE,
+ ModifyAction.CREATE, null));
+ childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfdecimal1"), cont, new BigDecimal(
+ "43.32"), ModifyAction.CREATE, null));
+ childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfdecimal2"), cont, new BigDecimal(
+ "-0.43"), ModifyAction.CREATE, null));
+ childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfdecimal3"), cont, new BigDecimal(
+ "43"), ModifyAction.CREATE, null));
+ childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfdecimal4"), cont, new BigDecimal(
+ "43E3"), ModifyAction.CREATE, null));
+ childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfdecimal6"), cont, new BigDecimal(
+ "33.12345"), ModifyAction.CREATE, null));
+ childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfenum"), cont, "enum3",
+ ModifyAction.CREATE, null));
+
+ HashSet<String> bits = new HashSet<String>();
+ bits.add("bit3");
+ childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfbits"), cont, bits,
+ ModifyAction.CREATE, null));
+
+ childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfbinary"), cont, DatatypeConverter
+ .parseBase64Binary("AAaacdabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"),
+ ModifyAction.CREATE, null));
+ childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfempty"), cont, null,
+ ModifyAction.CREATE, null));
+ childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion1"), cont, (int) 324,
+ ModifyAction.CREATE, null));
+ childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion2"), cont, new BigDecimal(
+ "33.3"), ModifyAction.CREATE, null));
+ childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion3"), cont, "55",
+ ModifyAction.CREATE, null));
+ childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion4"), cont, Boolean.TRUE,
+ ModifyAction.CREATE, null));
+ childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion5"), cont, "true",
+ ModifyAction.CREATE, null));
+ childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion6"), cont, "false",
+ ModifyAction.CREATE, null));
+ childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion7"), cont, null,
+ ModifyAction.CREATE, null));
+ childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion8"), cont, "",
+ ModifyAction.CREATE, null));
+ childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion9"), cont, "",
+ ModifyAction.CREATE, null));
+
+ HashSet<String> bits2 = new HashSet<String>();
+ bits2.add("bt1");
+ childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion10"), cont, bits2,
+ ModifyAction.CREATE, null));
+
+ childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion11"), cont, (short) 33,
+ ModifyAction.CREATE, null));
+ childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion12"), cont, Boolean.FALSE,
+ ModifyAction.CREATE, null));
+ try {
+ childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("identityref1"), cont, new QName(
+ new URI("simple:data:types"), "iden"), ModifyAction.CREATE, null));
+ } catch (URISyntaxException e) {
+ }
+
+ cont.getChildren().addAll(childNodes);
+
+ cont.init();
+
+ return cont;
+ }
+
+ private void verifyJsonOutput(String jsonOutput) {
+ StringReader strReader = new StringReader(jsonOutput);
+ JsonReader jReader = new JsonReader(strReader);
+
+ String exception = null;
+ try {
+ jsonReadCont(jReader);
+ } catch (IOException e) {
+ exception = e.getMessage();
+ }
+
+ assertNull("Error during reading Json output: " + exception, exception);
+ }
+
+ private void jsonReadCont(JsonReader jReader) throws IOException {
+ jReader.beginObject();
+ assertNotNull("cont1 is missing.", jReader.hasNext());
+
+ // Cont dataFromJson = new Cont(jReader.nextName());
+ jReader.nextName();
+ jsonReadContElements(jReader);
+
+ assertFalse("cont shouldn't have other element.", jReader.hasNext());
+ jReader.endObject();
+ // return dataFromJson;
+ }
+
+ private void jsonReadContElements(JsonReader jReader) throws IOException {
+ jReader.beginObject();
+ List<String> loadedLfs = new ArrayList<>();
+ boolean exceptForDecimal5Raised = false;
+ boolean enumChecked = false;
+ boolean bitsChecked = false;
+ boolean lfdecimal6Checked = false;
+ boolean lfdecimal4Checked = false;
+ boolean lfdecimal3Checked = false;
+ boolean lfdecimal2Checked = false;
+ boolean lfdecimal1Checked = false;
+ boolean lfbool1Checked = false;
+ boolean lfbool2Checked = false;
+ boolean lfstrChecked = false;
+ boolean lfbinaryChecked = false;
+ // boolean lfref1Checked = false;
+ boolean lfemptyChecked = false;
+ boolean lfstr1Checked = false;
+ boolean lfidentityrefChecked = false;
+
+ while (jReader.hasNext()) {
+ String keyName = jReader.nextName();
+ JsonToken peek = null;
+ try {
+ peek = jReader.peek();
+ } catch (IOException e) {
+ if (keyName.equals("lfdecimal5")) {
+ exceptForDecimal5Raised = true;
+ } else {
+ assertTrue("Key " + keyName + " has incorrect value for specifed type", false);
+ }
+ }
+
+ if (keyName.startsWith("lfnint") || keyName.startsWith("lfnuint")) {
+ assertEquals("Key " + keyName + " has incorrect type", JsonToken.NUMBER, peek);
+ try {
+ jReader.nextLong();
+ } catch (NumberFormatException e) {
+ assertTrue("Key " + keyName + " has incorrect value - " + e.getMessage(), false);
+ }
+ loadedLfs.add(keyName.substring(3));
+ } else if (keyName.equals("identityref1")) {
+ assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
+ assertEquals("simple-data-types:iden", jReader.nextString());
+ lfidentityrefChecked = true;
+ } else if (keyName.equals("lfstr")) {
+ assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
+ assertEquals("lfstr", jReader.nextString());
+ lfstrChecked = true;
+ } else if (keyName.equals("lfstr1")) {
+ assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
+ assertEquals("", jReader.nextString());
+ lfstr1Checked = true;
+ } else if (keyName.equals("lfbool1")) {
+ assertEquals("Key " + keyName + " has incorrect type", JsonToken.BOOLEAN, peek);
+ assertEquals(true, jReader.nextBoolean());
+ lfbool1Checked = true;
+ } else if (keyName.equals("lfbool2")) {
+ assertEquals("Key " + keyName + " has incorrect type", JsonToken.BOOLEAN, peek);
+ assertEquals(false, jReader.nextBoolean());
+ lfbool2Checked = true;
+ } else if (keyName.equals("lfbool3")) {
+ assertEquals("Key " + keyName + " has incorrect type", JsonToken.BOOLEAN, peek);
+ assertEquals(false, jReader.nextBoolean());
+ } else if (keyName.equals("lfdecimal1")) {
+ assertEquals("Key " + keyName + " has incorrect type", JsonToken.NUMBER, peek);
+ assertEquals(new Double(43.32), (Double) jReader.nextDouble());
+ lfdecimal1Checked = true;
+ } else if (keyName.equals("lfdecimal2")) {
+ assertEquals("Key " + keyName + " has incorrect type", JsonToken.NUMBER, peek);
+ assertEquals(new Double(-0.43), (Double) jReader.nextDouble());
+ lfdecimal2Checked = true;
+ } else if (keyName.equals("lfdecimal3")) {
+ assertEquals("Key " + keyName + " has incorrect type", JsonToken.NUMBER, peek);
+ assertEquals(new Double(43), (Double) jReader.nextDouble());
+ lfdecimal3Checked = true;
+ } else if (keyName.equals("lfdecimal4")) {
+ assertEquals("Key " + keyName + " has incorrect type", JsonToken.NUMBER, peek);
+ assertEquals(new Double(43E3), (Double) jReader.nextDouble());
+ lfdecimal4Checked = true;
+ } else if (keyName.equals("lfdecimal6")) {
+ assertEquals("Key " + keyName + " has incorrect type", JsonToken.NUMBER, peek);
+ assertEquals(new Double(33.12345), (Double) jReader.nextDouble());
+ lfdecimal6Checked = true;
+ } else if (keyName.equals("lfenum")) {
+ assertEquals("enum3", jReader.nextString());
+ enumChecked = true;
+ } else if (keyName.equals("lfbits")) {
+ assertEquals("bit3 bit2", jReader.nextString());
+ bitsChecked = true;
+ } else if (keyName.equals("lfbinary")) {
+ assertEquals("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", jReader.nextString());
+ lfbinaryChecked = true;
+ } else if (keyName.equals("lfempty")) {
+ jReader.beginArray();
+ jReader.nextNull();
+ jReader.endArray();
+ lfemptyChecked = true;
+ } else if (keyName.startsWith("lfunion")) {
+ checkLfUnion(jReader, keyName, peek);
+ } else {
+ assertTrue("Key " + keyName + " doesn't exists in yang file.", false);
+ }
+
+ }
+ Collections.sort(loadedLfs);
+ String expectedLfsStr = "[int16Max, int16Min, int32Max, int32Min, int64Max, int64Min, int8Max, int8Min, uint16Max, uint32Max, uint8Max]";
+ String actualLfsStr = loadedLfs.toString();
+ assertEquals("Some leaves are missing", expectedLfsStr, actualLfsStr);
+ assertTrue("Enum wasn't checked", enumChecked);
+ assertTrue("Bits wasn't checked", bitsChecked);
+ assertTrue("Decimal1 wasn't checked", lfdecimal1Checked);
+ assertTrue("Decimal2 wasn't checked", lfdecimal2Checked);
+ assertTrue("Decimal3 wasn't checked", lfdecimal3Checked);
+ assertTrue("Decimal4 wasn't checked", lfdecimal4Checked);
+ assertTrue("Decimal5 wasn't checked", lfdecimal6Checked);
+ assertTrue("lfbool1 wasn't checked", lfbool1Checked);
+ assertTrue("lfbool2 wasn't checked", lfbool2Checked);
+ assertTrue("lfstr wasn't checked", lfstrChecked);
+ assertTrue("lfstr1 wasn't checked", lfstr1Checked);
+ assertTrue("lfbinary wasn't checked", lfbinaryChecked);
+ assertTrue("lfempty wasn't checked", lfemptyChecked);
+ assertTrue("lfidentityref wasn't checked", lfidentityrefChecked);
+ jReader.endObject();
+ }
+
+ private void checkLfUnion(JsonReader jReader, String keyName, JsonToken peek) throws IOException {
+ if (keyName.equals("lfunion1")) {
+ assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
+ assertEquals("324", jReader.nextString());
+ } else if (keyName.equals("lfunion2")) {
+ assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
+ assertEquals("33.3", jReader.nextString());
+ } else if (keyName.equals("lfunion3")) {
+ assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
+ assertEquals("55", jReader.nextString());
+ } else if (keyName.equals("lfunion4")) {
+ assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
+ assertEquals("true", jReader.nextString());
+ } else if (keyName.equals("lfunion5")) {
+ assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
+ assertEquals("true", jReader.nextString());
+ } else if (keyName.equals("lfunion6")) {
+ assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
+ assertEquals("false", jReader.nextString());
+ } else if (keyName.equals("lfunion7")) {
+ assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
+ assertEquals("", jReader.nextString());
+ } else if (keyName.equals("lfunion8")) {
+ assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
+ assertEquals("", jReader.nextString());
+ } else if (keyName.equals("lfunion9")) {
+ assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
+ assertEquals("", jReader.nextString());
+ } else if (keyName.equals("lfunion10")) {
+ assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
+ assertEquals("bt1", jReader.nextString());
+ } else if (keyName.equals("lfunion11")) {
+ assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
+ assertEquals("33", jReader.nextString());
+ } else if (keyName.equals("lfunion12")) {
+ assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
+ assertEquals("false", jReader.nextString());
+ } else if (keyName.equals("lfunion13")) {
+ assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
+ assertEquals("44", jReader.nextString());
+ } else if (keyName.equals("lfunion14")) {
+ assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
+ assertEquals("21", jReader.nextString());
+ }
+ }
+}
-package org.opendaylight.controller.sal.restconf.impl.test;
+package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.test;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.*;
-import java.io.*;
-import java.util.*;
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.Map;
+import java.util.Set;
import org.junit.Test;
+import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
import org.opendaylight.controller.sal.restconf.impl.test.structures.*;
import org.opendaylight.yangtools.yang.data.api.*;
import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
-import com.google.gson.stream.*;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonToken;
public class ToJsonBasicYangTypesTest {
@Test
public void compositeNodeAndYangWithJsonReaderEmptyDataTest() {
String jsonOutput = TestUtils.convertCompositeNodeDataAndYangToJson(prepareCompositeNodeWithEmpties(),
- "/yang-to-json-conversion/simple-yang-types", "/yang-to-json-conversion/simple-yang-types/xml");
+ "/cnsn-to-json/simple-yang-types", "/cnsn-to-json/simple-yang-types/xml", "simple-yang-types", "cont1");
verifyJsonOutputForEmpty(jsonOutput);
}
@Test
public void xmlAndYangTypesWithJsonReaderTest() {
String jsonOutput = TestUtils.convertCompositeNodeDataAndYangToJson(
- TestUtils.loadCompositeNode("/yang-to-json-conversion/simple-yang-types/xml/data.xml"),
- "/yang-to-json-conversion/simple-yang-types", "/yang-to-json-conversion/simple-yang-types/xml");
+ TestUtils.loadCompositeNode("/cnsn-to-json/simple-yang-types/xml/data.xml"),
+ "/cnsn-to-json/simple-yang-types", "/cnsn-to-json/simple-yang-types/xml", "simple-yang-types", "cont1");
verifyJsonOutput(jsonOutput);
}
return lstItem;
}
- private String nextValue(JsonReader jReader) throws IOException {
+ private Object nextValue(JsonReader jReader) throws IOException {
if (jReader.peek().equals(JsonToken.NULL)) {
jReader.nextNull();
return null;
+ } else if (jReader.peek().equals(JsonToken.NUMBER)) {
+ return jReader.nextInt();
} else {
return jReader.nextString();
}
LstItem lst11_2 = null;
LstItem lst11_3 = null;
for (LstItem lstItem : lstItems) {
- if (lstItem.getLfs().get("lf111").getValue().equals("1")) {
+ if (lstItem.getLfs().get("lf111").getValue().equals(1)) {
lst11_1 = lstItem;
- } else if (lstItem.getLfs().get("lf111").getValue().equals("2")) {
+ } else if (lstItem.getLfs().get("lf111").getValue().equals(2)) {
lst11_2 = lstItem;
- } else if (lstItem.getLfs().get("lf111").getValue().equals("3")) {
+ } else if (lstItem.getLfs().get("lf111").getValue().equals(3)) {
lst11_3 = lstItem;
}
}
assertEquals(1, lst11_1.getLfs().size());
assertEquals(1, lst11_1.getConts().size());
assertEquals(1, lst11_1.getLsts().size());
- assertEquals(lst11_1.getLsts().get("lst111"), new Lst("lst111").addLstItem(new LstItem().addLf("lf1111", "35"))
- .addLstItem(new LstItem().addLf("lf1111", "34")).addLstItem(new LstItem()).addLstItem(new LstItem()));
+ assertEquals(
+ lst11_1.getLsts().get("lst111"),
+ new Lst("lst111").addLstItem(new LstItem().addLf("lf1111", (int) 35))
+ .addLstItem(new LstItem().addLf("lf1111", (int) 34)).addLstItem(new LstItem())
+ .addLstItem(new LstItem()));
assertEquals(lst11_1.getConts().get("cont111"), new Cont("cont111"));
// : lst11_1
assertEquals(1, lst11_2_cont111.getLsts().size());
assertTrue(lst11_2_cont111.getConts().isEmpty());
- assertEquals(new LfLst("lflst1111").addLf("1024").addLf("4096"), lst11_2_cont111.getLfLsts().get("lflst1111"));
+ assertEquals(new LfLst("lflst1111").addLf((int) 1024).addLf((int) 4096),
+ lst11_2_cont111.getLfLsts().get("lflst1111"));
assertEquals(
- new Lst("lst1111").addLstItem(new LstItem().addLf("lf1111B", "4")).addLstItem(
+ new Lst("lst1111").addLstItem(new LstItem().addLf("lf1111B", (int) 4)).addLstItem(
new LstItem().addLf("lf1111A", "lf1111A str12")), lst11_2_cont111.getLsts().get("lst1111"));
// :-cont111
assertEquals(lst11_2.getLsts().get("lst112"), new Lst("lst112").addLstItem(new LstItem()));
assertNotNull(lflst12);
assertEquals(3, lflst11.getLfs().size());
- assertTrue(lflst11.getLfs().contains(new Lf("55")));
- assertTrue(lflst11.getLfs().contains(new Lf("56")));
- assertTrue(lflst11.getLfs().contains(new Lf("57")));
+ assertTrue(lflst11.getLfs().contains(new Lf(55)));
+ assertTrue(lflst11.getLfs().contains(new Lf(56)));
+ assertTrue(lflst11.getLfs().contains(new Lf(57)));
assertEquals(3, lflst12.getLfs().size());
assertTrue(lflst12.getLfs().contains(new Lf("lflst12 str1")));
LstItem lst11_2 = null;
for (LstItem lstItem : lst11.getLstItems()) {
Lf lf = lstItem.getLfs().get("lf111");
- if (lf != null && lf.getValue().equals("140")) {
+ if (lf != null && lf.getValue().equals(140)) {
lst11_1 = lstItem;
- } else if (lf != null && lf.getValue().equals("141")) {
+ } else if (lf != null && lf.getValue().equals(141)) {
lst11_2 = lstItem;
}
}
// cont111 check
assertEquals(new Lf("lf1111", "lf1111 str2"), lst11_2_cont.getLfs().get("lf1111"));
- assertEquals(new LfLst("lflst1111").addLf(new Lf("2049")).addLf(new Lf("1025")).addLf(new Lf("4097")),
- lst11_2_cont.getLfLsts().get("lflst1111"));
+ assertEquals(new LfLst("lflst1111").addLf(new Lf(2049)).addLf(new Lf(1025)).addLf(new Lf(4097)), lst11_2_cont
+ .getLfLsts().get("lflst1111"));
assertNotNull(lst11_2_cont.getLsts().get("lst1111"));
checkLst1111(lst11_2_cont.getLsts().get("lst1111").getLstItems(), new Lf("lf1111A", "lf1111A str21"), new Lf(
- "lf1111B", "5"), new Lf("lf1111A", "lf1111A str22"), new Lf("lf1111B", "8"));
+ "lf1111B", 5), new Lf("lf1111A", "lf1111A str22"), new Lf("lf1111B", 8));
- checkLst11x(lst11_2.getLsts().get("lst111"), new LstItem().addLf(new Lf("lf1111", "55")),
- new LstItem().addLf(new Lf("lf1111", "56")));
+ checkLst11x(lst11_2.getLsts().get("lst111"), new LstItem().addLf(new Lf("lf1111", 55)),
+ new LstItem().addLf(new Lf("lf1111", 56)));
checkLst11x(lst11_2.getLsts().get("lst112"), new LstItem().addLf(new Lf("lf1121", "lf1121 str22")),
new LstItem().addLf(new Lf("lf1121", "lf1121 str21")));
}
// cont111 check
assertEquals(new Lf("lf1111", "lf1111 str"), lst11_1_cont.getLfs().get("lf1111"));
- assertEquals(new LfLst("lflst1111").addLf(new Lf("2048")).addLf(new Lf("1024")).addLf(new Lf("4096")),
- lst11_1_cont.getLfLsts().get("lflst1111"));
+ assertEquals(new LfLst("lflst1111").addLf(new Lf(2048)).addLf(new Lf(1024)).addLf(new Lf(4096)), lst11_1_cont
+ .getLfLsts().get("lflst1111"));
assertNotNull(lst11_1_cont.getLsts().get("lst1111"));
checkLst1111(lst11_1_cont.getLsts().get("lst1111").getLstItems(), new Lf("lf1111A", "lf1111A str11"), new Lf(
- "lf1111B", "4"), new Lf("lf1111A", "lf1111A str12"), new Lf("lf1111B", "7"));
+ "lf1111B", 4), new Lf("lf1111A", "lf1111A str12"), new Lf("lf1111B", 7));
- checkLst11x(lst11_1.getLsts().get("lst111"), new LstItem().addLf(new Lf("lf1111", "65")));
+ checkLst11x(lst11_1.getLsts().get("lst111"), new LstItem().addLf(new Lf("lf1111", 65)));
checkLst11x(lst11_1.getLsts().get("lst112"), new LstItem().addLf(new Lf("lf1121", "lf1121 str11")));
}
null, ModifyAction.CREATE, null);
cont1.getChildren().add(lst11_1);
- MutableSimpleNode<?> lf111_1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf111"), lst11_1, "1",
- ModifyAction.CREATE, null);
+ MutableSimpleNode<?> lf111_1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf111"), lst11_1,
+ (short) 1, ModifyAction.CREATE, null);
lst11_1.getChildren().add(lf111_1);
// lst111_1_1
lst11_1, null, ModifyAction.CREATE, null);
lst11_1.getChildren().add(lst111_1_1);
MutableSimpleNode<?> lf1111_1_1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1111"),
- lst111_1_1, "34", ModifyAction.CREATE, null);
+ lst111_1_1, (int) 34, ModifyAction.CREATE, null);
lst111_1_1.getChildren().add(lf1111_1_1);
lst111_1_1.init();
// :lst111_1_1
lst11_1, null, ModifyAction.CREATE, null);
lst11_1.getChildren().add(lst111_1_2);
MutableSimpleNode<?> lf1111_1_2 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1111"),
- lst111_1_2, "35", ModifyAction.CREATE, null);
+ lst111_1_2, (int) 35, ModifyAction.CREATE, null);
lst111_1_2.getChildren().add(lf1111_1_2);
lst111_1_2.init();
// :lst111_1_2
null, ModifyAction.CREATE, null);
cont1.getChildren().add(lst11_2);
- MutableSimpleNode<?> lf111_2 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf111"), lst11_2, "2",
- ModifyAction.CREATE, null);
+ MutableSimpleNode<?> lf111_2 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf111"), lst11_2,
+ (short) 2, ModifyAction.CREATE, null);
lst11_2.getChildren().add(lf111_2);
// cont111_2
lst11_2.getChildren().add(cont111_2);
MutableSimpleNode<?> lflst1111_2_2 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lflst1111"),
- cont111_2, "1024", ModifyAction.CREATE, null);
+ cont111_2, (int) 1024, ModifyAction.CREATE, null);
cont111_2.getChildren().add(lflst1111_2_2);
MutableSimpleNode<?> lflst1111_2_3 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lflst1111"),
- cont111_2, "4096", ModifyAction.CREATE, null);
+ cont111_2, (int) 4096, ModifyAction.CREATE, null);
cont111_2.getChildren().add(lflst1111_2_3);
// lst1111_2
cont111_2, null, ModifyAction.CREATE, null);
cont111_2.getChildren().add(lst1111_2_1);
MutableSimpleNode<?> lf1111B_2_1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1111B"),
- lst1111_2_1, "4", ModifyAction.CREATE, null);
+ lst1111_2_1, (short) 4, ModifyAction.CREATE, null);
lst1111_2_1.getChildren().add(lf1111B_2_1);
lst1111_2_1.init();
MutableCompositeNode lst1111_2_2 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst1111"),
cont111_2, null, ModifyAction.CREATE, null);
cont111_2.getChildren().add(lst1111_2_2);
- MutableSimpleNode<?> lf1111B_2_2 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1111A"),
+ MutableSimpleNode<?> lf1111A_2_2 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1111A"),
lst1111_2_2, "lf1111A str12", ModifyAction.CREATE, null);
- lst1111_2_2.getChildren().add(lf1111B_2_2);
+ lst1111_2_2.getChildren().add(lf1111A_2_2);
lst1111_2_2.init();
// :lst1111_2
null, ModifyAction.CREATE, null);
cont1.getChildren().add(lst11_3);
- MutableSimpleNode<?> lf111_3 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf111"), lst11_3, "3",
- ModifyAction.CREATE, null);
+ MutableSimpleNode<?> lf111_3 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf111"), lst11_3,
+ (short) 3, ModifyAction.CREATE, null);
lst11_3.getChildren().add(lf111_3);
// cont111_3
--- /dev/null
+package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.test;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+
+import javax.ws.rs.WebApplicationException;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
+import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+
+public class ToJsonChoiceCaseTest extends YangAndXmlAndDataSchemaLoader {
+
+ @BeforeClass
+ public static void initialization() {
+ dataLoad("/cnsn-to-json/choice");
+ }
+
+ /**
+ * Test when some data are in one case node and other in another. This isn't
+ * correct. Next Json validator should return error because nodes has to be
+ * from one case below concrete choice.
+ *
+ */
+ @Test
+ public void nodeSchemasOnVariousChoiceCasePathTest() {
+ testWrapper("/cnsn-to-json/choice/xml/data_various_path_err.xml", "choice-case-test:cont");
+ }
+
+ /**
+ * Test when some data are in one case node and other in another.
+ * Additionally data are loadef from various choices. This isn't correct.
+ * Next Json validator should return error because nodes has to be from one
+ * case below concrete choice.
+ *
+ */
+ @Test
+ public void nodeSchemasOnVariousChoiceCasePathAndMultipleChoicesTest() {
+ testWrapper("/cnsn-to-json/choice/xml/data_more_choices_same_level_various_paths_err.xml",
+ "choice-case-test:cont");
+ }
+
+ /**
+ * Test when second level data are red first, then first and at the end
+ * third level. Level represents pass through couple choice-case
+ */
+
+ @Test
+ public void nodeSchemasWithRandomOrderAccordingLevel() {
+ testWrapper("/cnsn-to-json/choice/xml/data_random_level.xml", "choice-case-test:cont");
+ }
+
+ /**
+ * Test when element from no first case is used
+ */
+ @Test
+ public void nodeSchemasNotInFirstCase() {
+ testWrapper("/cnsn-to-json/choice/xml/data_no_first_case.xml", "choice-case-test:cont");
+ }
+
+ /**
+ * Test when element in case is list
+ */
+ @Test
+ public void nodeSchemaAsList() {
+ testWrapper("/cnsn-to-json/choice/xml/data_list.xml", "choice-case-test:cont");
+ }
+
+ /**
+ * Test when element in case is container
+ */
+ @Test
+ public void nodeSchemaAsContainer() {
+ testWrapper("/cnsn-to-json/choice/xml/data_container.xml", "choice-case-test:cont");
+ }
+
+ /**
+ * Test when element in case is leaflist
+ */
+ @Test
+ public void nodeSchemaAsLeafList() {
+ testWrapper("/cnsn-to-json/choice/xml/data_leaflist.xml", "choice-case-test:cont");
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void nodeSchemasInMultipleChoicesTest() {
+ testWrapper("/cnsn-to-json/choice/xml/data_more_choices_same_level.xml", "choice-case-test:cont");
+ }
+
+ /**
+ * Test whether is possible to find data schema for node which is specified
+ * as dirrect subnode of choice (case without CASE key word)
+ */
+ @Test
+ public void nodeSchemasInCaseNotDefinedWithCaseKeyword() {
+ testWrapper("/cnsn-to-json/choice/xml/data_case_defined_without_case.xml", "choice-case-test:cont");
+ }
+
+ /**
+ * Test of multiple use of choices
+ */
+ @Test
+ public void nodeSchemasInThreeChoicesAtSameLevel() {
+ testWrapper("/cnsn-to-json/choice/xml/data_three_choices_same_level.xml", "choice-case-test:cont");
+ }
+
+ private void testWrapper(String xmlPath, String pathToSchemaNode) {
+ CompositeNode compNode = TestUtils.loadCompositeNode(xmlPath);
+ TestUtils.normalizeCompositeNode(compNode, modules, dataSchemaNode, pathToSchemaNode);
+ try {
+ TestUtils.writeCompNodeWithSchemaContextToJson(compNode, modules, dataSchemaNode);
+ } catch (WebApplicationException | IOException e) {
+ // shouldn't end here
+ assertTrue(false);
+ }
+ }
+}
-package org.opendaylight.controller.sal.restconf.impl.test;
+package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.test;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
-import java.util.regex.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import javax.ws.rs.WebApplicationException;
-import org.junit.*;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
+import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
import org.opendaylight.yangtools.yang.data.api.*;
import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
@BeforeClass
public static void initialization() {
- dataLoad("/yang-to-json-conversion/identityref", 2, "identityref-module", "cont");
+ dataLoad("/cnsn-to-json/identityref", 2, "identityref-module", "cont");
}
@Test
public void identityrefToJsonTest() {
String json = null;
try {
- json = TestUtils
- .writeCompNodeWithSchemaContextToJson(prepareCompositeNode(), null, modules, dataSchemaNode);
+ json = TestUtils.writeCompNodeWithSchemaContextToJson(prepareCompositeNode(), modules, dataSchemaNode);
} catch (WebApplicationException | IOException e) {
// shouldn't end here
assertTrue(false);
private CompositeNode prepareCompositeNode() {
MutableCompositeNode cont = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont"), null, null,
ModifyAction.CREATE, null);
- MutableSimpleNode<?> lf1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1"), cont,
+ MutableCompositeNode cont1 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont1"), cont, null,
+ ModifyAction.CREATE, null);
+ cont.getChildren().add(cont1);
+
+ MutableSimpleNode<?> lf1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1"), cont1,
TestUtils.buildQName("name_test", "identityref:module", "2013-12-2"), ModifyAction.CREATE, null);
- cont.getChildren().add(lf1);
+ cont1.getChildren().add(lf1);
+ cont1.init();
cont.init();
return cont;
-package org.opendaylight.controller.sal.restconf.impl.test;
+package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.test;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import javax.ws.rs.WebApplicationException;
import org.junit.*;
+import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
+import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
+
+/**
+ *
+ * All tests are commented now because leafref isn't supported now
+ *
+ */
public class ToJsonLeafrefType extends YangAndXmlAndDataSchemaLoader {
@BeforeClass
public static void initialization() {
- dataLoad("/yang-to-json-conversion/leafref", 2, "main-module", "cont");
+ dataLoad("/cnsn-to-json/leafref", 2, "main-module", "cont");
}
+ @Ignore
@Test
public void leafrefAbsolutePathToExistingLeafTest() {
String json = null;
try {
- json = TestUtils.writeCompNodeWithSchemaContextToJson(TestUtils
- .loadCompositeNode("/yang-to-json-conversion/leafref/xml/data_absolut_ref_to_existing_leaf.xml"),
- "/yang-to-json-conversion/leafref/xml", modules, dataSchemaNode);
+ json = TestUtils.writeCompNodeWithSchemaContextToJson(
+ TestUtils.loadCompositeNode("/cnsn-to-json/leafref/xml/data_absolut_ref_to_existing_leaf.xml"),
+ modules, dataSchemaNode);
} catch (WebApplicationException | IOException e) {
// shouldn't end here
assertTrue(false);
assertTrue(mtch.matches());
}
+ @Ignore
@Test
public void leafrefRelativePathToExistingLeafTest() {
String json = null;
try {
- json = TestUtils.writeCompNodeWithSchemaContextToJson(TestUtils
- .loadCompositeNode("/yang-to-json-conversion/leafref/xml/data_relativ_ref_to_existing_leaf.xml"),
- "/yang-to-json-conversion/leafref/xml", modules, dataSchemaNode);
+ json = TestUtils.writeCompNodeWithSchemaContextToJson(
+ TestUtils.loadCompositeNode("/cnsn-to-json/leafref/xml/data_relativ_ref_to_existing_leaf.xml"),
+ modules, dataSchemaNode);
} catch (WebApplicationException | IOException e) {
// shouldn't end here
assertTrue(false);
* Tests case when reference to not existing element is present. In this
* case value from single node is printed as string.
*/
+ @Ignore
@Test
public void leafrefToNonExistingLeafTest() {
String json = null;
try {
- json = TestUtils.writeCompNodeWithSchemaContextToJson(TestUtils
- .loadCompositeNode("/yang-to-json-conversion/leafref/xml/data_ref_to_non_existing_leaf.xml"),
- "/yang-to-json-conversion/leafref/xml", modules, dataSchemaNode);
+ json = TestUtils.writeCompNodeWithSchemaContextToJson(
+ TestUtils.loadCompositeNode("/cnsn-to-json/leafref/xml/data_ref_to_non_existing_leaf.xml"),
+ modules, dataSchemaNode);
} catch (WebApplicationException | IOException e) {
// shouldn't end here
assertTrue(false);
* Tests case when non leaf element is referenced. In this case value from
* single node is printed as string.
*/
+ @Ignore
@Test
public void leafrefToNotLeafTest() {
String json = null;
try {
json = TestUtils.writeCompNodeWithSchemaContextToJson(
- TestUtils.loadCompositeNode("/yang-to-json-conversion/leafref/xml/data_ref_to_not_leaf.xml"),
- "/yang-to-json-conversion/leafref/xml", modules, dataSchemaNode);
+ TestUtils.loadCompositeNode("/cnsn-to-json/leafref/xml/data_ref_to_not_leaf.xml"), modules,
+ dataSchemaNode);
} catch (WebApplicationException | IOException e) {
// shouldn't end here
assertTrue(false);
/**
* Tests case when leaflist element is refers to leaf.
*/
+ @Ignore
@Test
public void leafrefFromLeafListToLeafTest() {
String json = null;
json = TestUtils
.writeCompNodeWithSchemaContextToJson(
TestUtils
- .loadCompositeNode("/yang-to-json-conversion/leafref/xml/data_relativ_ref_from_leaflist_to_existing_leaf.xml"),
- "/yang-to-json-conversion/leafref/xml", modules, dataSchemaNode);
+ .loadCompositeNode("/cnsn-to-json/leafref/xml/data_relativ_ref_from_leaflist_to_existing_leaf.xml"),
+ modules, dataSchemaNode);
} catch (WebApplicationException | IOException e) {
// shouldn't end here
assertTrue(false);
/**
* Tests case when leaflist element is refers to leaf.
*/
+ @Ignore
@Test
public void leafrefFromLeafrefToLeafrefTest() {
String json = null;
try {
- json = TestUtils.writeCompNodeWithSchemaContextToJson(TestUtils
- .loadCompositeNode("/yang-to-json-conversion/leafref/xml/data_from_leafref_to_leafref.xml"),
- "/yang-to-json-conversion/leafref/xml", modules, dataSchemaNode);
+ json = TestUtils.writeCompNodeWithSchemaContextToJson(
+ TestUtils.loadCompositeNode("/cnsn-to-json/leafref/xml/data_from_leafref_to_leafref.xml"), modules,
+ dataSchemaNode);
} catch (WebApplicationException | IOException e) {
// shouldn't end here
assertTrue(false);
-package org.opendaylight.controller.sal.restconf.impl.test;
+package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.test;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
+import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
public class ToJsonWithAugmentTest {
*/
@Test
public void augmentedElementsToJson() {
- String jsonOutput = TestUtils.convertCompositeNodeDataAndYangToJson(
- TestUtils.loadCompositeNode("/yang-to-json-conversion/augmentation/xml/data.xml"),
- "/yang-to-json-conversion/augmentation", "/yang-to-json-conversion/augmentation/xml", "yang", "cont");
+
+ CompositeNode compositeNode = TestUtils.loadCompositeNode("/cnsn-to-json/augmentation/xml/data.xml");
+ String jsonOutput = TestUtils.convertCompositeNodeDataAndYangToJson(compositeNode,
+ "/cnsn-to-json/augmentation", "/cnsn-to-json/augmentation/xml", "yang", "cont");
assertTrue(jsonOutput.contains("\"augment-leaf:lf2\": \"lf2\""));
assertTrue(jsonOutput.contains("\"augment-container:cont1\": {"));
--- /dev/null
+package org.opendaylight.controller.sal.restconf.impl.cnsn.to.xml.test;
+
+import static org.junit.Assert.*;
+
+import java.io.StringWriter;
+import java.util.Set;
+
+import javax.activation.UnsupportedDataTypeException;
+import javax.xml.transform.*;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.controller.sal.rest.impl.XmlMapper;
+import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
+import org.opendaylight.yangtools.yang.data.api.*;
+import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
+import org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec;
+import org.opendaylight.yangtools.yang.model.api.*;
+import org.w3c.dom.Document;
+
+/**
+ *
+ * CnSn = Composite node and Simple node data structure Class contains test of
+ * serializing simple nodes data values according data types from YANG schema to
+ * XML file
+ *
+ */
+public class CnSnToXmlTest {
+
+ private static Set<Module> modules;
+ private static DataSchemaNode dataSchemaNode;
+
+ @BeforeClass
+ public static void initialization() {
+ modules = TestUtils.resolveModules("/cnsn-to-xml/yang");
+ assertEquals(2, modules.size());
+ Module module = TestUtils.resolveModule("basic-module", modules);
+ assertNotNull(module);
+ dataSchemaNode = TestUtils.resolveDataSchemaNode(module, "cont");
+ assertNotNull(dataSchemaNode);
+
+ }
+
+ @Test
+ public void snAsYangIdentityrefToXMLTest() {
+ serializeToXml(prepareIdentityrefData(), "<lf11 xmlns:x=\"referenced:module\">x:iden</lf11>");
+ }
+
+ @Test
+ public void snAsYangStringToXmlTest() {
+ serializeToXml(
+ prepareCnStructForYangData(TypeDefinitionAwareCodec.STRING_DEFAULT_CODEC.deserialize("lfStr value"),
+ "lfStr"), "<lfStr>lfStr value</lfStr>");
+ }
+
+ @Test
+ public void snAsYangInt8ToXmlTest() {
+ String elName = "lfInt8";
+ serializeToXml(
+ prepareCnStructForYangData(TypeDefinitionAwareCodec.INT8_DEFAULT_CODEC.deserialize("14"), elName), "<"
+ + elName + ">14</" + elName + ">");
+ }
+
+ @Test
+ public void snAsYangInt16ToXmlTest() {
+ String elName = "lfInt16";
+ serializeToXml(
+ prepareCnStructForYangData(TypeDefinitionAwareCodec.INT16_DEFAULT_CODEC.deserialize("3000"), elName),
+ "<" + elName + ">3000</" + elName + ">");
+ }
+
+ @Test
+ public void snAsYangInt32ToXmlTest() {
+ String elName = "lfInt32";
+ serializeToXml(
+ prepareCnStructForYangData(TypeDefinitionAwareCodec.INT32_DEFAULT_CODEC.deserialize("201234"), elName),
+ "<" + elName + ">201234</" + elName + ">");
+ }
+
+ @Test
+ public void snAsYangInt64ToXmlTest() {
+ String elName = "lfInt64";
+ serializeToXml(
+ prepareCnStructForYangData(TypeDefinitionAwareCodec.INT64_DEFAULT_CODEC.deserialize("5123456789"),
+ elName), "<" + elName + ">5123456789</" + elName + ">");
+ }
+
+ @Test
+ public void snAsYangUint8ToXmlTest() {
+ String elName = "lfUint8";
+ serializeToXml(
+ prepareCnStructForYangData(TypeDefinitionAwareCodec.UINT8_DEFAULT_CODEC.deserialize("200"), elName),
+ "<" + elName + ">200</" + elName + ">");
+ }
+
+ @Test
+ public void snAsYangUint16ToXmlTest() {
+ String elName = "lfUint16";
+ serializeToXml(
+ prepareCnStructForYangData(TypeDefinitionAwareCodec.UINT16_DEFAULT_CODEC.deserialize("4000"), elName),
+ "<" + elName + ">4000</" + elName + ">");
+ }
+
+ @Test
+ public void snAsYangUint32ToXmlTest() {
+ String elName = "lfUint32";
+ serializeToXml(
+ prepareCnStructForYangData(TypeDefinitionAwareCodec.UINT32_DEFAULT_CODEC.deserialize("4123456789"),
+ elName), "<" + elName + ">4123456789</" + elName + ">");
+ }
+
+ @Test
+ public void snAsYangUint64ToXmlTest() {
+ String elName = "lfUint64";
+ serializeToXml(
+ prepareCnStructForYangData(TypeDefinitionAwareCodec.UINT64_DEFAULT_CODEC.deserialize("5123456789"),
+ elName), "<" + elName + ">5123456789</" + elName + ">");
+ }
+
+ @Test
+ public void snAsYangBinaryToXmlTest() {
+ String elName = "lfBinary";
+ serializeToXml(
+ prepareCnStructForYangData(
+ TypeDefinitionAwareCodec.BINARY_DEFAULT_CODEC
+ .deserialize("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567"),
+ elName), "<" + elName + ">ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567</"
+ + elName + ">");
+ }
+
+ @Test
+ public void snAsYangBitsToXmlTest() {
+ String elName = "lfBits";
+ serializeToXml(
+ prepareCnStructForYangData(TypeDefinitionAwareCodec.BITS_DEFAULT_CODEC.deserialize("one two"), elName),
+ "<" + elName + ">one two</" + elName + ">", "<" + elName + ">two one</" + elName + ">");
+ }
+
+ @Test
+ public void snAsYangEnumerationToXmlTest() {
+ String elName = "lfEnumeration";
+ serializeToXml(
+ prepareCnStructForYangData(TypeDefinitionAwareCodec.ENUMERATION_DEFAULT_CODEC.deserialize("enum2"),
+ elName), "<" + elName + ">enum2</" + elName + ">");
+ }
+
+ @Test
+ public void snAsYangEmptyToXmlTest() {
+ String elName = "lfEmpty";
+ serializeToXml(
+ prepareCnStructForYangData(TypeDefinitionAwareCodec.EMPTY_DEFAULT_CODEC.deserialize(null), elName), "<"
+ + elName + "/>");
+ }
+
+ @Test
+ public void snAsYangBooleanToXmlTest() {
+ String elName = "lfBoolean";
+ serializeToXml(
+ prepareCnStructForYangData(TypeDefinitionAwareCodec.BOOLEAN_DEFAULT_CODEC.deserialize("str"), elName),
+ "<" + elName + ">false</" + elName + ">");
+ serializeToXml(
+ prepareCnStructForYangData(TypeDefinitionAwareCodec.BOOLEAN_DEFAULT_CODEC.deserialize("true"), elName),
+ "<" + elName + ">true</" + elName + ">");
+ }
+
+ @Test
+ public void snAsYangUnionToXmlTest() {
+ String elName = "lfUnion";
+ String int8 = "15";
+ serializeToXml(
+ prepareCnStructForYangData(TypeDefinitionAwareCodec.UNION_DEFAULT_CODEC.deserialize(int8), elName), "<"
+ + elName + ">15</" + elName + ">");
+
+ String bits = "first second";
+ serializeToXml(
+ prepareCnStructForYangData(TypeDefinitionAwareCodec.UNION_DEFAULT_CODEC.deserialize(bits), elName), "<"
+ + elName + ">first second</" + elName + ">");
+
+ String bool = "str";
+ serializeToXml(
+ prepareCnStructForYangData(TypeDefinitionAwareCodec.UNION_DEFAULT_CODEC.deserialize(bool), elName), "<"
+ + elName + ">str</" + elName + ">");
+ }
+
+ private void serializeToXml(CompositeNode compositeNode, String... xmlRepresentation)
+ throws TransformerFactoryConfigurationError {
+ XmlMapper xmlMapper = new XmlMapper();
+ String xmlString = null;
+ if (dataSchemaNode instanceof DataNodeContainer) {
+ try {
+ Document doc = xmlMapper.write(compositeNode, (DataNodeContainer) dataSchemaNode);
+ DOMSource domSource = new DOMSource(doc);
+ StringWriter writer = new StringWriter();
+ StreamResult result = new StreamResult(writer);
+ TransformerFactory tf = TransformerFactory.newInstance();
+ Transformer transformer = tf.newTransformer();
+ transformer.transform(domSource, result);
+ xmlString = writer.toString();
+ } catch (UnsupportedDataTypeException | TransformerException e) {
+ }
+ }
+ assertNotNull(xmlMapper);
+ boolean containSearchedStr = false;
+ String strRepresentation = "";
+ for (String searchedStr : xmlRepresentation) {
+ if (xmlString.contains(searchedStr)) {
+ containSearchedStr = true;
+ break;
+ }
+ strRepresentation = strRepresentation + "[" + searchedStr + "]";
+ }
+ assertTrue("At least one of specified strings " + strRepresentation + " wasn't found.", containSearchedStr);
+
+ }
+
+ private CompositeNode prepareIdentityrefData() {
+ MutableCompositeNode cont = NodeFactory.createMutableCompositeNode(
+ TestUtils.buildQName("cont", "basic:module", "2013-12-2"), null, null, ModifyAction.CREATE, null);
+ MutableCompositeNode cont1 = NodeFactory.createMutableCompositeNode(
+ TestUtils.buildQName("cont1", "basic:module", "2013-12-2"), cont, null, ModifyAction.CREATE, null);
+ cont.getChildren().add(cont1);
+
+ MutableSimpleNode<Object> lf11 = NodeFactory.createMutableSimpleNode(
+ TestUtils.buildQName("lf11", "basic:module", "2013-12-2"), cont1,
+ TestUtils.buildQName("iden", "referenced:module", "2013-12-2"), ModifyAction.CREATE, null);
+ cont1.getChildren().add(lf11);
+ cont1.init();
+ cont.init();
+
+ return cont;
+ }
+
+ private CompositeNode prepareCnStructForYangData(Object data, String leafName) {
+ MutableCompositeNode cont = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont"), null, null,
+ ModifyAction.CREATE, null);
+
+ MutableSimpleNode<Object> lf1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName(leafName), cont, data,
+ ModifyAction.CREATE, null);
+ cont.getChildren().add(lf1);
+ cont.init();
+
+ return cont;
+ }
+
+}
-package org.opendaylight.controller.sal.restconf.impl.test;
+package org.opendaylight.controller.sal.restconf.impl.json.to.cnsn.test;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.*;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
+import java.io.*;
import java.net.URISyntaxException;
import java.util.List;
+import java.util.Set;
import javax.ws.rs.WebApplicationException;
import org.junit.Test;
import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider;
import org.opendaylight.controller.sal.restconf.impl.CompositeNodeWrapper;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.Node;
-import org.opendaylight.yangtools.yang.data.api.SimpleNode;
+import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.*;
import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.gson.JsonSyntaxException;
-public class FromJsonToCompositeNodeTest {
+public class JsonToCnSnTest {
- private static final Logger LOG = LoggerFactory.getLogger(FromJsonToCompositeNodeTest.class);
+ private static final Logger LOG = LoggerFactory.getLogger(JsonToCnSnTest.class);
@Test
public void simpleListTest() {
- simpleTest("/json-to-composite-node/simple-list.json", "/json-to-composite-node/simple-list-yang", "lst",
- "simple:list:yang1", "simple-list-yang1");
+ simpleTest("/json-to-cnsn/simple-list.json", "/json-to-cnsn/simple-list-yang", "lst", "simple:list:yang1",
+ "simple-list-yang1");
}
@Test
public void simpleContainerTest() {
- simpleTest("/json-to-composite-node/simple-container.json", "/json-to-composite-node/simple-container-yang",
- "cont", "simple:container:yang", "simple-container-yang");
+ simpleTest("/json-to-cnsn/simple-container.json", "/json-to-cnsn/simple-container-yang", "cont",
+ "simple:container:yang", "simple-container-yang");
}
/**
*/
@Test
public void multipleItemsInLeafList() {
- CompositeNode compositeNode = compositeContainerFromJson(
- "/json-to-composite-node/multiple-leaflist-items.json", true);
+ CompositeNode compositeNode = compositeContainerFromJson("/json-to-cnsn/multiple-leaflist-items.json", true);
assertNotNull(compositeNode);
assertEquals(3, compositeNode.getChildren().size());
*/
@Test
public void multipleItemsInListTest() {
- CompositeNode compositeNode = compositeContainerFromJson("/json-to-composite-node/multiple-items-in-list.json",
- true);
+ CompositeNode compositeNode = compositeContainerFromJson("/json-to-cnsn/multiple-items-in-list.json", true);
assertNotNull(compositeNode);
assertEquals("lst", compositeNode.getNodeType().getLocalName());
@Test
public void nullArrayToSimpleNodeWithNullValueTest() {
- CompositeNode compositeNode = compositeContainerFromJson("/json-to-composite-node/array-with-null.json", true);
+ CompositeNode compositeNode = compositeContainerFromJson("/json-to-cnsn/array-with-null.json", true);
assertNotNull(compositeNode);
assertEquals("cont", compositeNode.getNodeType().getLocalName());
public void incorrectTopLevelElementsTest() {
Throwable cause1 = null;
try {
- compositeContainerFromJson("/json-to-composite-node/wrong-top-level1.json", true);
+ compositeContainerFromJson("/json-to-cnsn/wrong-top-level1.json", true);
} catch (WebApplicationException e) {
cause1 = e;
}
Throwable cause2 = null;
try {
- compositeContainerFromJson("/json-to-composite-node/wrong-top-level2.json", true);
+ compositeContainerFromJson("/json-to-cnsn/wrong-top-level2.json", true);
} catch (WebApplicationException e) {
cause2 = e;
}
Throwable cause3 = null;
try {
- compositeContainerFromJson("/json-to-composite-node/wrong-top-level3.json", true);
+ compositeContainerFromJson("/json-to-cnsn/wrong-top-level3.json", true);
} catch (WebApplicationException e) {
cause3 = e;
}
*/
@Test
public void emptyDataReadTest() {
- CompositeNode compositeNode = compositeContainerFromJson("/json-to-composite-node/empty-data.json", true);
+ CompositeNode compositeNode = compositeContainerFromJson("/json-to-cnsn/empty-data.json", true);
assertNotNull(compositeNode);
String reason = null;
try {
- compositeContainerFromJson("/json-to-composite-node/empty-data1.json", true);
+ compositeContainerFromJson("/json-to-cnsn/empty-data1.json", true);
} catch (JsonSyntaxException e) {
reason = e.getMessage();
}
@Test
public void notSupplyNamespaceIfAlreadySupplied() {
- CompositeNode compositeNode = compositeContainerFromJson("/json-to-composite-node/simple-list.json");
+ CompositeNode compositeNode = compositeContainerFromJson("/json-to-cnsn/simple-list.json");
assertNotNull(compositeNode);
DataSchemaNode dataSchemaNode1 = null;
DataSchemaNode dataSchemaNode2 = null;
try {
- dataSchemaNode1 = TestUtils.obtainSchemaFromYang("/json-to-composite-node/simple-list-yang",
- "simple-list-yang1");
- dataSchemaNode2 = TestUtils.obtainSchemaFromYang("/json-to-composite-node/simple-list-yang",
- "simple-list-yang2");
+ dataSchemaNode1 = TestUtils.obtainSchemaFromYang("/json-to-cnsn/simple-list-yang", "simple-list-yang1");
+ dataSchemaNode2 = TestUtils.obtainSchemaFromYang("/json-to-cnsn/simple-list-yang", "simple-list-yang2");
} catch (FileNotFoundException e) {
LOG.error(e.getMessage());
assertTrue(false);
}
+ @Test
+ public void jsonIdentityrefToCompositeNode() {
+ CompositeNode compositeNode = compositeContainerFromJson("/json-to-cnsn/identityref/json/data.json");
+ assertNotNull(compositeNode);
+
+ Set<Module> modules = TestUtils.resolveModules("/json-to-cnsn/identityref");
+ assertEquals(2, modules.size());
+ Module module = TestUtils.resolveModule("identityref-module", modules);
+ assertNotNull(module);
+ DataSchemaNode dataSchemaNode = TestUtils.resolveDataSchemaNode(module, null);
+ assertNotNull(dataSchemaNode);
+
+ TestUtils.normalizeCompositeNode(compositeNode, modules, dataSchemaNode, "identityref-module:cont");
+
+ assertEquals("cont", compositeNode.getNodeType().getLocalName());
+
+ List<Node<?>> childs = compositeNode.getChildren();
+ assertEquals(1, childs.size());
+ Node<?> nd = childs.iterator().next();
+ assertTrue(nd instanceof CompositeNode);
+ assertEquals("cont1", nd.getNodeType().getLocalName());
+
+ childs = ((CompositeNode) nd).getChildren();
+ assertEquals(4, childs.size());
+ SimpleNode<?> lf11 = null;
+ SimpleNode<?> lf12 = null;
+ SimpleNode<?> lf13 = null;
+ SimpleNode<?> lf14 = null;
+ for (Node<?> child : childs) {
+ assertTrue(child instanceof SimpleNode);
+ if (child.getNodeType().getLocalName().equals("lf11")) {
+ lf11 = (SimpleNode<?>) child;
+ } else if (child.getNodeType().getLocalName().equals("lf12")) {
+ lf12 = (SimpleNode<?>) child;
+ } else if (child.getNodeType().getLocalName().equals("lf13")) {
+ lf13 = (SimpleNode<?>) child;
+ } else if (child.getNodeType().getLocalName().equals("lf14")) {
+ lf14 = (SimpleNode<?>) child;
+ }
+ }
+
+ assertTrue(lf11.getValue() instanceof QName);
+ assertEquals("iden", ((QName) lf11.getValue()).getLocalName());
+ assertEquals("identity:module", ((QName) lf11.getValue()).getNamespace().toString());
+
+ assertTrue(lf12.getValue() instanceof QName);
+ assertEquals("iden_local", ((QName) lf12.getValue()).getLocalName());
+ assertEquals("identityref:module", ((QName) lf12.getValue()).getNamespace().toString());
+
+ assertTrue(lf13.getValue() instanceof QName);
+ assertEquals("iden_local", ((QName) lf13.getValue()).getLocalName());
+ assertEquals("identityref:module", ((QName) lf13.getValue()).getNamespace().toString());
+
+ assertTrue(lf14.getValue() instanceof QName);
+ assertEquals("iden_local", ((QName) lf14.getValue()).getLocalName());
+ assertEquals("identity:module", ((QName) lf14.getValue()).getNamespace().toString());
+ }
+
private void simpleTest(String jsonPath, String yangPath, String topLevelElementName, String namespace,
String moduleName) {
CompositeNode compositeNode = compositeContainerFromJson(jsonPath);
throws WebApplicationException {
JsonToCompositeNodeProvider jsonToCompositeNodeProvider = JsonToCompositeNodeProvider.INSTANCE;
- InputStream jsonStream = FromJsonToCompositeNodeTest.class.getResourceAsStream(jsonPath);
+ InputStream jsonStream = JsonToCnSnTest.class.getResourceAsStream(jsonPath);
try {
CompositeNode compositeNode = jsonToCompositeNodeProvider
.readFrom(null, null, null, null, null, jsonStream);
import static org.mockito.Mockito.when;
import java.io.FileNotFoundException;
-import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URLEncoder;
import java.util.List;
import java.util.Set;
-import java.util.concurrent.Future;
import java.util.logging.Level;
import java.util.logging.LogRecord;
-import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
-import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider;
import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
import org.opendaylight.controller.sal.restconf.impl.BrokerFacade;
import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
import org.opendaylight.controller.sal.restconf.impl.RestconfImpl;
-import org.opendaylight.yangtools.yang.common.RpcResult;
import org.opendaylight.yangtools.yang.data.api.CompositeNode;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
import org.opendaylight.yangtools.yang.model.api.Module;
String uri = createUri("/config/", "ietf-interfaces:interfaces/interface/eth0");
- InputStream xmlStream = RestconfImplTest.class.getResourceAsStream("/parts/ietf-interfaces_interfaces.xml");
- CompositeNode loadedCompositeNode = TestUtils.loadCompositeNode(xmlStream);
+ CompositeNode loadedCompositeNode = TestUtils.loadCompositeNodeWithXmlTreeBuilder("/parts/ietf-interfaces_interfaces.xml");
when(brokerFacade.readConfigurationData(any(InstanceIdentifier.class))).thenReturn(loadedCompositeNode);
Response response = target(uri).request(MEDIA_TYPE_DRAFT02).get();
public void testReadOperationalData() throws UnsupportedEncodingException, FileNotFoundException {
String uri = createUri("/operational/", "ietf-interfaces:interfaces/interface/eth0");
- InputStream xmlStream = RestconfImplTest.class.getResourceAsStream("/parts/ietf-interfaces_interfaces.xml");
- CompositeNode loadedCompositeNode = TestUtils.loadCompositeNode(xmlStream);
+ CompositeNode loadedCompositeNode = TestUtils.loadCompositeNodeWithXmlTreeBuilder("/parts/ietf-interfaces_interfaces.xml");
when(brokerFacade.readOperationalData(any(InstanceIdentifier.class))).thenReturn(loadedCompositeNode);
Response response = target(uri).request(MEDIA_TYPE_DRAFT02).get();
package org.opendaylight.controller.sal.restconf.impl.test;
-import static org.mockito.Mockito.*;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
import java.io.FileNotFoundException;
import java.io.InputStream;
import org.junit.BeforeClass;
import org.junit.Test;
-import org.opendaylight.controller.sal.restconf.impl.BrokerFacade;
-import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
-import org.opendaylight.controller.sal.restconf.impl.RestconfImpl;
+import org.opendaylight.controller.sal.restconf.impl.*;
import org.opendaylight.yangtools.yang.data.api.CompositeNode;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
import org.opendaylight.yangtools.yang.model.api.Module;
@BeforeClass
public static void init() throws FileNotFoundException {
- Set<Module> allModules = TestUtils.loadModules(RestconfImplTest.class.getResource("/full-versions/yangs").getPath());
+ Set<Module> allModules = TestUtils.loadModules(RestconfImplTest.class.getResource("/full-versions/yangs")
+ .getPath());
SchemaContext schemaContext = TestUtils.loadSchemaContext(allModules);
ControllerContext controllerContext = ControllerContext.getInstance();
controllerContext.setSchemas(schemaContext);
@Test
public void testExample() throws FileNotFoundException {
InputStream xmlStream = RestconfImplTest.class.getResourceAsStream("/parts/ietf-interfaces_interfaces.xml");
- CompositeNode loadedCompositeNode = TestUtils.loadCompositeNode(xmlStream);
+ CompositeNode loadedCompositeNode = TestUtils.loadCompositeNodeWithXmlTreeBuilder(xmlStream);
BrokerFacade brokerFacade = mock(BrokerFacade.class);
when(brokerFacade.readOperationalData(any(InstanceIdentifier.class))).thenReturn(loadedCompositeNode);
assertEquals(loadedCompositeNode, brokerFacade.readOperationalData(null));
package org.opendaylight.controller.sal.restconf.impl.test;
-import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.io.*;
-import java.net.*;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.sql.Date;
import java.util.*;
import java.util.concurrent.Future;
import javax.xml.transform.stream.StreamResult;
import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
-import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider;
+import org.opendaylight.controller.sal.rest.impl.*;
import org.opendaylight.controller.sal.restconf.impl.*;
-import org.opendaylight.yangtools.yang.common.*;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.RpcResult;
import org.opendaylight.yangtools.yang.data.api.*;
import org.opendaylight.yangtools.yang.data.impl.XmlTreeBuilder;
import org.opendaylight.yangtools.yang.model.api.*;
import org.opendaylight.yangtools.yang.model.parser.api.YangModelParser;
import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
-import org.slf4j.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
import com.google.common.base.Preconditions;
-final class TestUtils {
+public final class TestUtils {
private static final Logger logger = LoggerFactory.getLogger(TestUtils.class);
return result;
}
- public static CompositeNode loadCompositeNode(InputStream xmlInputStream) throws FileNotFoundException {
- if (xmlInputStream == null) {
- throw new IllegalArgumentException();
- }
- Node<?> dataTree;
- try {
- dataTree = XmlTreeBuilder.buildDataTree(xmlInputStream);
- } catch (XMLStreamException e) {
- logger.error("Error during building data tree from XML", e);
- return null;
- }
- if (dataTree == null) {
- logger.error("data tree is null");
- return null;
- }
- if (dataTree instanceof SimpleNode) {
- logger.error("RPC XML was resolved as SimpleNode");
- return null;
- }
- return (CompositeNode) dataTree;
- }
+
public static Document loadDocumentFrom(InputStream inputStream) {
try {
}
- static String convertCompositeNodeDataAndYangToJson(CompositeNode compositeNode, String yangPath, String outputPath) {
- return convertCompositeNodeDataAndYangToJson(compositeNode, yangPath, outputPath, null, null);
- }
-
- static String convertCompositeNodeDataAndYangToJson(CompositeNode compositeNode, String yangPath,
+ public static String convertCompositeNodeDataAndYangToJson(CompositeNode compositeNode, String yangPath,
String outputPath, String searchedModuleName, String searchedDataSchemaName) {
Set<Module> modules = resolveModules(yangPath);
Module module = resolveModule(searchedModuleName, modules);
DataSchemaNode dataSchemaNode = resolveDataSchemaNode(module, searchedDataSchemaName);
+ normalizeCompositeNode(compositeNode, modules, dataSchemaNode, searchedModuleName + ":"
+ + searchedDataSchemaName);
+
try {
- return writeCompNodeWithSchemaContextToJson(compositeNode, outputPath, modules, dataSchemaNode);
+ return writeCompNodeWithSchemaContextToJson(compositeNode, modules, dataSchemaNode);
} catch (WebApplicationException | IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
- static Module resolveModule(String searchedModuleName, Set<Module> modules) {
+ public static void normalizeCompositeNode(CompositeNode compositeNode, Set<Module> modules,
+ DataSchemaNode dataSchemaNode, String schemaNodePath) {
+ RestconfImpl restconf = RestconfImpl.getInstance();
+ ControllerContext.getInstance().setSchemas(TestUtils.loadSchemaContext(modules));
+
+ TestUtils.prepareMockForRestconfBeforeNormalization(modules, dataSchemaNode, restconf);
+ restconf.createConfigurationData(schemaNodePath, compositeNode);
+ }
+
+ public static Module resolveModule(String searchedModuleName, Set<Module> modules) {
assertNotNull("modules can't be null.", modules);
Module module = null;
if (searchedModuleName != null) {
return module;
}
- static Set<Module> resolveModules(String yangPath) {
+ public static Set<Module> resolveModules(String yangPath) {
Set<Module> modules = null;
try {
- modules = TestUtils.loadModules(ToJsonBasicDataTypesTest.class.getResource(yangPath).getPath());
+ modules = TestUtils.loadModules(TestUtils.class.getResource(yangPath).getPath());
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return modules;
}
- static DataSchemaNode resolveDataSchemaNode(Module module, String searchedDataSchemaName) {
+ public static DataSchemaNode resolveDataSchemaNode(Module module, String searchedDataSchemaName) {
assertNotNull("Module is missing", module);
DataSchemaNode dataSchemaNode = null;
return dataSchemaNode;
}
- static String writeCompNodeWithSchemaContextToJson(CompositeNode compositeNode, String outputPath,
- Set<Module> modules, DataSchemaNode dataSchemaNode) throws IOException, WebApplicationException {
+ public static String writeCompNodeWithSchemaContextToJson(CompositeNode compositeNode, Set<Module> modules,
+ DataSchemaNode dataSchemaNode) throws IOException, WebApplicationException {
String jsonResult;
assertNotNull(dataSchemaNode);
assertNotNull("Composite node can't be null", compositeNode);
ByteArrayOutputStream byteArrayOS = new ByteArrayOutputStream();
- ControllerContext contContext = ControllerContext.getInstance();
- contContext.setSchemas(loadSchemaContext(modules));
+ ControllerContext.getInstance().setSchemas(loadSchemaContext(modules));
StructuredDataToJsonProvider structuredDataToJsonProvider = StructuredDataToJsonProvider.INSTANCE;
structuredDataToJsonProvider.writeTo(new StructuredData(compositeNode, dataSchemaNode), null, null, null, null,
null, byteArrayOS);
jsonResult = byteArrayOS.toString();
- if (outputPath != null) {
- try {
- outputToFile(byteArrayOS, outputPath);
- } catch (IOException e) {
- System.out.println("Output file wasn't cloased sucessfuly.");
- }
- }
return jsonResult;
}
- static CompositeNode loadCompositeNode(String xmlDataPath) {
- InputStream xmlStream = ToJsonBasicDataTypesTest.class.getResourceAsStream(xmlDataPath);
+ public static CompositeNode loadCompositeNode(String xmlDataPath) {
+ InputStream xmlStream = TestUtils.class.getResourceAsStream(xmlDataPath);
CompositeNode compositeNode = null;
try {
- compositeNode = TestUtils.loadCompositeNode(xmlStream);
- } catch (FileNotFoundException e) {
+ XmlReader xmlReader = new XmlReader();
+ compositeNode = xmlReader.read(xmlStream);
+
+ } catch (UnsupportedFormatException | XMLStreamException e) {
e.printStackTrace();
}
return compositeNode;
static void outputToFile(ByteArrayOutputStream outputStream, String outputDir) throws IOException {
FileOutputStream fileOS = null;
try {
- String path = ToJsonBasicDataTypesTest.class.getResource(outputDir).getPath();
+ String path = TestUtils.class.getResource(outputDir).getPath();
File outFile = new File(path + "/data.json");
fileOS = new FileOutputStream(outFile);
try {
}
private static FileReader getFileReader(String path) {
- String fullPath = ToJsonBasicDataTypesTest.class.getResource(path).getPath();
+ String fullPath = TestUtils.class.getResource(path).getPath();
assertNotNull("Path to file can't be null.", fullPath);
File file = new File(fullPath);
assertNotNull("File can't be null", file);
return strBuilder.toString();
}
- static QName buildQName(String name, String uri, String date) {
+ public static QName buildQName(String name, String uri, String date) {
try {
URI u = new URI(uri);
Date dt = null;
}
}
- static QName buildQName(String name) {
+ public static QName buildQName(String name) {
return buildQName(name, "", null);
}
- static void supplementNamespace(DataSchemaNode dataSchemaNode, CompositeNode compositeNode) {
+ public static void supplementNamespace(DataSchemaNode dataSchemaNode, CompositeNode compositeNode) {
RestconfImpl restconf = RestconfImpl.getInstance();
InstanceIdWithSchemaNode instIdAndSchema = new InstanceIdWithSchemaNode(mock(InstanceIdentifier.class),
restconf.createConfigurationData("something", compositeNode);
}
- static DataSchemaNode obtainSchemaFromYang(String yangFolder) throws FileNotFoundException {
+ public static DataSchemaNode obtainSchemaFromYang(String yangFolder) throws FileNotFoundException {
return obtainSchemaFromYang(yangFolder, null);
}
- static DataSchemaNode obtainSchemaFromYang(String yangFolder, String moduleName) throws FileNotFoundException {
+ public static DataSchemaNode obtainSchemaFromYang(String yangFolder, String moduleName)
+ throws FileNotFoundException {
Set<Module> modules = null;
- modules = TestUtils.loadModules(ToJsonBasicDataTypesTest.class.getResource(yangFolder).getPath());
+ modules = TestUtils.loadModules(TestUtils.class.getResource(yangFolder).getPath());
if (modules == null) {
return null;
}
- static void addDummyNamespaceToAllNodes(NodeWrapper<?> wrappedNode) throws URISyntaxException {
+ public static void addDummyNamespaceToAllNodes(NodeWrapper<?> wrappedNode) throws URISyntaxException {
wrappedNode.setNamespace(new URI(""));
if (wrappedNode instanceof CompositeNodeWrapper) {
for (NodeWrapper<?> childNodeWrapper : ((CompositeNodeWrapper) wrappedNode).getValues()) {
}
}
+ public static void prepareMockForRestconfBeforeNormalization(Set<Module> modules, DataSchemaNode dataSchemaNode,
+ RestconfImpl restconf) {
+ ControllerContext instance = ControllerContext.getInstance();
+ instance.setSchemas(TestUtils.loadSchemaContext(modules));
+ restconf.setControllerContext(ControllerContext.getInstance());
+
+ BrokerFacade mockedBrokerFacade = mock(BrokerFacade.class);
+ when(mockedBrokerFacade.commitConfigurationDataPut(any(InstanceIdentifier.class), any(CompositeNode.class)))
+ .thenReturn(
+ new DummyFuture.Builder().rpcResult(
+ new DummyRpcResult.Builder<TransactionStatus>().result(TransactionStatus.COMMITED)
+ .build()).build());
+ restconf.setBroker(mockedBrokerFacade);
+ }
+
+ static CompositeNode loadCompositeNodeWithXmlTreeBuilder(String xmlDataPath) {
+ InputStream xmlStream = TestUtils.class.getResourceAsStream(xmlDataPath);
+ CompositeNode compositeNode = null;
+ try {
+ compositeNode = TestUtils.loadCompositeNodeWithXmlTreeBuilder(xmlStream);
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ }
+ return compositeNode;
+
+
+
+ }
+
+
+ public static CompositeNode loadCompositeNodeWithXmlTreeBuilder(InputStream xmlInputStream) throws FileNotFoundException {
+ if (xmlInputStream == null) {
+ throw new IllegalArgumentException();
+ }
+ Node<?> dataTree;
+ try {
+ dataTree = XmlTreeBuilder.buildDataTree(xmlInputStream);
+ } catch (XMLStreamException e) {
+ logger.error("Error during building data tree from XML", e);
+ return null;
+ }
+ if (dataTree == null) {
+ logger.error("data tree is null");
+ return null;
+ }
+ if (dataTree instanceof SimpleNode) {
+ logger.error("RPC XML was resolved as SimpleNode");
+ return null;
+ }
+ return (CompositeNode) dataTree;
+ }
+
}
+++ /dev/null
-package org.opendaylight.controller.sal.restconf.impl.test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import java.io.*;
-import java.util.*;
-
-import org.junit.Test;
-
-import com.google.gson.stream.*;
-
-public class ToJsonBasicDataTypesTest {
-
- @Test
- public void simpleYangDataTest() {
- String jsonOutput;
- jsonOutput = TestUtils.convertCompositeNodeDataAndYangToJson(
- TestUtils.loadCompositeNode("/yang-to-json-conversion/simple-data-types/xml/data.xml"),
- "/yang-to-json-conversion/simple-data-types", "/yang-to-json-conversion/simple-data-types/xml");
- verifyJsonOutput(jsonOutput);
- }
-
- private void verifyJsonOutput(String jsonOutput) {
- StringReader strReader = new StringReader(jsonOutput);
- JsonReader jReader = new JsonReader(strReader);
-
- String exception = null;
- try {
- jsonReadCont(jReader);
- } catch (IOException e) {
- exception = e.getMessage();
- }
-
- assertNull("Error during reading Json output: " + exception, exception);
- }
-
- private void jsonReadCont(JsonReader jReader) throws IOException {
- jReader.beginObject();
- assertNotNull("cont1 is missing.", jReader.hasNext());
-
- // Cont dataFromJson = new Cont(jReader.nextName());
- jReader.nextName();
- jsonReadContElements(jReader);
-
- assertFalse("cont shouldn't have other element.", jReader.hasNext());
- jReader.endObject();
- // return dataFromJson;
- }
-
- private void jsonReadContElements(JsonReader jReader) throws IOException {
- jReader.beginObject();
- List<String> loadedLfs = new ArrayList<>();
- boolean exceptForDecimal5Raised = false;
- boolean enumChecked = false;
- boolean bitsChecked = false;
- boolean lfdecimal6Checked = false;
- boolean lfdecimal4Checked = false;
- boolean lfdecimal3Checked = false;
- boolean lfdecimal2Checked = false;
- boolean lfdecimal1Checked = false;
- boolean lfbool1Checked = false;
- boolean lfbool2Checked = false;
- boolean lfstrChecked = false;
- boolean lfbinaryChecked = false;
- // boolean lfref1Checked = false;
- boolean lfemptyChecked = false;
- boolean lfstr1Checked = false;
-
- while (jReader.hasNext()) {
- String keyName = jReader.nextName();
- JsonToken peek = null;
- try {
- peek = jReader.peek();
- } catch (IOException e) {
- if (keyName.equals("lfdecimal5")) {
- exceptForDecimal5Raised = true;
- } else {
- assertTrue("Key " + keyName + " has incorrect value for specifed type", false);
- }
- }
-
- if (keyName.startsWith("lfnint") || keyName.startsWith("lfnuint")) {
- assertEquals("Key " + keyName + " has incorrect type", JsonToken.NUMBER, peek);
- try {
- jReader.nextLong();
- } catch (NumberFormatException e) {
- assertTrue("Key " + keyName + " has incorrect value - " + e.getMessage(), false);
- }
- loadedLfs.add(keyName.substring(3));
- } else if (keyName.equals("lfstr")) {
- assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
- assertEquals("lfstr", jReader.nextString());
- lfstrChecked = true;
- } else if (keyName.equals("lfstr1")) {
- assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
- assertEquals("", jReader.nextString());
- lfstr1Checked = true;
- } else if (keyName.equals("lfbool1")) {
- assertEquals("Key " + keyName + " has incorrect type", JsonToken.BOOLEAN, peek);
- assertEquals(true, jReader.nextBoolean());
- lfbool1Checked = true;
- } else if (keyName.equals("lfbool2")) {
- assertEquals("Key " + keyName + " has incorrect type", JsonToken.BOOLEAN, peek);
- assertEquals(false, jReader.nextBoolean());
- lfbool2Checked = true;
- } else if (keyName.equals("lfbool3")) {
- assertEquals("Key " + keyName + " has incorrect type", JsonToken.BOOLEAN, peek);
- assertEquals(false, jReader.nextBoolean());
- } else if (keyName.equals("lfdecimal1")) {
- assertEquals("Key " + keyName + " has incorrect type", JsonToken.NUMBER, peek);
- assertEquals(new Double(43.32), (Double) jReader.nextDouble());
- lfdecimal1Checked = true;
- } else if (keyName.equals("lfdecimal2")) {
- assertEquals("Key " + keyName + " has incorrect type", JsonToken.NUMBER, peek);
- assertEquals(new Double(-0.43), (Double) jReader.nextDouble());
- lfdecimal2Checked = true;
- } else if (keyName.equals("lfdecimal3")) {
- assertEquals("Key " + keyName + " has incorrect type", JsonToken.NUMBER, peek);
- assertEquals(new Double(43), (Double) jReader.nextDouble());
- lfdecimal3Checked = true;
- } else if (keyName.equals("lfdecimal4")) {
- assertEquals("Key " + keyName + " has incorrect type", JsonToken.NUMBER, peek);
- assertEquals(new Double(43E3), (Double) jReader.nextDouble());
- lfdecimal4Checked = true;
- } else if (keyName.equals("lfdecimal6")) {
- assertEquals("Key " + keyName + " has incorrect type", JsonToken.NUMBER, peek);
- assertEquals(new Double(33.12345), (Double) jReader.nextDouble());
- lfdecimal6Checked = true;
- } else if (keyName.equals("lfenum")) {
- assertEquals("enum3", jReader.nextString());
- enumChecked = true;
- } else if (keyName.equals("lfbits")) {
- assertEquals("bit3", jReader.nextString());
- bitsChecked = true;
- } else if (keyName.equals("lfbinary")) {
- assertEquals("AAaacdabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ%%-#^", jReader.nextString());
- lfbinaryChecked = true;
- } else if (keyName.equals("lfempty")) {
- jReader.beginArray();
- jReader.nextNull();
- jReader.endArray();
- lfemptyChecked = true;
- } else if (keyName.startsWith("lfunion")) {
- checkLfUnion(jReader, keyName, peek);
- } else {
- assertTrue("Key " + keyName + " doesn't exists in yang file.", false);
- }
-
- }
- Collections.sort(loadedLfs);
- String expectedLfsStr = "[int16Max, int16Min, int32Max, int32Min, int64Max, int64Min, int8Max, int8Min, uint16Max, uint32Max, uint8Max]";
- String actualLfsStr = loadedLfs.toString();
- assertEquals("Some leaves are missing", expectedLfsStr, actualLfsStr);
- // assertTrue("For lfdecimal5 wasn't catch error",exceptForDecimal5Raised);
- assertTrue("Enum wasn't checked", enumChecked);
- assertTrue("Bits wasn't checked", bitsChecked);
- assertTrue("Decimal1 wasn't checked", lfdecimal1Checked);
- assertTrue("Decimal2 wasn't checked", lfdecimal2Checked);
- assertTrue("Decimal3 wasn't checked", lfdecimal3Checked);
- assertTrue("Decimal4 wasn't checked", lfdecimal4Checked);
- assertTrue("Decimal5 wasn't checked", lfdecimal6Checked);
- assertTrue("lfbool1 wasn't checked", lfbool1Checked);
- assertTrue("lfbool2 wasn't checked", lfbool2Checked);
- assertTrue("lfstr wasn't checked", lfstrChecked);
- assertTrue("lfstr1 wasn't checked", lfstr1Checked);
- assertTrue("lfbinary wasn't checked", lfbinaryChecked);
- assertTrue("lfempty wasn't checked", lfemptyChecked);
- // assertTrue("lfref1 wasn't checked", lfref1Checked);
-
- jReader.endObject();
-
- }
-
- private void checkLfUnion(JsonReader jReader, String keyName, JsonToken peek) throws IOException {
- if (keyName.equals("lfunion1")) {
- assertEquals("Key " + keyName + " has incorrect type", JsonToken.NUMBER, peek);
- jReader.nextString();
- } else if (keyName.equals("lfunion2")) {
- assertEquals("Key " + keyName + " has incorrect type", JsonToken.NUMBER, peek);
- jReader.nextString();
- } else if (keyName.equals("lfunion3")) {
- assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
- jReader.nextInt();
- } else if (keyName.equals("lfunion4")) {
- assertEquals("Key " + keyName + " has incorrect type", JsonToken.BOOLEAN, peek);
- jReader.nextBoolean();
- } else if (keyName.equals("lfunion5")) {
- assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
- jReader.nextString();
- } else if (keyName.equals("lfunion6")) {
- assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
- jReader.nextString();
- } else if (keyName.equals("lfunion7")) {
- assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
- jReader.nextString();
- } else if (keyName.equals("lfunion8")) {
- assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
- jReader.nextString();
- } else if (keyName.equals("lfunion9")) {
- assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
- jReader.nextString();
- } else if (keyName.equals("lfunion10")) {
- assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
- jReader.nextString();
- } else if (keyName.equals("lfunion11")) {
- assertEquals("Key " + keyName + " has incorrect type", JsonToken.NUMBER, peek);
- jReader.nextString();
- } else if (keyName.equals("lfunion12")) {
- assertEquals("Key " + keyName + " has incorrect type", JsonToken.BOOLEAN, peek);
- jReader.nextBoolean();
- }
- }
-}
+++ /dev/null
-package org.opendaylight.controller.sal.restconf.impl.test;
-
-import static org.junit.Assert.assertTrue;
-
-import java.io.IOException;
-
-import javax.ws.rs.WebApplicationException;
-
-import org.junit.*;
-
-public class ToJsonChoiceCaseTest extends YangAndXmlAndDataSchemaLoader {
-
- @BeforeClass
- public static void initialization() {
- dataLoad("/yang-to-json-conversion/choice");
- }
-
- /**
- * Test when some data are in one case node and other in another. This isn't
- * correct. Next Json validator should return error because nodes has to be
- * from one case below concrete choice.
- *
- */
- @Test
- public void nodeSchemasOnVariousChoiceCasePathTest() {
- try {
- TestUtils.writeCompNodeWithSchemaContextToJson(
- TestUtils.loadCompositeNode("/yang-to-json-conversion/choice/xml/data_various_path_err.xml"),
- "/yang-to-json-conversion/choice/xml", modules, dataSchemaNode);
- } catch (WebApplicationException | IOException e) {
- // shouldn't end here
- assertTrue(false);
- }
- }
-
- /**
- * Test when some data are in one case node and other in another.
- * Additionally data are loadef from various choices. This isn't correct.
- * Next Json validator should return error because nodes has to be from one
- * case below concrete choice.
- *
- */
- @Test
- public void nodeSchemasOnVariousChoiceCasePathAndMultipleChoicesTest() {
- try {
- TestUtils
- .writeCompNodeWithSchemaContextToJson(
- TestUtils
- .loadCompositeNode("/yang-to-json-conversion/choice/xml/data_more_choices_same_level_various_paths_err.xml"),
- "/yang-to-json-conversion/choice/xml", modules, dataSchemaNode);
- } catch (WebApplicationException | IOException e) {
- // shouldn't end here
- assertTrue(false);
- }
- }
-
- /**
- * Test when second level data are red first, then first and at the end
- * third level. Level represents pass through couple choice-case
- */
-
- @Test
- public void nodeSchemasWithRandomOrderAccordingLevel() {
- try {
- TestUtils.writeCompNodeWithSchemaContextToJson(
- TestUtils.loadCompositeNode("/yang-to-json-conversion/choice/xml/data_random_level.xml"),
- "/yang-to-json-conversion/choice/xml", modules, dataSchemaNode);
-
- } catch (WebApplicationException | IOException e) {
- // shouldn't end here
- assertTrue(false);
- }
- }
-
- /**
- * Test when element from no first case is used
- */
- @Test
- public void nodeSchemasNotInFirstCase() {
- try {
- TestUtils.writeCompNodeWithSchemaContextToJson(
- TestUtils.loadCompositeNode("/yang-to-json-conversion/choice/xml/data_no_first_case.xml"),
- "/yang-to-json-conversion/choice/xml", modules, dataSchemaNode);
- } catch (WebApplicationException | IOException e) {
- // shouldn't end here
- assertTrue(false);
- }
- }
-
- /**
- * Test when element in case is list
- */
- @Test
- public void nodeSchemaAsList() {
- try {
- TestUtils.writeCompNodeWithSchemaContextToJson(
- TestUtils.loadCompositeNode("/yang-to-json-conversion/choice/xml/data_list.xml"),
- "/yang-to-json-conversion/choice/xml", modules, dataSchemaNode);
- } catch (WebApplicationException | IOException e) {
- // shouldn't end here
- assertTrue(false);
- }
- }
-
- /**
- * Test when element in case is container
- */
- @Test
- public void nodeSchemaAsContainer() {
- try {
- TestUtils.writeCompNodeWithSchemaContextToJson(
- TestUtils.loadCompositeNode("/yang-to-json-conversion/choice/xml/data_container.xml"),
- "/yang-to-json-conversion/choice/xml", modules, dataSchemaNode);
- } catch (WebApplicationException | IOException e) {
- // shouldn't end here
- assertTrue(false);
- }
- }
-
- /**
- * Test when element in case is leaflist
- */
- @Test
- public void nodeSchemaAsLeafList() {
- try {
- TestUtils.writeCompNodeWithSchemaContextToJson(
- TestUtils.loadCompositeNode("/yang-to-json-conversion/choice/xml/data_leaflist.xml"),
- "/yang-to-json-conversion/choice/xml", modules, dataSchemaNode);
- } catch (WebApplicationException | IOException e) {
- // shouldn't end here
- assertTrue(false);
- }
- }
-
- /**
- *
- */
- @Test
- public void nodeSchemasInMultipleChoicesTest() {
- try {
- TestUtils
- .writeCompNodeWithSchemaContextToJson(TestUtils
- .loadCompositeNode("/yang-to-json-conversion/choice/xml/data_more_choices_same_level.xml"),
- "/yang-to-json-conversion/choice/xml", modules, dataSchemaNode);
- } catch (WebApplicationException | IOException e) {
- // shouldn't end here
- assertTrue(false);
- }
- }
-
- /**
- * Test whether is possible to find data schema for node which is specified
- * as dirrect subnode of choice (case without CASE key word)
- */
- @Test
- public void nodeSchemasInCaseNotDefinedWithCaseKeyword() {
- try {
- TestUtils.writeCompNodeWithSchemaContextToJson(TestUtils
- .loadCompositeNode("/yang-to-json-conversion/choice/xml/data_case_defined_without_case.xml"),
- "/yang-to-json-conversion/choice/xml", modules, dataSchemaNode);
- } catch (WebApplicationException | IOException e) {
- // shouldn't end here
- assertTrue(false);
- }
- }
-
- /**
- * Test of multiple use of choices
- */
- @Test
- public void nodeSchemasInThreeChoicesAtSameLevel() {
- try {
- TestUtils.writeCompNodeWithSchemaContextToJson(TestUtils
- .loadCompositeNode("/yang-to-json-conversion/choice/xml/data_three_choices_same_level.xml"),
- "/yang-to-json-conversion/choice/xml", modules, dataSchemaNode);
- } catch (WebApplicationException | IOException e) {
- // shouldn't end here
- assertTrue(false);
- }
- }
-}
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLEncoder;
-import java.util.List;
-import java.util.Set;
+import java.util.*;
import java.util.concurrent.Future;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import org.opendaylight.controller.sal.rest.api.RestconfService;
import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider;
import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
-import org.opendaylight.controller.sal.restconf.impl.BrokerFacade;
-import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
-import org.opendaylight.controller.sal.restconf.impl.RestconfImpl;
+import org.opendaylight.controller.sal.restconf.impl.*;
import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.*;
+import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
import org.opendaylight.yangtools.yang.model.api.Module;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
public void testStructuredDataToXmlProvider() throws FileNotFoundException, UnsupportedEncodingException {
String uri = createUri("/datastore/", "ietf-interfaces:interfaces/interface/eth0");
- InputStream xmlStream = RestconfImplTest.class.getResourceAsStream("/parts/ietf-interfaces_interfaces.xml");
- CompositeNode loadedCompositeNode = TestUtils.loadCompositeNode(xmlStream);
+ CompositeNode loadedCompositeNode = prepareCompositeNodeWithIetfInterfacesInterfacesData();
when(brokerFacade.readOperationalData(any(InstanceIdentifier.class))).thenReturn(loadedCompositeNode);
Response response = target(uri).request(MEDIA_TYPE).get();
assertEquals(200, response.getStatus());
}
+ private CompositeNode prepareCompositeNodeWithIetfInterfacesInterfacesData() {
+ CompositeNode intface;
+ try {
+ intface = new CompositeNodeWrapper(new URI("interface"), "interface");
+ List<Node<?>> childs = new ArrayList<>();
+
+ childs.add(new SimpleNodeWrapper(new URI("name"), "name", "eth0"));
+ childs.add(new SimpleNodeWrapper(new URI("type"), "type", "ethernetCsmacd"));
+ childs.add(new SimpleNodeWrapper(new URI("enabled"), "enabled", Boolean.FALSE));
+ childs.add(new SimpleNodeWrapper(new URI("description"), "description", "some interface"));
+ intface.setValue(childs);
+ return intface;
+ } catch (URISyntaxException e) {
+ }
+
+ return null;
+ }
+
@Test
public void testBadFormatXmlToCompositeNodeProvider() throws UnsupportedEncodingException, URISyntaxException {
String uri = createUri("/operations/", "ietf-interfaces:interfaces/interface/eth0");
package org.opendaylight.controller.sal.restconf.impl.test.structures;
public class Lf extends YangElement {
- private String value;
+ private Object value;
private int numOfEqualItems = 0;
-
- public Lf(String name, String value) {
+ public Lf(String name, Object value) {
super(name);
this.value = value;
}
- public Lf(String value) {
+ public Lf(Object value) {
super("");
this.value = value;
}
- public String getValue() {
+ public Object getValue() {
return value;
}
}
return true;
}
-
+
public void incNumOfEqualItems() {
this.numOfEqualItems++;
}
-
@Override
public int hashCode() {
package org.opendaylight.controller.sal.restconf.impl.test.structures;
-import java.util.*;
+import java.util.HashSet;
+import java.util.Set;
public class LfLst extends YangElement {
Set<Lf> lfs;
lfs = new HashSet<>();
}
- public LfLst addLf(String value) {
+ public LfLst addLf(Object value) {
return addLf(new Lf(value));
}
-
public LfLst addLf(Lf lf) {
while (this.lfs.contains(lf)) {
lf.incNumOfEqualItems();
package org.opendaylight.controller.sal.restconf.impl.test.structures;
-import java.util.*;
+import java.util.HashMap;
+import java.util.Map;
public class LstItem {
String lstName;
return this;
}
- public LstItem addLf(String name, String value) {
+ public LstItem addLf(String name, Object value) {
lfs.put(name, new Lf(name, value));
return this;
}
-package org.opendaylight.controller.sal.restconf.impl.test;
+package org.opendaylight.controller.sal.restconf.impl.xml.to.cnsn.test;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.*;
import java.io.*;
import java.net.URISyntaxException;
+import java.util.List;
+import java.util.Set;
import javax.ws.rs.WebApplicationException;
-import org.junit.*;
+import org.junit.Test;
import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
-import org.opendaylight.controller.sal.restconf.impl.*;
+import org.opendaylight.controller.sal.restconf.impl.CompositeNodeWrapper;
+import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
+import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.*;
import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.slf4j.*;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
-public class FromXmlToCompositeNodeTest {
- private static final Logger LOG = LoggerFactory.getLogger(FromXmlToCompositeNodeTest.class);
+public class XmlToCnSnTest {
+ private static final Logger LOG = LoggerFactory.getLogger(XmlToCnSnTest.class);
/**
* top level element represents container. second level element is list with
*/
@Test
public void testXmlDataContainer() {
- CompositeNode compNode = compositeContainerFromXml("/xml-to-composite-node/data-container.xml", false);
+ CompositeNode compNode = compositeNodeFromXml("/xml-to-cnsn/data-container.xml", false);
assertNotNull(compNode);
DataSchemaNode dataSchemaNode = null;
try {
- dataSchemaNode = TestUtils.obtainSchemaFromYang("/xml-to-composite-node/data-container-yang");
+ dataSchemaNode = TestUtils.obtainSchemaFromYang("/xml-to-cnsn/data-container-yang");
} catch (FileNotFoundException e) {
LOG.error(e.getMessage());
assertTrue(false);
@Test
public void testXmlDataList() {
- CompositeNode compNode = compositeContainerFromXml("/xml-to-composite-node/data-list.xml", false);
+ CompositeNode compNode = compositeNodeFromXml("/xml-to-cnsn/data-list.xml", false);
assertNotNull(compNode);
DataSchemaNode dataSchemaNode = null;
try {
- dataSchemaNode = TestUtils.obtainSchemaFromYang("/xml-to-composite-node/data-list-yang",
- "data-container-yang");
+ dataSchemaNode = TestUtils.obtainSchemaFromYang("/xml-to-cnsn/data-list-yang", "data-container-yang");
} catch (FileNotFoundException e) {
LOG.error(e.getMessage());
}
@Test
public void testXmlEmptyData() {
- CompositeNode compNode = compositeContainerFromXml("/xml-to-composite-node/empty-data.xml", true);
+ CompositeNode compNode = compositeNodeFromXml("/xml-to-cnsn/empty-data.xml", true);
assertEquals("cont", compNode.getNodeType().getLocalName());
SimpleNode<?> lf1 = null;
SimpleNode<?> lflst1_1 = null;
}
+ /**
+ * Test case like this <lf11 xmlns:x="namespace">x:identity</lf11>
+ */
+ @Test
+ public void testIdentityrefNmspcInElement() {
+ testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-nmspc-in-element.xml", "/xml-to-cnsn/identityref",
+ "identityref-module", "cont", 2, "iden", "identity:module");
+ }
+
+ /**
+ *
+ * Test case like <lf11 xmlns="namespace1"
+ * xmlns:x="namespace">identity</lf11>
+ */
+
+ @Test
+ public void testIdentityrefDefaultNmspcInElement() {
+ testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-default-nmspc-in-element.xml",
+ "/xml-to-cnsn/identityref/yang-augments", "general-module", "cont", 3, "iden", "identityref:module");
+ }
+
+ /**
+ *
+ * Test case like <cont1 xmlns="namespace1"> <lf11
+ * xmlns:x="namespace">identity</lf11> </cont1>
+ */
+ @Test
+ public void testIdentityrefDefaultNmspcInParrentElement() {
+ testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-default-nmspc-in-parrent-element.xml",
+ "/xml-to-cnsn/identityref", "identityref-module", "cont", 2, "iden", "identityref:module");
+ }
+
+ /**
+ *
+ * Test case like <cont1 xmlns="namespace1" xmlns:x="namespace">
+ * <lf11>x:identity</lf11> </cont1>
+ */
+ @Test
+ public void testIdentityrefNmspcInParrentElement() {
+ testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-nmspc-in-parrent-element.xml",
+ "/xml-to-cnsn/identityref", "identityref-module", "cont", 2, "iden", "z:namespace");
+
+ }
+
+ /**
+ *
+ * Test case like (without namespace in xml) <cont1> <lf11>x:identity</lf11>
+ * </cont1>
+ */
+ @Test
+ public void testIdentityrefNoNmspcValueWithPrefix() {
+ testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-no-nmspc-value-with-prefix.xml",
+ "/xml-to-cnsn/identityref", "identityref-module", "cont", 2, "x:iden", "identityref:module");
+ }
+
+ /**
+ *
+ * Test case like (without namespace in xml) <cont1> <lf11>identity</lf11>
+ * </cont1>
+ */
+ @Test
+ public void testIdentityrefNoNmspcValueWithoutPrefix() {
+ testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-no-nmspc-value-without-prefix.xml",
+ "/xml-to-cnsn/identityref", "identityref-module", "cont", 2, "iden", "identityref:module");
+ }
+
private void verifyCommonPartAOfXml(CompositeNode compNode, String suf, String nameSpace) {
SimpleNode<?> lf1suf = null;
SimpleNode<?> lflst1suf_1 = null;
assertEquals((short) 100, cont1_lf11.getValue());
}
- private CompositeNode compositeContainerFromXml(String xmlPath, boolean dummyNamespaces) {
+ private CompositeNode compositeNodeFromXml(String xmlPath, boolean dummyNamespaces) {
XmlToCompositeNodeProvider xmlToCompositeNodeProvider = XmlToCompositeNodeProvider.INSTANCE;
try {
- InputStream xmlStream = FromXmlToCompositeNodeTest.class.getResourceAsStream(xmlPath);
+ InputStream xmlStream = XmlToCnSnTest.class.getResourceAsStream(xmlPath);
CompositeNode compositeNode = xmlToCompositeNodeProvider.readFrom(null, null, null, null, null, xmlStream);
if (dummyNamespaces) {
try {
return null;
}
+ private void testIdentityrefToCnSn(String xmlPath, String yangPath, String moduleName, String schemaName,
+ int moduleCount, String resultLocalName, String resultNamespace) {
+ CompositeNode compositeNode = compositeNodeFromXml(xmlPath, false);
+ assertNotNull(compositeNode);
+
+ Set<Module> modules = TestUtils.resolveModules(yangPath);
+ assertEquals(moduleCount, modules.size());
+ Module module = TestUtils.resolveModule(moduleName, modules);
+ assertNotNull(module);
+ DataSchemaNode dataSchemaNode = TestUtils.resolveDataSchemaNode(module, null);
+ assertNotNull(dataSchemaNode);
+
+ TestUtils.normalizeCompositeNode(compositeNode, modules, dataSchemaNode, moduleName + ":" + schemaName);
+
+ SimpleNode<?> lf11 = getLf11(compositeNode);
+ assertTrue(lf11.getValue() instanceof QName);
+ QName qName = (QName) lf11.getValue();
+ assertEquals(resultLocalName, qName.getLocalName());
+ assertEquals(resultNamespace, qName.getNamespace().toString());
+
+ }
+
+ private SimpleNode<?> getLf11(CompositeNode compositeNode) {
+ assertEquals("cont", compositeNode.getNodeType().getLocalName());
+
+ List<Node<?>> childs = compositeNode.getChildren();
+ assertEquals(1, childs.size());
+ Node<?> nd = childs.iterator().next();
+ assertTrue(nd instanceof CompositeNode);
+ assertEquals("cont1", nd.getNodeType().getLocalName());
+
+ childs = ((CompositeNode) nd).getChildren();
+ SimpleNode<?> lf11 = null;
+ for (Node<?> child : childs) {
+ assertTrue(child instanceof SimpleNode);
+ if (child.getNodeType().getLocalName().equals("lf11")) {
+ lf11 = (SimpleNode<?>) child;
+ }
+ }
+ assertNotNull(lf11);
+ return lf11;
+ }
+
}
--- /dev/null
+module identityref-module {
+ namespace "identityref:module";
+
+ prefix "iderefmod";
+
+ import identity-module {prefix idemo; revision-date 2013-12-2;}
+
+ revision 2013-12-2 {
+ }
+
+ container cont {
+ container cont1 {
+ leaf lf1 {
+ type identityref {
+ base "idemo:iden";
+ }
+ }
+ }
+ }
+
+}
\ No newline at end of file
revision 2013-11-12 {
}
+ identity iden {
+ }
+
typedef tpdfempty {
type empty;
}
leaf lfunion12 {
type tpdfun2;
}
+
+ leaf lfunion13 {
+ type tpdfbit;
+ }
+
+ leaf lfunion14 {
+ type union {
+ type enumeration {
+ enum zero;
+ enum one;
+ }
+ type uint16;
+ }
+ }
+
+ leaf identityref1 {
+ type identityref {
+ base iden;
+ }
+ }
}
<lfdecimal4>43E3</lfdecimal4>
<lfdecimal6>33.12345</lfdecimal6>
<lfenum>enum3</lfenum>
- <lfbits>bit3</lfbits>
- <lfbinary>AAaacdabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ%%-#^</lfbinary>
- <lfempty></lfempty>
+ <lfbits>bit3 bit2</lfbits>
+ <lfbinary>ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz</lfbinary>
+ <lfempty />
<lfunion1>324</lfunion1>
<lfunion2>33.3</lfunion2>
<lfunion3>55</lfunion3>
<lfunion10>bt1</lfunion10>
<lfunion11>33</lfunion11>
<lfunion12>false</lfunion12>
+ <lfunion13>44</lfunion13>
+ <lfunion14>21</lfunion14>
+ <lfempty />
+ <identityref1 xmlns:x="simple:data:types">x:iden</identityref1>
</cont>
\ No newline at end of file
--- /dev/null
+module aug-referenced-elements-module {
+ namespace "aug:referenced:elements:module";
+
+ prefix "augrefelmo";
+
+ import referenced-elements-module {prefix refelmo; revision-date 2013-12-3;}
+
+ revision 2013-12-3 {
+ }
+
+ augment "/refelmo:cont" {
+ leaf lf2 {
+ type boolean;
+ }
+ }
+
+
+}
\ No newline at end of file
--- /dev/null
+module referenced-elements-module {
+ namespace "referenced:elements:module";
+
+ prefix "refelmo";
+
+ revision 2013-12-3 {
+ }
+
+ container cont {
+ leaf lf1 {
+ type string;
+ }
+ }
+ leaf-list lflst1 {
+ type uint32;
+ }
+
+ }
+
+}
\ No newline at end of file
--- /dev/null
+module instance-identifier-module {
+ namespace "instance:identifier:module";
+
+ prefix "inidmod";
+
+ revision 2013-12-3 {
+ }
+
+ container cont {
+ leaf lf1 {
+ type instance-identifier {
+ }
+ }
+ }
+
+}
\ No newline at end of file
--- /dev/null
+module basic-module {
+ namespace "basic:module";
+
+ prefix "basmod";
+
+ import referenced-module {prefix refmo; revision-date 2013-12-2;}
+
+ revision 2013-12-2 {
+ }
+
+ container cont {
+ container cont1 {
+ leaf lf11 {
+ type identityref {
+ base "refmo:iden";
+ }
+ }
+ }
+ leaf lfStr {
+ type string;
+ }
+ leaf lfInt8 {
+ type int8;
+ }
+
+ leaf lfInt16 {
+ type int16;
+ }
+
+ leaf lfInt32 {
+ type int32;
+ }
+
+ leaf lfInt64 {
+ type int64;
+ }
+
+ leaf lfUint8 {
+ type uint8;
+ }
+
+ leaf lfUint16 {
+ type uint16;
+ }
+
+ leaf lfUint32 {
+ type uint32;
+ }
+
+ leaf lfUint64 {
+ type uint64;
+ }
+
+ leaf lfBinary {
+ type binary;
+ }
+
+ leaf lfBits {
+ type bits {
+ bit one;
+ bit two;
+ bit three;
+ }
+ }
+
+ leaf lfEnumeration {
+ type enumeration {
+ enum enum1;
+ enum enum2;
+ enum enum3;
+ }
+ }
+
+ leaf lfEmpty {
+ type empty;
+ }
+
+ leaf lfBoolean {
+ type boolean;
+ }
+
+ leaf lfUnion {
+ type union {
+ type int8;
+ type string;
+ type bits {
+ bit first;
+ bit second;
+ }
+ type boolean;
+ }
+ }
+
+ }
+
+}
\ No newline at end of file
--- /dev/null
+module referenced-module {
+ namespace "referenced:module";
+
+ prefix "refmod";
+ revision 2013-12-2 {
+ }
+
+ identity iden {
+ }
+}
\ No newline at end of file
--- /dev/null
+module identity-module {
+ namespace "identity:module";
+
+ prefix "idemod";
+ revision 2013-12-2 {
+ }
+
+ identity iden {
+ }
+}
\ No newline at end of file
--- /dev/null
+module identityref-module {
+ namespace "identityref:module";
+
+ prefix "iderefmod";
+
+ import identity-module {prefix idemo; revision-date 2013-12-2;}
+
+ revision 2013-12-2 {
+ }
+
+ identity iden_local {
+ }
+
+ container cont {
+ container cont1 {
+ leaf lf11 {
+ type identityref {
+ base "idemo:iden";
+ }
+ }
+ leaf lf12 {
+ type identityref {
+ base "iden_local";
+ }
+ }
+ leaf lf13 {
+ type identityref {
+ base "iden_local";
+ }
+ }
+ leaf lf14 {
+ type identityref {
+ base "iden_local";
+ }
+ }
+ }
+ }
+
+}
\ No newline at end of file
--- /dev/null
+{
+ "cont":{
+ "cont1":{
+ "lf11":"identity-module:iden",
+ "lf12":"iden_local",
+ "identityref-module:lf13":"iden_local",
+ "identityref-module:lf14":"identity-module:iden_local"
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+<cont xmlns:x="x:namespace" xmlns:y="y:namespace">
+ <cont1 xmlns:z="z:namespace" xmlns:a="a:namespace" xmlns:b="b:namespace">
+ <lf11 xmlns:c="identity:module">c:iden</lf11>
+ </cont1>
+</cont>
\ No newline at end of file
--- /dev/null
+module identity-module {
+ namespace "identity:module";
+
+ prefix "idemod";
+ revision 2013-12-2 {
+ }
+
+ identity iden {
+ }
+}
\ No newline at end of file
--- /dev/null
+module identityref-module {
+ namespace "identityref:module";
+
+ prefix "iderefmod";
+
+ import identity-module {prefix idemo; revision-date 2013-12-2;}
+
+ revision 2013-12-2 {
+ }
+
+ container cont {
+ container cont1 {
+ leaf lf11 {
+ type identityref {
+ base "idemo:iden";
+ }
+ }
+ }
+ }
+
+}
\ No newline at end of file
--- /dev/null
+<cont xmlns="general:module" xmlns:x="x:namespace" xmlns:y="y:namespace">
+ <cont1 xmlns:z="z:namespace" xmlns:a="a:namespace" xmlns:b="b:namespace">
+ <lf11 xmlns="identityref:module" xmlns:c="c:namespace">iden</lf11>
+ </cont1>
+</cont>
\ No newline at end of file
--- /dev/null
+<cont xmlns:x="x:namespace" xmlns:y="y:namespace">
+ <cont1 xmlns="identityref:module" xmlns:z="z:namespace" xmlns:a="a:namespace" xmlns:b="b:namespace">
+ <lf11 xmlns:c="c:namespace">iden</lf11>
+ </cont1>
+</cont>
\ No newline at end of file
--- /dev/null
+<cont xmlns="identityref:module" xmlns:x="x:namespace" xmlns:y="y:namespace">
+ <cont1 xmlns:z="z:namespace" xmlns:a="a:namespace" xmlns:b="b:namespace">
+ <lf11 xmlns:c="identity:module">c:iden</lf11>
+ </cont1>
+</cont>
\ No newline at end of file
--- /dev/null
+<cont xmlns="identityref:module" xmlns:x="x:namespace" xmlns:y="y:namespace">
+ <cont1 xmlns:c="identity:module" xmlns:z="z:namespace" xmlns:a="a:namespace" xmlns:b="b:namespace">
+ <lf11>z:iden</lf11>
+ </cont1>
+</cont>
\ No newline at end of file
--- /dev/null
+<cont>
+ <cont1>
+ <lf11>x:iden</lf11>
+ </cont1>
+</cont>
\ No newline at end of file
--- /dev/null
+<cont>
+ <cont1>
+ <lf11>iden</lf11>
+ </cont1>
+</cont>
\ No newline at end of file
--- /dev/null
+module general-module {
+ namespace "general:module";
+
+ prefix "genmod";
+ revision 2013-12-12 {
+ }
+
+ container cont {
+ container cont1 {
+ }
+ }
+
+
+}
\ No newline at end of file
--- /dev/null
+module identity-module {
+ namespace "identity:module";
+
+ prefix "idemod";
+ revision 2013-12-2 {
+ }
+
+ identity iden {
+ }
+}
\ No newline at end of file
prefix "iderefmod";
import identity-module {prefix idemo; revision-date 2013-12-2;}
+ import general-module {prefix gmo; revision-date 2013-12-12;}
revision 2013-12-2 {
}
- container cont {
- leaf lf1 {
+ augment "/gmo:cont/gmo:cont1" {
+ leaf lf11 {
type identityref {
base "idemo:iden";
}
import org.opendaylight.yangtools.yang.common.QName;
import java.net.URI;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.Set;
+import static org.junit.Assert.fail;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
public class NetconfOperationServiceImplTest {
- private Date date = new Date(0);
+ private static final Date date1970_01_01;
+
+ static {
+ try {
+ date1970_01_01 = new SimpleDateFormat("yyyy-MM-dd").parse("1970-01-01");
+ } catch (ParseException e) {
+ throw new IllegalStateException(e);
+ }
+ }
@Test
public void testCheckConsistencyBetweenYangStoreAndConfig_ok() throws Exception {
mockYangStoreSnapshot());
}
- @Test(expected = IllegalStateException.class)
+ @Test
public void testCheckConsistencyBetweenYangStoreAndConfig_yangStoreMore() throws Exception {
try {
NetconfOperationServiceImpl.checkConsistencyBetweenYangStoreAndConfig(mockJmxClient("qname1"),
mockYangStoreSnapshot("qname2", "qname1"));
+ fail("An exception of type " + IllegalArgumentException.class + " was expected");
} catch (IllegalStateException e) {
String message = e.getMessage();
Assert.assertThat(
message,
JUnitMatchers
- .containsString(" missing from config subsystem but present in yangstore: [(namespace?revision=1970-01-01)qname2]"));
+ .containsString("missing from config subsystem but present in yangstore: [(namespace?revision=1970-01-01)qname2]"));
Assert.assertThat(
message,
JUnitMatchers
.containsString("All modules present in config: [(namespace?revision=1970-01-01)qname1]"));
- throw e;
}
}
}
private QName getQName(String qname) {
- return new QName(URI.create("namespace"), date, qname);
+ return new QName(URI.create("namespace"), date1970_01_01, qname);
}
private LookupRegistry mockJmxClient(String... visibleQNames) {
<artifactId>netconf-ssh</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>netconf-ssh</artifactId>
+ <scope>test</scope>
+ <type>test-jar</type>
+ </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>netconf-util</artifactId>
package org.opendaylight.controller.netconf.it;
-import static java.util.Collections.emptyList;
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertNotNull;
-import static junit.framework.Assert.assertTrue;
-import static org.mockito.Matchers.anyLong;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
+import ch.ethz.ssh2.Connection;
+import ch.ethz.ssh2.Session;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
import io.netty.channel.ChannelFuture;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.util.HashedWheelTimer;
-
import java.io.IOException;
import java.io.InputStream;
import java.lang.management.ManagementFactory;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
-
import javax.management.ObjectName;
import javax.xml.parsers.ParserConfigurationException;
-
import junit.framework.Assert;
-
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.opendaylight.controller.config.yang.test.impl.NetconfTestImplModuleFactory;
import org.opendaylight.controller.config.yang.test.impl.NetconfTestImplModuleMXBean;
import org.opendaylight.controller.config.yang.test.impl.TestImplModuleFactory;
+import org.opendaylight.controller.netconf.StubUserManager;
import org.opendaylight.controller.netconf.api.NetconfMessage;
import org.opendaylight.controller.netconf.client.NetconfClient;
import org.opendaylight.controller.netconf.client.NetconfClientDispatcher;
import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceSnapshot;
import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService;
import org.opendaylight.controller.netconf.ssh.NetconfSSHServer;
+import org.opendaylight.controller.netconf.ssh.authentication.AuthProvider;
import org.opendaylight.controller.netconf.util.test.XmlFileLoader;
import org.opendaylight.controller.netconf.util.xml.ExiParameters;
import org.opendaylight.controller.netconf.util.xml.XmlElement;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;
-
-import ch.ethz.ssh2.Connection;
-import ch.ethz.ssh2.Session;
-
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
+import static java.util.Collections.emptyList;
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertTrue;
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
public class NetconfITTest extends AbstractConfigTest {
private void startSSHServer() throws Exception{
logger.info("Creating SSH server");
- Thread sshServerThread = new Thread(NetconfSSHServer.start(10830,tcpAddress));
+ StubUserManager um = new StubUserManager(USERNAME,PASSWORD);
+ AuthProvider ap = new AuthProvider(um);
+ Thread sshServerThread = new Thread(NetconfSSHServer.start(10830,tcpAddress,ap));
sshServerThread.setDaemon(true);
sshServerThread.start();
logger.info("SSH server on");
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>usermanager</artifactId>
+ <version>0.4.1-SNAPSHOT</version>
+ </dependency>
</dependencies>
<build>
<plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.4</version>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <goals>
+ <goal>test-jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
org.apache.commons.io,
org.opendaylight.controller.netconf.util,
org.opendaylight.controller.netconf.util.osgi,
+ org.opendaylight.controller.usermanager,
+ org.opendaylight.controller.sal.authorization,
+ org.opendaylight.controller.sal.utils,
org.opendaylight.protocol.framework,
org.osgi.framework,
- org.slf4j
+ org.osgi.util.tracker,
+ org.slf4j,
</Import-Package>
</instructions>
</configuration>
import com.google.common.base.Optional;
import java.net.InetSocketAddress;
import org.opendaylight.controller.netconf.ssh.NetconfSSHServer;
+import org.opendaylight.controller.netconf.ssh.authentication.AuthProvider;
import org.opendaylight.controller.netconf.util.osgi.NetconfConfigUtil;
+import org.opendaylight.controller.usermanager.IUserManager;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private NetconfSSHServer server;
private static final Logger logger = LoggerFactory.getLogger(NetconfSSHActivator.class);
private static final String EXCEPTION_MESSAGE = "Netconf ssh bridge is not available.";
+ private IUserManager iUserManager;
+ private BundleContext context = null;
+
+ ServiceTrackerCustomizer<IUserManager, IUserManager> customizer = new ServiceTrackerCustomizer<IUserManager, IUserManager>(){
+ @Override
+ public IUserManager addingService(ServiceReference<IUserManager> reference) {
+ logger.info("Service IUserManager added, let there be SSH bridge.");
+ iUserManager = context.getService(reference);
+ try {
+ onUserManagerFound(iUserManager);
+ } catch (Exception e) {
+ logger.trace("Can't start SSH server due to {}",e);
+ }
+ return iUserManager;
+ }
+ @Override
+ public void modifiedService(ServiceReference<IUserManager> reference, IUserManager service) {
+ logger.info("Replacing modified service IUserManager in netconf SSH.");
+ server.addUserManagerService(service);
+ }
+ @Override
+ public void removedService(ServiceReference<IUserManager> reference, IUserManager service) {
+ logger.info("Removing service IUserManager from netconf SSH. " +
+ "SSH won't authenticate users until IUserManeger service will be started.");
+ removeUserManagerService();
+ }
+ };
+
@Override
public void start(BundleContext context) throws Exception {
+ this.context = context;
+ listenForManagerService();
+ }
+ @Override
+ public void stop(BundleContext context) throws Exception {
+ if (server != null){
+ server.stop();
+ logger.trace("Netconf SSH bridge is down ...");
+ }
+ }
+ private void startSSHServer() throws Exception {
logger.trace("Starting netconf SSH bridge.");
-
- Optional<InetSocketAddress> sshSocketAddressOptional = NetconfConfigUtil.extractSSHNetconfAddress(context,EXCEPTION_MESSAGE);
+ Optional<InetSocketAddress> sshSocketAddressOptional = NetconfConfigUtil.extractSSHNetconfAddress(context, EXCEPTION_MESSAGE);
InetSocketAddress tcpSocketAddress = NetconfConfigUtil.extractTCPNetconfAddress(context,
EXCEPTION_MESSAGE, true);
if (sshSocketAddressOptional.isPresent()){
- server = NetconfSSHServer.start(sshSocketAddressOptional.get().getPort(),tcpSocketAddress);
+ AuthProvider authProvider = new AuthProvider(iUserManager);
+ this.server = NetconfSSHServer.start(sshSocketAddressOptional.get().getPort(),tcpSocketAddress,authProvider);
Thread serverThread = new Thread(server,"netconf SSH server thread");
serverThread.setDaemon(true);
serverThread.start();
throw new Exception("No valid connection configuration for SSH bridge found.");
}
}
-
- @Override
- public void stop(BundleContext context) throws Exception {
- if (server != null){
- logger.trace("Netconf SSH bridge going down ...");
- server.stop();
- logger.trace("Netconf SSH bridge is down ...");
+ private void onUserManagerFound(IUserManager userManager) throws Exception{
+ if (server!=null && server.isUp()){
+ server.addUserManagerService(userManager);
+ } else {
+ startSSHServer();
}
}
+ private void removeUserManagerService(){
+ this.server.removeUserManagerService();
+ }
+ private void listenForManagerService(){
+ ServiceTracker<IUserManager, IUserManager> listenerTracker = new ServiceTracker<>(context, IUserManager.class,customizer);
+ listenerTracker.open();
+ }
}
import java.net.ServerSocket;
import java.util.concurrent.atomic.AtomicLong;
import javax.annotation.concurrent.ThreadSafe;
+import org.opendaylight.controller.netconf.ssh.authentication.AuthProvider;
import org.opendaylight.controller.netconf.ssh.threads.SocketThread;
+import org.opendaylight.controller.usermanager.IUserManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ThreadSafe
public class NetconfSSHServer implements Runnable {
- private static boolean acceptMore = true;
private ServerSocket ss = null;
private static final Logger logger = LoggerFactory.getLogger(NetconfSSHServer.class);
private static final AtomicLong sesssionId = new AtomicLong();
private final InetSocketAddress clientAddress;
+ private final AuthProvider authProvider;
+ private boolean up = false;
- private NetconfSSHServer(int serverPort,InetSocketAddress clientAddress) throws Exception{
+ private NetconfSSHServer(int serverPort,InetSocketAddress clientAddress, AuthProvider authProvider) throws Exception{
logger.trace("Creating SSH server socket on port {}",serverPort);
this.ss = new ServerSocket(serverPort);
}
logger.trace("Server socket created.");
this.clientAddress = clientAddress;
-
+ this.authProvider = authProvider;
+ this.up = true;
}
-
- public static NetconfSSHServer start(int serverPort, InetSocketAddress clientAddress) throws Exception {
- return new NetconfSSHServer(serverPort, clientAddress);
+ public static NetconfSSHServer start(int serverPort, InetSocketAddress clientAddress,AuthProvider authProvider) throws Exception {
+ return new NetconfSSHServer(serverPort, clientAddress,authProvider);
}
public void stop() throws Exception {
- acceptMore = false;
+ up = false;
logger.trace("Closing SSH server socket.");
ss.close();
logger.trace("SSH server socket closed.");
}
+ public void removeUserManagerService(){
+ this.authProvider.removeUserManagerService();
+ }
+
+ public void addUserManagerService(IUserManager userManagerService){
+ this.authProvider.addUserManagerService(userManagerService);
+ }
+ public boolean isUp(){
+ return this.up;
+ }
@Override
public void run() {
- while (acceptMore) {
+ while (up) {
logger.trace("Starting new socket thread.");
try {
- SocketThread.start(ss.accept(), clientAddress, sesssionId.incrementAndGet());
+ SocketThread.start(ss.accept(), clientAddress, sesssionId.incrementAndGet(),authProvider);
} catch (IOException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
--- /dev/null
+/*
+ * Copyright (c) 2013 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.netconf.ssh.authentication;
+
+import ch.ethz.ssh2.signature.RSAPrivateKey;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.commons.io.IOUtils;
+import org.opendaylight.controller.sal.authorization.AuthResultEnum;
+import org.opendaylight.controller.sal.authorization.UserLevel;
+import org.opendaylight.controller.usermanager.IUserManager;
+import org.opendaylight.controller.usermanager.UserConfig;
+
+public class AuthProvider implements AuthProviderInterface {
+
+ private static RSAPrivateKey hostkey = null;
+ private static IUserManager um;
+ private static final String DEAFULT_USER = "netconf";
+ private static final String DEAFULT_PASSWORD = "netconf";
+
+
+ public AuthProvider(IUserManager ium) throws Exception {
+
+ this.um = ium;
+
+ if (this.um == null){
+ throw new Exception("No usermanager service available.");
+ }
+
+ List<String> roles = new ArrayList<String>(1);
+ roles.add(UserLevel.SYSTEMADMIN.toString());
+ this.um.addLocalUser(new UserConfig(DEAFULT_USER, DEAFULT_PASSWORD, roles));
+ }
+ @Override
+ public boolean authenticated(String username, String password) throws Exception {
+ if (this.um == null){
+ throw new Exception("No usermanager service available.");
+ }
+ AuthResultEnum authResult = this.um.authenticate(username,password);
+ if (authResult.equals(AuthResultEnum.AUTH_ACCEPT) || authResult.equals(AuthResultEnum.AUTH_ACCEPT_LOC)){
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public char[] getPEMAsCharArray() {
+
+ InputStream is = getClass().getResourceAsStream("/RSA.pk");
+ try {
+ return IOUtils.toCharArray(is);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ @Override
+ public void removeUserManagerService() {
+ this.um = null;
+ }
+
+ @Override
+ public void addUserManagerService(IUserManager userManagerService) {
+ this.um = userManagerService;
+ }
+
+
+}
+
/*
* Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
*
*/
package org.opendaylight.controller.netconf.ssh.authentication;
-import ch.ethz.ssh2.signature.RSAPrivateKey;
+import org.opendaylight.controller.usermanager.IUserManager;
+
+public interface AuthProviderInterface {
-public interface KeyStoreHandler {
- public RSAPrivateKey getPrivateKey();
+ public boolean authenticated(String username, String password) throws Exception;
+ public char[] getPEMAsCharArray();
+ public void removeUserManagerService();
+ public void addUserManagerService(IUserManager userManagerService);
}
+++ /dev/null
-/*
- * Copyright (c) 2013 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.netconf.ssh.authentication;
-
-import ch.ethz.ssh2.signature.RSAPrivateKey;
-
-import java.math.BigInteger;
-
-public class RSAKey implements KeyStoreHandler {
-
- private static RSAPrivateKey hostkey = null;
- private static String user = "netconf";
- private static String password = "netconf";
- static {
-
- BigInteger p = new BigInteger("2967886344240998436887630478678331145236162666668503940430852241825039192450179076148979094256007292741704260675085192441025058193581327559331546948442042987131728039318861235625879376246169858586459472691398815098207618446039"); //.BigInteger.probablePrime(N / 2, rnd);
- BigInteger q = new BigInteger("4311534819291430017572425052029278681302539382618633848168923130451247487970187151403375389974616614405320169278870943605377518341666894603659873284783174749122655429409273983428000534304828056597676444751611433784228298909767"); //BigInteger.probablePrime(N / 2, rnd);
- BigInteger phi = (p.subtract(BigInteger.ONE)).multiply(q.subtract(BigInteger.ONE));
-
- BigInteger n = p.multiply(q);
- BigInteger e = new BigInteger("65537");
- BigInteger d = e.modInverse(phi);
-
- hostkey = new RSAPrivateKey(d, e, n);
- }
-
- @Override
- public RSAPrivateKey getPrivateKey() {
- return hostkey;
- }
-}
import java.net.InetSocketAddress;
import java.net.Socket;
import javax.annotation.concurrent.ThreadSafe;
-import org.opendaylight.controller.netconf.ssh.authentication.RSAKey;
+import org.opendaylight.controller.netconf.ssh.authentication.AuthProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private long sessionId;
private String currentUser;
private final String remoteAddressWithPort;
+ private final AuthProvider authProvider;
- public static void start(Socket socket, InetSocketAddress clientAddress, long sessionId) throws IOException{
- Thread netconf_ssh_socket_thread = new Thread(new SocketThread(socket,clientAddress,sessionId));
+ public static void start(Socket socket,
+ InetSocketAddress clientAddress,
+ long sessionId,
+ AuthProvider authProvider) throws IOException{
+ Thread netconf_ssh_socket_thread = new Thread(new SocketThread(socket,clientAddress,sessionId,authProvider));
netconf_ssh_socket_thread.setDaemon(true);
netconf_ssh_socket_thread.start();
}
- private SocketThread(Socket socket, InetSocketAddress clientAddress, long sessionId) throws IOException {
+ private SocketThread(Socket socket,
+ InetSocketAddress clientAddress,
+ long sessionId,
+ AuthProvider authProvider) throws IOException {
this.socket = socket;
this.clientAddress = clientAddress;
this.sessionId = sessionId;
this.remoteAddressWithPort = socket.getRemoteSocketAddress().toString().replaceFirst("/","");
+ this.authProvider = authProvider;
}
@Override
public void run() {
conn = new ServerConnection(socket);
- RSAKey keyStore = new RSAKey();
- conn.setRsaHostKey(keyStore.getPrivateKey());
+ try {
+ conn.setPEMHostKey(authProvider.getPEMAsCharArray(),"netconf");
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
conn.setAuthenticationCallback(this);
conn.setServerConnectionCallback(this);
try {
netconf_ssh_output.start();
} catch (Throwable t){
- logger.error(t.getMessage(),t);
+ logger.error("SSH bridge couldn't create echo socket",t.getMessage(),t);
try {
if (netconf_ssh_input!=null){
public AuthenticationResult authenticateWithPassword(ServerConnection sc, String username, String password)
{
- if (USER.equals(username) && PASSWORD.equals(password)){
- currentUser = username;
- logger.trace("user {}@{} authenticated",currentUser,remoteAddressWithPort);
- return AuthenticationResult.SUCCESS;
- }
-
+ try {
+ if (authProvider.authenticated(username,password)){
+ currentUser = username;
+ logger.trace("user {}@{} authenticated",currentUser,remoteAddressWithPort);
+ return AuthenticationResult.SUCCESS;
+ }
+ } catch (Exception e){
+ logger.info("Authentication failed due to :" + e.getLocalizedMessage());
+ }
return AuthenticationResult.FAILURE;
}
--- /dev/null
+-----BEGIN RSA PRIVATE KEY-----
+MIIEogIBAAKCAQEAuC9hbEacpewvylI0mwFwjy3Wou2hpr/ncN9BBiFDSaG5yW2k
+3Oy+SCAcFCL+ZKWb6cc6Ch4gUeCwyEHRojZguuhliKtak9YQf6qbvpPLe00842Lx
+iqNAGurMpzizCDsGFq8ChaAkBZQI3TvcHuPoSUWSMJ+K8xHpRyUdVr6g2yEjezKJ
+sTXBtWaeCCh6YUafFujuDJk7fvYcPW7Je5KRBBStIKvxcMW0zB+7eq04deTHwGbJ
+gGjKWilQ72hsDDP3Hbp5CJMAYg1r4GlCmFx3KyHRGztgWgNgaD7nNpKCkTLjtmA6
+b4x7TA+jrzZ6Af2z5TMrI4dv5w1SrxHaZ+ziLQIDAQABAoIBAHTndeGgq/rQf8De
+Do+4CTaHtK0zQSAyu/azbXUzlZ7drKuCEVs8VMY4wzmwwGEnkF+A2YDkgEUX5X0l
+8aYQ97KKoS9u+43MGCrAIhyDeGrpqlT1TzRcy+qJz53v6gq2U/X/3QztiQ+VV078
+mIluxNgE9XYxPaNsYfGLSCTv1+9c8y/hjGVX2kwFK+u4ut0ZZETggNa8UxfaHVDS
+fIJQX9Gm3J3GSUV30fDGMBIUW6ESLc2L8b7u8Mp9TRP39ZeQSuEUjBe8MYKv0Rel
+oEpjZvcnniMTpFbLpndBYn7/AoIiEBvtCN8faVTuRRcvvLcsRm09IctzKQYnMh6M
+6PLKV+ECgYEA8HFRYaKHUzxpzE/fyon82GQbzqFFY0/bbWrfWICMfNbIgshJUie6
+FmH5iUFMfeqaT7v557HFM0GB9FeIeSbvd88YmiBAcRopZ3DfMkDH+DT73yJ+/TKG
+2nrQtdhyuTIs4bwHqeS2BBJYs7PK9R2rratF3l34Tf7mjlvyOgygHdUCgYEAxBo2
+8hEBlAVNcNb1hTYUxe1w1B6675/mFlmw98Xmj9dRYfICXNhahs8tX3/lsBEd+vBu
+fI0oyHaff8m5bPgGzD1ZMybfeROujNrgxaKVk7Ef0FDRRCop4bm18OroFlFAt9l8
+wMp++ToACbdvQvL/mjWMPYlIxhB/YxHswICZZvkCgYAexxKYwdo6sGAGlC7cWT9x
+X5cjowcjyEQZRHXkeUgCbufpvcOM7aLnXJE5nY8yCwbHsBM0MlBA2GDPKylAANjk
+aDEJAZneIHAuWodngl1Wi0m2bU7+ECqs6s2uiU9eH2sZVh1RBQK7kLGkBx6ys6KX
+L3ZZGYRAT6GplWFzRsx0JQKBgCeVlxPD5QqpC1nEumi6YvUVGdpnnZpzL3HBhxxs
+wT612wKnZFyze4qM1X7ahVXGDsQxtkvD/sCAWW/lG13orw6ZL6FIroF1PJ3ILOkY
+CZN3hJF7TtKwpCWhZB2OfWzL2AGEkE8mUP0j/Q/5DCd6f6f0OSvOw3bfq6cm3iB5
+lP2ZAoGAXsRN5TZTX4AQ2xTlrDQ8A5XgcvyWQpJOmEXMTyHV7VaJVzmNWFVAvndK
+5UIq8ALDwB2t7vjmMUW6euvIwqtXiop7G79UOb3e3NhzeyWFGQyBLqCRznGaXQTT
+dlFy73xhukZMhFnj006bjKCYvOPnwuGl3+0fuWil5Rq3jOuY5c8=
+-----END RSA PRIVATE KEY-----
* 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.netconf.ssh;
+package org.opendaylight.controller.netconf;
import ch.ethz.ssh2.Connection;
-import ch.ethz.ssh2.Session;
-import java.io.IOException;
import java.net.InetSocketAddress;
import junit.framework.Assert;
-import org.apache.commons.io.IOUtils;
import org.junit.Test;
+import org.opendaylight.controller.netconf.ssh.NetconfSSHServer;
+import org.opendaylight.controller.netconf.ssh.authentication.AuthProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private static final int PORT = 1830;
private static final InetSocketAddress tcpAddress = new InetSocketAddress("127.0.0.1", 8383);
private static final Logger logger = LoggerFactory.getLogger(SSHServerTest.class);
+ private Thread sshServerThread;
+
+
+
-// @Before
public void startSSHServer() throws Exception{
- logger.info("Creating SSH server");
- NetconfSSHServer server = NetconfSSHServer.start(PORT,tcpAddress);
- Thread sshServerThread = new Thread(server);
- sshServerThread.setDaemon(true);
- sshServerThread.start();
- logger.info("SSH server on");
+ logger.info("Creating SSH server");
+ StubUserManager um = new StubUserManager(USER,PASSWORD);
+ AuthProvider ap = new AuthProvider(um);
+ NetconfSSHServer server = NetconfSSHServer.start(PORT,tcpAddress,ap);
+ sshServerThread = new Thread(server);
+ sshServerThread.setDaemon(true);
+ sshServerThread.start();
+ logger.info("SSH server on");
}
@Test
public void connect(){
- Connection conn = new Connection(HOST,PORT);
- Assert.assertNotNull(conn);
try {
+ this.startSSHServer();
+ Connection conn = new Connection(HOST,PORT);
+ Assert.assertNotNull(conn);
logger.info("connecting to SSH server");
conn.connect();
logger.info("authenticating ...");
boolean isAuthenticated = conn.authenticateWithPassword(USER,PASSWORD);
Assert.assertTrue(isAuthenticated);
- logger.info("opening session");
- Session sess = conn.openSession();
- logger.info("subsystem netconf");
- sess.startSubSystem("netconf");
- sess.getStdin().write("<?xml version=\"1.0\" encoding=\"UTF-8\"?><hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"><capabilities><capability>urn:ietf:params:netconf:base:1.1</capability></capabilities></hello>]]>]]>".getBytes());
- IOUtils.copy(sess.getStdout(), System.out);
- } catch (IOException e) {
- e.printStackTrace();
+ } catch (Exception e) {
+ logger.error("Error while starting SSH server.", e);
}
+
}
}
--- /dev/null
+/*
+ * Copyright (c) 2013 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.netconf;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.opendaylight.controller.sal.authorization.AuthResultEnum;
+import org.opendaylight.controller.sal.authorization.UserLevel;
+import org.opendaylight.controller.sal.utils.Status;
+import org.opendaylight.controller.sal.utils.StatusCode;
+import org.opendaylight.controller.usermanager.AuthorizationConfig;
+import org.opendaylight.controller.usermanager.ISessionManager;
+import org.opendaylight.controller.usermanager.IUserManager;
+import org.opendaylight.controller.usermanager.ServerConfig;
+import org.opendaylight.controller.usermanager.UserConfig;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
+import org.springframework.security.web.context.SecurityContextRepository;
+
+public class StubUserManager implements IUserManager{
+
+
+ private static String user;
+ private static String password;
+
+ public StubUserManager(String user, String password){
+ this.user = user;
+ this.password = password;
+ }
+ @Override
+ public List<String> getUserRoles(String userName) {
+ return null;
+ }
+
+ @Override
+ public AuthResultEnum authenticate(String username, String password) {
+ if (this.user.equals(username) && this.password.equals(password)){
+ return AuthResultEnum.AUTH_ACCEPT_LOC;
+ }
+ return AuthResultEnum.AUTH_REJECT_LOC;
+ }
+
+ @Override
+ public Status addAAAServer(ServerConfig configObject) {
+ return null;
+ }
+
+ @Override
+ public Status removeAAAServer(ServerConfig configObject) {
+ return null;
+ }
+
+ @Override
+ public Status addLocalUser(UserConfig configObject) {
+ return new Status(StatusCode.SUCCESS);
+ }
+
+ @Override
+ public Status modifyLocalUser(UserConfig configObject) {
+ return null;
+ }
+
+ @Override
+ public Status removeLocalUser(UserConfig configObject) {
+ return null;
+ }
+
+ @Override
+ public Status removeLocalUser(String userName) {
+ return null;
+ }
+
+ @Override
+ public Status addAuthInfo(AuthorizationConfig AAAconf) {
+ return null;
+ }
+
+ @Override
+ public Status removeAuthInfo(AuthorizationConfig AAAconf) {
+ return null;
+ }
+
+ @Override
+ public List<AuthorizationConfig> getAuthorizationList() {
+ return null;
+ }
+
+ @Override
+ public Set<String> getAAAProviderNames() {
+ return null;
+ }
+
+ @Override
+ public Status changeLocalUserPassword(String user, String curPassword, String newPassword) {
+ return null;
+ }
+
+ @Override
+ public List<ServerConfig> getAAAServerList() {
+ return null;
+ }
+
+ @Override
+ public List<UserConfig> getLocalUserList() {
+ return null;
+ }
+
+ @Override
+ public Status saveLocalUserList() {
+ return null;
+ }
+
+ @Override
+ public Status saveAAAServerList() {
+ return null;
+ }
+
+ @Override
+ public Status saveAuthorizationList() {
+ return null;
+ }
+
+ @Override
+ public void userLogout(String username) {
+
+ }
+
+ @Override
+ public void userTimedOut(String username) {
+
+ }
+
+ @Override
+ public Map<String, List<String>> getUserLoggedIn() {
+ return null;
+ }
+
+ @Override
+ public String getAccessDate(String user) {
+ return null;
+ }
+
+ @Override
+ public UserLevel getUserLevel(String userName) {
+ return null;
+ }
+
+ @Override
+ public List<UserLevel> getUserLevels(String userName) {
+ return null;
+ }
+
+ @Override
+ public SecurityContextRepository getSecurityContextRepo() {
+ return null;
+ }
+
+ @Override
+ public ISessionManager getSessionManager() {
+ return null;
+ }
+
+ @Override
+ public boolean isRoleInUse(String role) {
+ return false;
+ }
+
+ @Override
+ public String getPassword(String username) {
+ return null;
+ }
+
+ @Override
+ public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
+ return null;
+ }
+
+}
<artifactId>netconf-ssh</artifactId>
<version>${netconf.version}</version>
</dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>netconf-ssh</artifactId>
+ <version>${netconf.version}</version>
+ <type>test-jar</type>
+ </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>netconf-mapping-api</artifactId>
</init-param>
<init-param>
<param-name>cors.allowed.methods</param-name>
- <param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>
+ <param-value>GET,POST,HEAD,OPTIONS,PUT,DELETE</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.headers</param-name>
@Override
public SubnetConfig getSubnetConfig(String subnet) {
// if there are no subnets, return the default subnet
- if(subnetsConfigList.size() == 0 && subnet == DEFAULT_SUBNET_NAME){
+ if(subnetsConfigList.isEmpty() && subnet.equalsIgnoreCase(DEFAULT_SUBNET_NAME)){
return DEFAULT_SUBNETCONFIG;
}else{
return subnetsConfigList.get(subnet);
}
private Status semanticCheck(SubnetConfig conf) {
- Subnet newSubnet = new Subnet(conf);
Set<InetAddress> IPs = subnets.keySet();
if (IPs == null) {
return new Status(StatusCode.SUCCESS);
}
+ Subnet newSubnet = new Subnet(conf);
for (InetAddress i : IPs) {
Subnet existingSubnet = subnets.get(i);
if ((existingSubnet != null) && !existingSubnet.isMutualExclusive(newSubnet)) {
return status;
}
} else {
- if (conf.getName().equals(DEFAULT_SUBNET_NAME)) {
+ if (conf.getName().equalsIgnoreCase(DEFAULT_SUBNET_NAME)) {
return new Status(StatusCode.NOTALLOWED, "The specified subnet gateway cannot be removed");
}
}
@Override
public Status removeSubnet(String name) {
- if (name.equals(DEFAULT_SUBNET_NAME)) {
+ if (name.equalsIgnoreCase(DEFAULT_SUBNET_NAME)) {
return new Status(StatusCode.NOTALLOWED, "The specified subnet gateway cannot be removed");
}
SubnetConfig conf = subnetsConfigList.get(name);
package org.opendaylight.controller.usermanager;
import java.io.Serializable;
-import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import javax.xml.bind.annotation.XmlRootElement;
import org.opendaylight.controller.sal.authorization.AuthResultEnum;
+import org.opendaylight.controller.sal.packet.BitBufferHelper;
import org.opendaylight.controller.sal.utils.HexEncode;
import org.opendaylight.controller.sal.utils.Status;
import org.opendaylight.controller.sal.utils.StatusCode;
protected static final String PASSWORD_REGEX = "(?=.*[^a-zA-Z0-9])(?=.*\\d)(?=.*[a-z])(?=.*[A-Z]).{8,256}$";
private static final Pattern INVALID_USERNAME_CHARACTERS = Pattern.compile("([/\\s\\.\\?#%;\\\\]+)");
private static MessageDigest oneWayFunction;
+ private static SecureRandom randomGenerator;
static {
try {
log.error(String.format("Implementation of %s digest algorithm not found: %s", DIGEST_ALGORITHM,
e.getMessage()));
}
+ UserConfig.randomGenerator = new SecureRandom(BitBufferHelper.toByteArray(System.currentTimeMillis()));
}
/**
@XmlElement
private String password;
+ private byte[] salt;
+
public UserConfig() {
/*
* Password validation to be done on clear text password. If fails, mark
* the password with a well known label, so that object validation can
- * report the proper error. Only if password is a valid one, hash it.
+ * report the proper error. Only if password is a valid one, generate
+ * salt, concatenate it with clear text password and hash the
+ * resulting string. Hash result is going to be our stored password.
*/
- this.password = (validatePassword(password).isSuccess()) ? hash(password) : BAD_PASSWORD;
+ if (validateClearTextPassword(password).isSuccess()) {
+ this.salt = BitBufferHelper.toByteArray(randomGenerator.nextLong());
+ this.password = hash(salt, password);
+ } else {
+ this.salt = null;
+ this.password = BAD_PASSWORD;
+ }
- this.roles = (roles == null) ? new ArrayList<String>() : new ArrayList<String>(roles);
+ this.roles = (roles == null) ? Collections.<String>emptyList() : new ArrayList<String>(roles);
}
public String getUser() {
public Status validate() {
Status validCheck = validateUsername();
if (validCheck.isSuccess()) {
+ // Password validation was run at object construction time
validCheck = (!password.equals(BAD_PASSWORD)) ? new Status(StatusCode.SUCCESS) : new Status(
StatusCode.BADREQUEST,
"Password should be 8 to 256 characters long, contain both upper and lower case letters, "
return new Status(StatusCode.SUCCESS);
}
- private Status validatePassword(String password) {
+ private Status validateClearTextPassword(String password) {
if (password == null || password.isEmpty()) {
return new Status(StatusCode.BADREQUEST, "Password cannot be empty");
}
// To make any changes to a user configured profile, current password
// must always be provided
- if (!this.password.equals(hash(currentPassword))) {
+ if (!this.password.equals(hash(this.salt, currentPassword))) {
return new Status(StatusCode.BADREQUEST, "Current password is incorrect");
}
// Create a new object with the proposed modifications
UserConfig proposed = new UserConfig();
proposed.user = this.user;
- proposed.password = (newPassword == null)? this.password : hash(newPassword);
+ proposed.password = (newPassword == null)? this.password : hash(this.salt, newPassword);
proposed.roles = (newRoles == null)? this.roles : newRoles;
// Validate it
return status;
}
- public AuthResponse authenticate(String clearTextPass) {
+ public AuthResponse authenticate(String clearTextPassword) {
AuthResponse locResponse = new AuthResponse();
- if (password.equals(hash(clearTextPass))) {
+ if (password.equals(hash(this.salt, clearTextPassword))) {
locResponse.setStatus(AuthResultEnum.AUTH_ACCEPT_LOC);
locResponse.addData(getRolesString());
} else {
return buffer.toString();
}
- public static String hash(String message) {
+ private static byte[] concatenate(byte[] salt, String password) {
+ byte[] messageArray = password.getBytes();
+ byte[] concatenation = new byte[salt.length + password.length()];
+ System.arraycopy(salt, 0, concatenation, 0, salt.length);
+ System.arraycopy(messageArray, 0, concatenation, salt.length, messageArray.length);
+ return concatenation;
+ }
+
+ private static String hash(byte[] salt, String message) {
if (message == null) {
+ log.warn("Password hash requested but empty or no password provided");
return message;
}
+ if (salt == null || salt.length == 0) {
+ log.warn("Password hash requested but empty or no salt provided");
+ return message;
+ }
+
+ // Concatenate salt and password
+ byte[] messageArray = message.getBytes();
+ byte[] concatenation = new byte[salt.length + message.length()];
+ System.arraycopy(salt, 0, concatenation, 0, salt.length);
+ System.arraycopy(messageArray, 0, concatenation, salt.length, messageArray.length);
+
UserConfig.oneWayFunction.reset();
- return HexEncode.bytesToHexString(UserConfig.oneWayFunction.digest(message.getBytes(Charset.defaultCharset())));
+ return HexEncode.bytesToHexString(UserConfig.oneWayFunction.digest(concatenate(salt, message)));
}
/**
public static UserConfig getUncheckedUserConfig(String userName, String password, List<String> roles) {
UserConfig config = new UserConfig();
config.user = userName;
- config.password = hash(password);
+ config.salt = BitBufferHelper.toByteArray(randomGenerator.nextLong());
+ config.password = hash(config.salt, password);
config.roles = roles;
return config;
}
*/
package org.opendaylight.controller.usermanager;
-import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
.isSuccess());
// New Password = null, No change in password
- assertTrue(userConfig.getPassword().equals(UserConfig.hash("ciscocisco")));
+ assertTrue(userConfig.authenticate("ciscocisco").getStatus().equals(AuthResultEnum.AUTH_ACCEPT_LOC));
// Password changed successfully, no change in user role
assertTrue(userConfig.update("ciscocisco", "cisco123", roles)
.isSuccess());
- assertTrue(userConfig.getPassword().equals(UserConfig.hash("cisco123")));
+ assertTrue(userConfig.authenticate("cisco123").getStatus().equals(AuthResultEnum.AUTH_ACCEPT_LOC));
assertTrue(userConfig.getRoles().get(0).equals(
UserLevel.NETWORKOPERATOR.toString()));
roles.add(UserLevel.SYSTEMADMIN.toString());
assertTrue(userConfig.update("cisco123", "cisco123", roles)
.isSuccess());
- assertTrue(userConfig.getPassword().equals(UserConfig.hash("cisco123")));
+ assertTrue(userConfig.authenticate("cisco123").getStatus().equals(AuthResultEnum.AUTH_ACCEPT_LOC));
assertTrue(userConfig.getRoles().get(0)
.equals(UserLevel.SYSTEMADMIN.toString()));
// Password and role changed successfully
assertTrue(userConfig.update("cisco123", "ciscocisco", roles)
.isSuccess());
- assertTrue(userConfig.getPassword().equals(UserConfig.hash("ciscocisco")));
+ assertTrue(userConfig.authenticate("ciscocisco").getStatus().equals(AuthResultEnum.AUTH_ACCEPT_LOC));
assertTrue(userConfig.getRoles().get(0)
.equals(UserLevel.SYSTEMADMIN.toString()));
assertTrue(authresp.getStatus().equals(AuthResultEnum.AUTH_ACCEPT_LOC));
authresp = userConfig.authenticate("wrongPassword");
assertTrue(authresp.getStatus().equals(AuthResultEnum.AUTH_REJECT_LOC));
-
- // test equals()
- roles.clear();
- roles.add(UserLevel.NETWORKOPERATOR.toString());
- userConfig = new UserConfig("uname", "ciscocisco", roles);
- assertEquals(userConfig, userConfig);
- UserConfig userConfig2 = new UserConfig("uname", "ciscocisco", roles);
- assertEquals(userConfig, userConfig2);
}
@Test
org.opendaylight.controller.usermanager
</Import-Package>
<Export-Package>
-<!--
+ <!--
org.opendaylight.controller.usermanager,
org.opendaylight.controller.usermanager.internal
- -->
+ -->
</Export-Package>
<Bundle-Activator>
org.opendaylight.controller.usermanager.internal.Activator
$tr = $(tr);
$span = $("td span", $tr);
var flowstatus = $span.data("flowstatus");
- if($span.data("installinhw") != null) {
- var installInHw = $span.data("installinhw").toString();
+ if($span.data("installInHw") != null) {
+ var installInHw = $span.data("installInHw").toString();
if(installInHw == "true" && flowstatus == "Success") {
$tr.addClass("success");
} else {