Merge "Fixed RESTConf support for identity-ref build-in datatype"
authorEd Warnicke <eaw@cisco.com>
Wed, 18 Dec 2013 11:20:14 +0000 (11:20 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Wed, 18 Dec 2013 11:20:14 +0000 (11:20 +0000)
27 files changed:
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/dynamicmbean/AbstractDynamicWrapper.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/dynamicmbean/AttributeHolder.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/dynamicmbean/DynamicWritableWrapper.java
opendaylight/config/yang-test/pom.xml
opendaylight/config/yang-test/src/test/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleTest.java [new file with mode: 0644]
opendaylight/distribution/opendaylight/pom.xml
opendaylight/distribution/opendaylight/src/main/resources/configuration/logback.xml
opendaylight/md-sal/pom.xml
opendaylight/md-sal/remoterpc-routingtable/implementation/pom.xml [moved from opendaylight/md-sal/zeromq-routingtable/implementation/pom.xml with 98% similarity]
opendaylight/md-sal/remoterpc-routingtable/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/api/RouteChangeListener.java [moved from opendaylight/md-sal/zeromq-routingtable/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/api/RouteChangeListener.java with 100% similarity]
opendaylight/md-sal/remoterpc-routingtable/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/api/RoutingTable.java [moved from opendaylight/md-sal/zeromq-routingtable/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/api/RoutingTable.java with 100% similarity]
opendaylight/md-sal/remoterpc-routingtable/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/api/RoutingTableException.java [moved from opendaylight/md-sal/zeromq-routingtable/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/api/RoutingTableException.java with 100% similarity]
opendaylight/md-sal/remoterpc-routingtable/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/api/SystemException.java [moved from opendaylight/md-sal/zeromq-routingtable/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/api/SystemException.java with 100% similarity]
opendaylight/md-sal/remoterpc-routingtable/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/impl/Activator.java [moved from opendaylight/md-sal/zeromq-routingtable/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/impl/Activator.java with 100% similarity]
opendaylight/md-sal/remoterpc-routingtable/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/impl/RoutingTableImpl.java [moved from opendaylight/md-sal/zeromq-routingtable/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/impl/RoutingTableImpl.java with 95% similarity]
opendaylight/md-sal/remoterpc-routingtable/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/impl/RoutingTableImplTest.java [moved from opendaylight/md-sal/zeromq-routingtable/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/impl/RoutingTableImplTest.java with 100% similarity]
opendaylight/md-sal/remoterpc-routingtable/integrationtest/pom.xml [moved from opendaylight/md-sal/zeromq-routingtable/integrationtest/pom.xml with 98% similarity]
opendaylight/md-sal/remoterpc-routingtable/integrationtest/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/impl/ZeroMQRoutingTableTestIT.java [moved from opendaylight/md-sal/zeromq-routingtable/integrationtest/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/impl/ZeroMQRoutingTableTestIT.java with 99% similarity]
opendaylight/md-sal/remoterpc-routingtable/integrationtest/src/test/resources/logback.xml [moved from opendaylight/md-sal/zeromq-routingtable/integrationtest/src/test/resources/logback.xml with 100% similarity]
opendaylight/md-sal/remoterpc-routingtable/integrationtest/test-nb/pom.xml [new file with mode: 0644]
opendaylight/md-sal/remoterpc-routingtable/integrationtest/test-nb/src/main/java/org/opendaylight/controller/tests/zmqroutingtable/rest/RouteIdentifierImpl.java [new file with mode: 0644]
opendaylight/md-sal/remoterpc-routingtable/integrationtest/test-nb/src/main/java/org/opendaylight/controller/tests/zmqroutingtable/rest/Router.java [new file with mode: 0644]
opendaylight/md-sal/remoterpc-routingtable/integrationtest/test-nb/src/main/resources/WEB-INF/web.xml [new file with mode: 0644]
opendaylight/md-sal/sal-remoterpc-connector/implementation/pom.xml
opendaylight/md-sal/sal-remoterpc-connector/integrationtest/test-nb/pom.xml
opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationServiceImplTest.java
opendaylight/northbound/subnets/src/main/resources/WEB-INF/web.xml

index ba2c1089c2bef93bbcacbbc98019c6ab5045043d..6f0d1b2682a00e17b8935cca72c86599cd2b2b63 100644 (file)
@@ -7,16 +7,14 @@
  */
 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;
@@ -40,15 +38,17 @@ import javax.management.Notification;
 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
@@ -246,6 +246,7 @@ abstract class AbstractDynamicWrapper implements DynamicMBeanModuleWrapper {
         } catch (InstanceNotFoundException e) {
             new MBeanException(e);
         }
+
         if (obj instanceof ObjectName) {
             AttributeHolder attributeHolder = attributeHolderMap
                     .get(attributeName);
@@ -254,8 +255,42 @@ abstract class AbstractDynamicWrapper implements DynamicMBeanModuleWrapper {
             }
             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) {
index 109ab10ac2a086e590ab1023bfa2ffd1442e8ad8..9dd6a2269e259cf4ca5ee4e6b1331d85ef015d81 100644 (file)
@@ -7,18 +7,17 @@
  */
 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 {
@@ -32,6 +31,14 @@ 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,
@@ -114,12 +121,12 @@ class AttributeHolder {
     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);
index a1cd6b01339dd7fc82864c3219bc5f32fc7de0ba..2ab04e53e304fa8909543ded413b408941566fcc 100644 (file)
@@ -7,7 +7,13 @@
  */
 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;
@@ -20,14 +26,7 @@ import javax.management.MBeanOperationInfo;
 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
@@ -92,16 +91,11 @@ public class DynamicWritableWrapper extends AbstractDynamicWrapper {
 
         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);
@@ -109,6 +103,39 @@ public class DynamicWritableWrapper extends AbstractDynamicWrapper {
 
     }
 
+    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();
index 149348df4b2234e7c54c49f59fd7f7118e9d0c91..b1f7013abef241620ff02d393751133270e78bcb 100644 (file)
             <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>
 
diff --git a/opendaylight/config/yang-test/src/test/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleTest.java b/opendaylight/config/yang-test/src/test/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleTest.java
new file mode 100644 (file)
index 0000000..50e1d4b
--- /dev/null
@@ -0,0 +1,89 @@
+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;
+    }
+
+}
index 35e160e8274e9fe5ee09bc49ce90f77841218425..b0f7ad89a4b81694c889c52e51f5cc00947c8c4f 100644 (file)
         <dependency>
               <groupId>org.opendaylight.controller</groupId>
               <artifactId>
-                  zeromq-routingtable.implementation
+                  remoterpc-routingtable.implementation
               </artifactId>
               <version>0.4.1-SNAPSHOT</version>
         </dependency>
index 2815422274fad3c61cfa95ba724969eadf30d001..84d1c913c413ef5e1978aded60ff85c200437169 100644 (file)
@@ -61,7 +61,7 @@
   <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"/>
index 4f2b255afd50c08005fae6abcf0d683db73dd86f..0d6523bc0bbb38dd059e9c978be147cab7a4b7e8 100644 (file)
@@ -43,7 +43,7 @@
         <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>
similarity index 98%
rename from opendaylight/md-sal/zeromq-routingtable/implementation/pom.xml
rename to opendaylight/md-sal/remoterpc-routingtable/implementation/pom.xml
index 2926786849f82999903565f3388e49481b4ab637..a788baf4c0642a1ebb26b390ba415a338a45a033 100644 (file)
@@ -15,7 +15,7 @@
         <tag>HEAD</tag>
     </scm>
 
-    <artifactId>zeromq-routingtable.implementation</artifactId>
+    <artifactId>remoterpc-routingtable.implementation</artifactId>
     <version>0.4.1-SNAPSHOT</version>
     <packaging>bundle</packaging>
 
@@ -30,6 +30,7 @@ import javax.transaction.RollbackException;
 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;
 
@@ -254,6 +255,23 @@ public class RoutingTableImpl<I, R> implements RoutingTable<I, R>, ICacheUpdateA
         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
similarity index 98%
rename from opendaylight/md-sal/zeromq-routingtable/integrationtest/pom.xml
rename to opendaylight/md-sal/remoterpc-routingtable/integrationtest/pom.xml
index 308d5a9316d621e2b235cd1b356b121475fe311d..bdc4569f31ac6869276e1cc7075ba7ded3844fc6 100644 (file)
     <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>
@@ -120,7 +120,7 @@ public class
                         .versionAsInProject(),
                 mavenBundle(ODL, "sal-connector-api")
                         .versionAsInProject(),
-                mavenBundle(ODL, "zeromq-routingtable.implementation")
+                mavenBundle(ODL, "remoterpc-routingtable.implementation")
                         .versionAsInProject(),
 
                 mavenBundle("org.jboss.spec.javax.transaction",
diff --git a/opendaylight/md-sal/remoterpc-routingtable/integrationtest/test-nb/pom.xml b/opendaylight/md-sal/remoterpc-routingtable/integrationtest/test-nb/pom.xml
new file mode 100644 (file)
index 0000000..35b2a4b
--- /dev/null
@@ -0,0 +1,92 @@
+<?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>
diff --git a/opendaylight/md-sal/remoterpc-routingtable/integrationtest/test-nb/src/main/java/org/opendaylight/controller/tests/zmqroutingtable/rest/RouteIdentifierImpl.java b/opendaylight/md-sal/remoterpc-routingtable/integrationtest/test-nb/src/main/java/org/opendaylight/controller/tests/zmqroutingtable/rest/RouteIdentifierImpl.java
new file mode 100644 (file)
index 0000000..6b7ee26
--- /dev/null
@@ -0,0 +1,69 @@
+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
diff --git a/opendaylight/md-sal/remoterpc-routingtable/integrationtest/test-nb/src/main/java/org/opendaylight/controller/tests/zmqroutingtable/rest/Router.java b/opendaylight/md-sal/remoterpc-routingtable/integrationtest/test-nb/src/main/java/org/opendaylight/controller/tests/zmqroutingtable/rest/Router.java
new file mode 100644 (file)
index 0000000..c426927
--- /dev/null
@@ -0,0 +1,157 @@
+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());
+  }
+
+
+
+}
diff --git a/opendaylight/md-sal/remoterpc-routingtable/integrationtest/test-nb/src/main/resources/WEB-INF/web.xml b/opendaylight/md-sal/remoterpc-routingtable/integrationtest/test-nb/src/main/resources/WEB-INF/web.xml
new file mode 100644 (file)
index 0000000..2a0f3f3
--- /dev/null
@@ -0,0 +1,58 @@
+<?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>
index b8e0938a5f0901c9d7b73de541543aa472fca217..c973498e8549888e4b076d7e102c388c6222b9e8 100644 (file)
@@ -37,7 +37,7 @@
     </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>
index dd7e36cfb4f8647656a6a0492731dfd730a4f458..dc2fdbf9a05382d19307d6cccb20c918c6c1aafc 100644 (file)
@@ -97,7 +97,7 @@
     </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>
index 0d459cfb865904fee47d19f0831aa62b8f795fa0..53e14ba5fbe8e1d0d945ac957b98c9e45ba65ad8 100644 (file)
@@ -19,16 +19,27 @@ import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
 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 {
@@ -51,22 +62,22 @@ public class NetconfOperationServiceImplTest {
                 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;
         }
     }
 
@@ -97,7 +108,7 @@ public class NetconfOperationServiceImplTest {
     }
 
     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) {
index 2300b8da400d6f15f46812f868c3e262b30b32df..7e0d465256fa63b5af631ce76e4fb078ef257c28 100644 (file)
@@ -25,7 +25,7 @@
           </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>