Merge "Bumped version of Maven YANG tools to 0.5.1-SNAPSHOT"
authorGiovanni Meo <gmeo@cisco.com>
Wed, 29 May 2013 16:32:29 +0000 (16:32 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Wed, 29 May 2013 16:32:29 +0000 (16:32 +0000)
15 files changed:
opendaylight/commons/concepts/pom.xml [new file with mode: 0644]
opendaylight/commons/concepts/src/main/java/org/opendaylight/controller/concepts/tranform/Acceptor.java [new file with mode: 0644]
opendaylight/commons/concepts/src/main/java/org/opendaylight/controller/concepts/tranform/AggregateTransformer.java [new file with mode: 0644]
opendaylight/commons/concepts/src/main/java/org/opendaylight/controller/concepts/tranform/CompositeClassBasedTransformer.java [new file with mode: 0644]
opendaylight/commons/concepts/src/main/java/org/opendaylight/controller/concepts/tranform/CompositeConditionalTransformer.java [new file with mode: 0644]
opendaylight/commons/concepts/src/main/java/org/opendaylight/controller/concepts/tranform/InputClassBasedTransformer.java [new file with mode: 0644]
opendaylight/commons/concepts/src/main/java/org/opendaylight/controller/concepts/tranform/RuleBasedTransformer.java [new file with mode: 0644]
opendaylight/commons/concepts/src/main/java/org/opendaylight/controller/concepts/tranform/SimpleConditionalTransformer.java [new file with mode: 0644]
opendaylight/commons/concepts/src/main/java/org/opendaylight/controller/concepts/tranform/Transformer.java [new file with mode: 0644]
opendaylight/distribution/opendaylight/pom.xml
opendaylight/northbound/integrationtest/src/test/java/org/opendaylight/controller/northbound/integrationtest/NorthboundIntegrationTest.java
opendaylight/protocol_plugins/stub/src/main/java/org/opendaylight/controller/protocol_plugins/stub/internal/Activator.java
opendaylight/protocol_plugins/stub/src/main/java/org/opendaylight/controller/protocol_plugins/stub/internal/StubNodeFactory.java [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Node.java
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/INodeFactory.java [new file with mode: 0644]

diff --git a/opendaylight/commons/concepts/pom.xml b/opendaylight/commons/concepts/pom.xml
new file mode 100644 (file)
index 0000000..369a58a
--- /dev/null
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<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">\r
+  <modelVersion>4.0.0</modelVersion>\r
+  <parent>\r
+    <groupId>org.opendaylight.controller</groupId>\r
+    <artifactId>commons.opendaylight</artifactId>\r
+    <version>1.4.0-SNAPSHOT</version>\r
+    <relativePath>../../commons/opendaylight</relativePath>\r
+  </parent>\r
+\r
+  <artifactId>concepts</artifactId>\r
+  <version>0.5.0-SNAPSHOT</version>\r
+  <packaging>bundle</packaging>\r
+\r
+  <build>\r
+    <plugins>\r
+      <plugin>\r
+        <groupId>org.apache.felix</groupId>\r
+        <artifactId>maven-bundle-plugin</artifactId>\r
+        <version>2.3.6</version>\r
+        <extensions>true</extensions>\r
+        <configuration>\r
+          <instructions>\r
+            <Import-Package>\r
+              org.slf4j,\r
+              org.osgi.framework,\r
+              org.apache.commons.lang3.builder,\r
+              org.apache.felix.dm,\r
+              org.apache.commons.lang3.tuple,\r
+              javax.xml.bind.annotation,\r
+              javax.xml.bind.annotation.adapters\r
+            </Import-Package>\r
+            <Export-Package>\r
+              org.opendaylight.controller.concepts.transform\r
+            </Export-Package>\r
+          </instructions>\r
+          <manifestLocation>${project.basedir}/META-INF</manifestLocation>\r
+        </configuration>\r
+      </plugin>\r
+    </plugins>\r
+  </build>\r
+  <dependencies>\r
+    <dependency>\r
+      <groupId>junit</groupId>\r
+      <artifactId>junit</artifactId>\r
+      <version>4.8.1</version>\r
+      <scope>test</scope>\r
+    </dependency>\r
+  </dependencies>\r
+</project>\r
diff --git a/opendaylight/commons/concepts/src/main/java/org/opendaylight/controller/concepts/tranform/Acceptor.java b/opendaylight/commons/concepts/src/main/java/org/opendaylight/controller/concepts/tranform/Acceptor.java
new file mode 100644 (file)
index 0000000..1bd78d6
--- /dev/null
@@ -0,0 +1,20 @@
+\r
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+\r
+package org.opendaylight.controller.concepts.tranform;\r
+\r
+public interface Acceptor<I> {\r
+\r
+    /**\r
+     * \r
+     * @param input\r
+     * @return true if input is accepted.\r
+     */\r
+    boolean isAcceptable(I input);\r
+}\r
diff --git a/opendaylight/commons/concepts/src/main/java/org/opendaylight/controller/concepts/tranform/AggregateTransformer.java b/opendaylight/commons/concepts/src/main/java/org/opendaylight/controller/concepts/tranform/AggregateTransformer.java
new file mode 100644 (file)
index 0000000..390bc03
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+\r
+package org.opendaylight.controller.concepts.tranform;\r
+\r
+import java.util.Collection;\r
+/**\r
+ * \r
+ * @author Tony Tkacik\r
+ *\r
+ * @param <I>\r
+ * @param <P>\r
+ */\r
+public interface AggregateTransformer<I,P> extends Transformer<I,P> {\r
+\r
+    Collection<P> transformAll(Collection<? extends I> inputs);\r
+}\r
diff --git a/opendaylight/commons/concepts/src/main/java/org/opendaylight/controller/concepts/tranform/CompositeClassBasedTransformer.java b/opendaylight/commons/concepts/src/main/java/org/opendaylight/controller/concepts/tranform/CompositeClassBasedTransformer.java
new file mode 100644 (file)
index 0000000..ec62fee
--- /dev/null
@@ -0,0 +1,121 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+\r
+package org.opendaylight.controller.concepts.tranform;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.Map;\r
+import java.util.concurrent.ConcurrentHashMap;\r
+\r
+\r
+/**\r
+ * Transformer which aggregates multiple implementations of\r
+ * {@link InputClassBasedTransformer}.\r
+ * \r
+ * The transformation process is driven by {@link Class} of input. The selection\r
+ * of used {@link InputClassBasedTransformer} is done by using the {@link Class}\r
+ * of input as a key to select the transformer.\r
+ * \r
+ * This approach provides quick resolution of transformer, but does not support\r
+ * registering a super type of input to provide transformation support for all\r
+ * subclasses, one must register a new instance of transformer for each valid\r
+ * input class.\r
+ * \r
+ * If you need more flexible selection of transformation consider using\r
+ * {@link CompositeConditionalTransformer} which is slower but most flexible or\r
+ * {@link RuleBasedTransformer} which provides declarative approach for\r
+ * transformation.\r
+ * \r
+ * See {@link #transform(Object)} for more information about tranformation\r
+ * process.\r
+ * \r
+ * @author Tony Tkacik <ttkacik@cisco.com>\r
+ * \r
+ * @param <I>\r
+ *            Input super-type\r
+ * @param <P>\r
+ *            Product\r
+ */\r
+public abstract class CompositeClassBasedTransformer<I, P> implements\r
+        InputClassBasedTransformer<I, I, P>,\r
+        AggregateTransformer<I, P> {\r
+\r
+    private Map<Class<? extends I>, InputClassBasedTransformer<I, ? extends I, P>> transformers = new ConcurrentHashMap<Class<? extends I>, InputClassBasedTransformer<I, ? extends I, P>>();\r
+\r
+    /**\r
+     * Transforms an input into instance of Product class.\r
+     * \r
+     * The final registered transformer is the one which match following\r
+     * condition:\r
+     * \r
+     * <code>input.getClass() == transformer.getInputClass()</code>\r
+     * \r
+     * This means that transformers are not resolved by class hierarchy, only\r
+     * selected based on final class of the input. If you need more flexible\r
+     * selection of transformation consider using\r
+     * {@link CompositeConditionalTransformer} which is slower but more\r
+     * flexible.\r
+     * \r
+     */\r
+    @Override\r
+    public P transform(I input) {\r
+        @SuppressWarnings("unchecked")\r
+        InputClassBasedTransformer<I, I, P> transformer = (InputClassBasedTransformer<I, I, P>) transformers\r
+                .get(input.getClass());\r
+        if (transformer == null)\r
+            throw new IllegalArgumentException("Transformation of: " + input\r
+                    + " is not supported");\r
+        return transformer.transform(input);\r
+    }\r
+\r
+    /**\r
+     * Registers a new transformer.\r
+     * \r
+     * The transformer is registered for class returned by\r
+     * {@link InputClassBasedTransformer#getInputClass()}. Only one transformer\r
+     * can be registered for particular input class.\r
+     * \r
+     */\r
+    public void addTransformer(\r
+            InputClassBasedTransformer<I, ? extends I, P> transformer)\r
+            throws IllegalStateException {\r
+        if (transformer == null)\r
+            throw new IllegalArgumentException("Transformer should not be null");\r
+        if (transformer.getInputClass() == null)\r
+            throw new IllegalArgumentException(\r
+                    "Transformer should specify input class.");\r
+        transformers.put(transformer.getInputClass(), transformer);\r
+    }\r
+\r
+    /**\r
+     * Removes an registered transformer.\r
+     * \r
+     * Note: Removal is currently unsupported.\r
+     * \r
+     * @param transformer\r
+     *            Tranformer to be removed.\r
+     * @throws IllegalArgumentException\r
+     *             If the provided transformer is null or is not registered.\r
+     */\r
+    public void removeTransformer(\r
+            InputClassBasedTransformer<I, ? extends I, P> transformer)\r
+            throws IllegalArgumentException {\r
+        throw new UnsupportedOperationException("Not implemented yet");\r
+    }\r
+    \r
+    @Override\r
+    public Collection<P> transformAll(Collection<? extends I> inputs) {\r
+        Collection<P> ret = new ArrayList<P>();\r
+        for (I i : inputs) {\r
+            ret.add(transform(i));\r
+        }\r
+        return ret;\r
+    }\r
+\r
+}\r
diff --git a/opendaylight/commons/concepts/src/main/java/org/opendaylight/controller/concepts/tranform/CompositeConditionalTransformer.java b/opendaylight/commons/concepts/src/main/java/org/opendaylight/controller/concepts/tranform/CompositeConditionalTransformer.java
new file mode 100644 (file)
index 0000000..a31d896
--- /dev/null
@@ -0,0 +1,157 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+\r
+package org.opendaylight.controller.concepts.tranform;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.Comparator;\r
+import java.util.Set;\r
+import java.util.TreeSet;\r
+\r
+/**\r
+ * Composite transformer which aggregates multiple implementation and selects\r
+ * the one which accepts the input.\r
+ * \r
+ * \r
+ * @author Tony Tkacik\r
+ * \r
+ * @param <I>\r
+ *            Input class for transformation\r
+ * @param <P>\r
+ *            Product of transformation\r
+ */\r
+public class CompositeConditionalTransformer<I, P> implements\r
+        SimpleConditionalTransformer<I, P>,\r
+        AggregateTransformer<I,P> {\r
+\r
+    private final Comparator<TransformerWithPriority<I, P>> comparator = new Comparator<TransformerWithPriority<I, P>>() {\r
+\r
+        @Override\r
+        public int compare(TransformerWithPriority<I, P> o1,\r
+                TransformerWithPriority<I, P> o2) {\r
+            return Integer.compare(o1.priority, o2.priority);\r
+        }\r
+\r
+    };\r
+    private final Set<TransformerWithPriority<I, P>> transformers;\r
+\r
+    public CompositeConditionalTransformer() {\r
+        // FIXME: Add Ordering\r
+        transformers = new TreeSet<TransformerWithPriority<I, P>>(comparator);\r
+    }\r
+\r
+    @Override\r
+    public boolean isAcceptable(I input) {\r
+        for (SimpleConditionalTransformer<I, P> trans : transformers) {\r
+            if (trans.isAcceptable(input)) {\r
+                return true;\r
+            }\r
+        }\r
+        return false;\r
+    }\r
+\r
+    @Override\r
+    public P transform(I input) {\r
+        for (SimpleConditionalTransformer<I, P> trans : transformers) {\r
+            if (trans.isAcceptable(input)) {\r
+                return trans.transform(input);\r
+            }\r
+        }\r
+        throw new IllegalStateException(\r
+                "Transformer for provided input is not available.");\r
+    }\r
+\r
+    public void addTransformer(SimpleConditionalTransformer<I, P> transformer,\r
+            int priority) throws IllegalStateException {\r
+        if (transformer == null) {\r
+            throw new IllegalArgumentException(\r
+                    "transformer should not be null.");\r
+        }\r
+        TransformerWithPriority<I, P> withPriority = new TransformerWithPriority<I, P>(\r
+                transformer, priority);\r
+        if (false == transformers.add(withPriority)) {\r
+            throw new IllegalStateException("transformer " + transformer\r
+                    + "already registered");\r
+        }\r
+    }\r
+\r
+    public void removeTransformer(SimpleConditionalTransformer<I, P> transformer)\r
+            throws IllegalArgumentException {\r
+        if (transformer == null) {\r
+            throw new IllegalArgumentException(\r
+                    "transformer should not be null.");\r
+        }\r
+        if (false == transformers.remove(transformer)) {\r
+            throw new IllegalStateException("transformer " + transformer\r
+                    + "already registered");\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public Collection<P> transformAll(Collection<? extends I> inputs) {\r
+        Collection<P> ret = new ArrayList<P>();\r
+        for (I i : inputs) {\r
+            ret.add(transform(i));\r
+        }\r
+        return ret;\r
+    }\r
+\r
+    private static class TransformerWithPriority<I, P> implements\r
+            SimpleConditionalTransformer<I, P> {\r
+        final int priority;\r
+        final SimpleConditionalTransformer<I, P> transformer;\r
+    \r
+        public TransformerWithPriority(\r
+                SimpleConditionalTransformer<I, P> transformer, int priority) {\r
+            this.priority = priority;\r
+            this.transformer = transformer;\r
+        }\r
+    \r
+        @Override\r
+        public int hashCode() {\r
+            final int prime = 31;\r
+            int result = 1;\r
+            result = prime * result\r
+                    + ((transformer == null) ? 0 : transformer.hashCode());\r
+            return result;\r
+        }\r
+    \r
+        @Override\r
+        public boolean equals(Object obj) {\r
+            if (this == obj)\r
+                return true;\r
+            if (obj == null)\r
+                return false;\r
+            if (getClass() != obj.getClass())\r
+                return false;\r
+            TransformerWithPriority<?,?> other = (TransformerWithPriority<?,?>) obj;\r
+            if (transformer == null) {\r
+                if (other.transformer != null)\r
+                    return false;\r
+            } else if (!transformer.equals(other.transformer))\r
+                return false;\r
+            return true;\r
+        }\r
+    \r
+        @Override\r
+        public boolean isAcceptable(I input) {\r
+            return transformer.isAcceptable(input);\r
+        }\r
+    \r
+        @Override\r
+        public P transform(I input) {\r
+            return transformer.transform(input);\r
+        }\r
+        \r
+    \r
+    \r
+    \r
+    \r
+    }\r
+}\r
diff --git a/opendaylight/commons/concepts/src/main/java/org/opendaylight/controller/concepts/tranform/InputClassBasedTransformer.java b/opendaylight/commons/concepts/src/main/java/org/opendaylight/controller/concepts/tranform/InputClassBasedTransformer.java
new file mode 100644 (file)
index 0000000..1b8d1f0
--- /dev/null
@@ -0,0 +1,38 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+\r
+package org.opendaylight.controller.concepts.tranform;\r
+\r
+/**\r
+ * Input class based transformer\r
+ * \r
+ * {@link Transformer} which accepts / transforms only specific classes of\r
+ * input, and is useful if the selection of transformer should be based on the\r
+ * class of the input and there is one-to-one mapping between input class and\r
+ * transformer.\r
+ * \r
+ * \r
+ * @author Tony Tkacik\r
+ * \r
+ * @param <S>\r
+ *            Common supertype of input\r
+ * @param <I>\r
+ *            Concrete type of input\r
+ * @param <P>\r
+ *            Product\r
+ */\r
+public interface InputClassBasedTransformer<S, I extends S, P> extends\r
+        Transformer<I, P> {\r
+\r
+    /**\r
+     * Returns an {@link Class} of input which is acceptable for transformation.\r
+     * \r
+     * @return {@link Class} of input which is acceptable for transformation.\r
+     */\r
+    Class<? extends S> getInputClass();\r
+}\r
diff --git a/opendaylight/commons/concepts/src/main/java/org/opendaylight/controller/concepts/tranform/RuleBasedTransformer.java b/opendaylight/commons/concepts/src/main/java/org/opendaylight/controller/concepts/tranform/RuleBasedTransformer.java
new file mode 100644 (file)
index 0000000..3f21e5a
--- /dev/null
@@ -0,0 +1,42 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+\r
+package org.opendaylight.controller.concepts.tranform;\r
+\r
+import java.util.Set;\r
+\r
+/**\r
+ * Transformer with set of acceptance rules\r
+ * \r
+ * The transformer provides a set of {@link Acceptor}s, which could be used to\r
+ * verify if the input will produce result using the transformer.\r
+ * \r
+ * The transormer is able to produce result if ANY of associated\r
+ * {@link Acceptor}s accepted result.\r
+ * \r
+ * @author Tony Tkacik\r
+ * \r
+ * @param <I>\r
+ *            Input class for transformation\r
+ * @param <P>\r
+ *            Product of transformation\r
+ */\r
+public interface RuleBasedTransformer<I, P> extends Transformer<I, P> {\r
+\r
+    /**\r
+     * Set of {@link Acceptor}, which could be used to verify if the input is\r
+     * usable by transformer.\r
+     * \r
+     * The transformer is able to produce result if ANY of associated\r
+     * {@link Acceptor}s accepted result.\r
+     * \r
+     * @return Set of input acceptance rules associated to this transformer.\r
+     */\r
+    Set<Acceptor<I>> getRules();\r
+\r
+}\r
diff --git a/opendaylight/commons/concepts/src/main/java/org/opendaylight/controller/concepts/tranform/SimpleConditionalTransformer.java b/opendaylight/commons/concepts/src/main/java/org/opendaylight/controller/concepts/tranform/SimpleConditionalTransformer.java
new file mode 100644 (file)
index 0000000..5a9b555
--- /dev/null
@@ -0,0 +1,38 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+\r
+package org.opendaylight.controller.concepts.tranform;\r
+\r
+/**\r
+ * Simple condition-based transformer\r
+ * \r
+ * The transformer provides {@link #isAcceptable(Object)} method,\r
+ * which could be used to query transformer if the input will produce\r
+ * result.\r
+ * \r
+ * This interface is simplified version of {@link RuleBasedTransformer} - does not\r
+ * provide decoupling of Acceptance rule from transformer, and should be used only\r
+ * for simple use-cases.\r
+ *  \r
+ * @author Tony Tkacik\r
+ *\r
+ * @param <I> Input class for transformation\r
+ * @param <P> Product of transformation\r
+ */\r
+public interface SimpleConditionalTransformer<I,P> extends Transformer<I, P>, Acceptor<I> {\r
+\r
+\r
+    /**\r
+     * Checks if the input is acceptable \r
+     * for processing by the transformer.\r
+     * \r
+     * @return true it the input is acceptable for processing by transformer.\r
+     */\r
+    @Override\r
+    public boolean isAcceptable(I input);\r
+}\r
diff --git a/opendaylight/commons/concepts/src/main/java/org/opendaylight/controller/concepts/tranform/Transformer.java b/opendaylight/commons/concepts/src/main/java/org/opendaylight/controller/concepts/tranform/Transformer.java
new file mode 100644 (file)
index 0000000..58fe0e1
--- /dev/null
@@ -0,0 +1,27 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+\r
+package org.opendaylight.controller.concepts.tranform;\r
+\r
+/**\r
+ * Factory which produces product based on input object\r
+ * \r
+ * @author Tony Tkacik\r
+ *\r
+ * @param <I> Input\r
+ * @param <P> Product\r
+ */\r
+public interface Transformer<I,P> {\r
+    /**\r
+     * Transforms input into instance of product.\r
+     * \r
+     * @param input Input which drives transformation\r
+     * @return Instance of product which was created from supplied input.\r
+     */\r
+    P transform(I input);\r
+}\r
index ddc24b3965f86da8ba65ac8d0f32a45eb12f472e..86725e9d05b388a10a4ee8b29e90ac922650133e 100644 (file)
@@ -97,6 +97,7 @@
     <module>../../samples/simpleforwarding</module>
     <module>../../samples/loadbalancer</module>
     <module>../../samples/northbound/loadbalancer</module>
+    <module>../../commons/concepts</module>
   </modules>
 
   <build>
index 19c756a1cbe231c13fc186986ea4633e015b9333..4997e37a252cb136b9304726f1f0e0298962baf2 100644 (file)
@@ -98,58 +98,58 @@ public class NorthboundIntegrationTest {
     private String getJsonResult(String restUrl, String method) {
         // initialize response code to indicate error
         httpResponseCode = 400;
-        
+
         try {
-          URL url = new URL(restUrl);
-
-          this.users.getAuthorizationList();
-          this.users.authenticate("admin", "admin");
-          String authString = "admin:admin";
-          byte[] authEncBytes = Base64.encodeBase64(authString.getBytes());
-          String authStringEnc = new String(authEncBytes);
-          
-          HttpURLConnection connection = (HttpURLConnection)url.openConnection();
-          connection.setRequestMethod(method);
-          connection.setRequestProperty("Authorization", "Basic "
-                  + authStringEnc);
-          connection.setRequestProperty("Content-Type", "application/json");
-          connection.setRequestProperty("Accept", "application/json");
-
-          connection.connect();
-          connection.getContentType();
-          
-          // Response code for success should be 2xx
-          httpResponseCode = connection.getResponseCode();
-          
-          InputStream is = connection.getInputStream();
-          BufferedReader rd = new BufferedReader(new InputStreamReader(is,
-                  Charset.forName("UTF-8")));
-          StringBuilder sb = new StringBuilder();
-          int cp;
-          while ((cp = rd.read()) != -1) {
-              sb.append((char) cp);
-          }
-          is.close();
-          connection.disconnect();
-          return sb.toString();
-      } catch (Exception e) {
-          return null;
-      }
-      
-  }
+            URL url = new URL(restUrl);
+
+            this.users.getAuthorizationList();
+            this.users.authenticate("admin", "admin");
+            String authString = "admin:admin";
+            byte[] authEncBytes = Base64.encodeBase64(authString.getBytes());
+            String authStringEnc = new String(authEncBytes);
+
+            HttpURLConnection connection = (HttpURLConnection) url
+                    .openConnection();
+            connection.setRequestMethod(method);
+            connection.setRequestProperty("Authorization", "Basic "
+                    + authStringEnc);
+            connection.setRequestProperty("Content-Type", "application/json");
+            connection.setRequestProperty("Accept", "application/json");
+
+            connection.connect();
+            connection.getContentType();
+
+            // Response code for success should be 2xx
+            httpResponseCode = connection.getResponseCode();
+
+            InputStream is = connection.getInputStream();
+            BufferedReader rd = new BufferedReader(new InputStreamReader(is,
+                    Charset.forName("UTF-8")));
+            StringBuilder sb = new StringBuilder();
+            int cp;
+            while ((cp = rd.read()) != -1) {
+                sb.append((char) cp);
+            }
+            is.close();
+            connection.disconnect();
+            return sb.toString();
+        } catch (Exception e) {
+            return null;
+        }
+
+    }
 
     @Test
     public void testStatistics() {
-
+        String actionTypes[] = { "drop", "loopback", "flood", "floodAll",
+                "controller", "swPath", "hwPath", "output", "setDlSrc",
+                "setDlDst", "setDlType", "setVlanId", "setVlanPcp",
+                "setVlanCfi", "popVlan", "pushVlan", "setNwSrc", "setNwDst",
+                "setNwTos", "setTpSrc", "setTpDst" };
         System.out.println("Starting Statistics JAXB client.");
 
         String baseURL = "http://127.0.0.1:8080/controller/nb/v2/statistics/default/";
         try {
-            String actionTypes[] = { "drop", "loopback", "flood", "floodAll",
-                    "controller", "swPath", "hwPath", "output", "setDlSrc",
-                    "setDlDst", "setDlType", "setVlanId", "setVlanPcp",
-                    "setVlanCfi", "popVlan", "pushVlan", "setNwSrc",
-                    "setNwDst", "setNwTos", "setTpSrc", "setTpDst" };
             String result = getJsonResult(baseURL + "flowstats");
             JSONTokener jt = new JSONTokener(result);
             JSONObject json = new JSONObject(jt);
@@ -164,96 +164,8 @@ public class NorthboundIntegrationTest {
             for (int i = 0; i < flowStats.length(); i++) {
 
                 JSONObject flowStat = flowStats.getJSONObject(i);
-                Assert.assertTrue(flowStat.getInt("tableId") == 1);
-                Assert.assertTrue(flowStat.getInt("durationSeconds") == 40);
-                Assert.assertTrue(flowStat.getInt("durationNanoseconds") == 400);
-                Assert.assertTrue(flowStat.getInt("packetCount") == 200);
-                Assert.assertTrue(flowStat.getInt("byteCount") == 100);
-
-                // test that flow information is correct
-                JSONObject flow = flowStat.getJSONObject("flow");
-                Assert.assertTrue(flow.getInt("priority") == 3500);
-                Assert.assertTrue(flow.getInt("idleTimeout") == 1000);
-                Assert.assertTrue(flow.getInt("hardTimeout") == 2000);
-                Assert.assertTrue(flow.getInt("id") == 12345);
-
-                JSONObject match = (flow.getJSONObject("match")
-                        .getJSONObject("matchField"));
-                Assert.assertTrue(match.getString("type").equals("NW_DST"));
-                Assert.assertTrue(match.getString("value").equals("1.1.1.1"));
-
-                JSONObject act = flow.getJSONObject("actions");
-                Assert.assertTrue(act.getString("@type").equals(actionTypes[i]));
-
-                if (act.getString("@type").equals("output")) {
-                    JSONObject port = act.getJSONObject("port");
-                    JSONObject port_node = port.getJSONObject("node");
-                    Assert.assertTrue(port.getInt("@id") == 51966);
-                    Assert.assertTrue(port.getString("@type").equals("STUB"));
-                    Assert.assertTrue(port_node.getInt("@id") == 51966);
-                    Assert.assertTrue(port_node.getString("@type").equals(
-                            "STUB"));
-                }
-
-                if (act.getString("@type").equals("setDlSrc")) {
-                    byte srcMatch[] = { (byte) 5, (byte) 4, (byte) 3, (byte) 2,
-                            (byte) 1 };
-                    String src = act.getString("address");
-                    byte srcBytes[] = new byte[5];
-                    srcBytes[0] = Byte.parseByte(src.substring(0, 2));
-                    srcBytes[1] = Byte.parseByte(src.substring(2, 4));
-                    srcBytes[2] = Byte.parseByte(src.substring(4, 6));
-                    srcBytes[3] = Byte.parseByte(src.substring(6, 8));
-                    srcBytes[4] = Byte.parseByte(src.substring(8, 10));
-                    Assert.assertTrue(Arrays.equals(srcBytes, srcMatch));
-                }
-
-                if (act.getString("@type").equals("setDlDst")) {
-                    byte dstMatch[] = { (byte) 1, (byte) 2, (byte) 3, (byte) 4,
-                            (byte) 5 };
-                    String dst = act.getString("address");
-                    byte dstBytes[] = new byte[5];
-                    dstBytes[0] = Byte.parseByte(dst.substring(0, 2));
-                    dstBytes[1] = Byte.parseByte(dst.substring(2, 4));
-                    dstBytes[2] = Byte.parseByte(dst.substring(4, 6));
-                    dstBytes[3] = Byte.parseByte(dst.substring(6, 8));
-                    dstBytes[4] = Byte.parseByte(dst.substring(8, 10));
-                    Assert.assertTrue(Arrays.equals(dstBytes, dstMatch));
-                }
-                if (act.getString("@type").equals("setDlType"))
-                    Assert.assertTrue(act.getInt("dlType") == 10);
-                if (act.getString("@type").equals("setVlanId"))
-                    Assert.assertTrue(act.getInt("vlanId") == 2);
-                if (act.getString("@type").equals("setVlanPcp"))
-                    Assert.assertTrue(act.getInt("pcp") == 3);
-                if (act.getString("@type").equals("setVlanCfi"))
-                    Assert.assertTrue(act.getInt("cfi") == 1);
-
-                if (act.getString("@type").equals("setNwSrc"))
-                    Assert.assertTrue(act.getString("address")
-                            .equals("2.2.2.2"));
-                if (act.getString("@type").equals("setNwDst"))
-                    Assert.assertTrue(act.getString("address")
-                            .equals("1.1.1.1"));
-
-                if (act.getString("@type").equals("pushVlan")) {
-                    int head = act.getInt("VlanHeader");
-                    // parsing vlan header
-                    int id = head & 0xfff;
-                    int cfi = (head >> 12) & 0x1;
-                    int pcp = (head >> 13) & 0x7;
-                    int tag = (head >> 16) & 0xffff;
-                    Assert.assertTrue(id == 1234);
-                    Assert.assertTrue(cfi == 1);
-                    Assert.assertTrue(pcp == 1);
-                    Assert.assertTrue(tag == 0x8100);
-                }
-                if (act.getString("@type").equals("setNwTos"))
-                    Assert.assertTrue(act.getInt("tos") == 16);
-                if (act.getString("@type").equals("setTpSrc"))
-                    Assert.assertTrue(act.getInt("port") == 4201);
-                if (act.getString("@type").equals("setTpDst"))
-                    Assert.assertTrue(act.getInt("port") == 8080);
+                testFlowStat(flowStat, actionTypes[i]);
+
             }
 
             // for /controller/nb/v2/statistics/default/portstats
@@ -281,8 +193,44 @@ public class NorthboundIntegrationTest {
             Assert.assertTrue(portStat.getInt("receiveCrcError") == 1);
             Assert.assertTrue(portStat.getInt("collisionCount") == 4);
 
-            // String result = getJsonResult(baseURL+"flowstats/STUB/51966");
-            // System.out.println(result);
+            // test for getting one specific node's stats
+            result = getJsonResult(baseURL + "flowstats/STUB/51966");
+            jt = new JSONTokener(result);
+            json = new JSONObject(jt);
+            node = json.getJSONObject("node");
+            // test that node was returned properly
+            Assert.assertTrue(node.getInt("@id") == 0xCAFE);
+            Assert.assertTrue(node.getString("@type").equals("STUB"));
+
+            // test that flow statistics results are correct
+            flowStats = json.getJSONArray("flowStat");
+            for (int i = 0; i < flowStats.length(); i++) {
+                JSONObject flowStat = flowStats.getJSONObject(i);
+                testFlowStat(flowStat, actionTypes[i]);
+            }
+
+            result = getJsonResult(baseURL + "portstats/STUB/51966");
+            jt = new JSONTokener(result);
+            json = new JSONObject(jt);
+            node2 = json.getJSONObject("node");
+            // test that node was returned properly
+            Assert.assertTrue(node2.getInt("@id") == 0xCAFE);
+            Assert.assertTrue(node2.getString("@type").equals("STUB"));
+
+            // test that port statistic results are correct
+            portStat = json.getJSONObject("portStat");
+            Assert.assertTrue(portStat.getInt("receivePackets") == 250);
+            Assert.assertTrue(portStat.getInt("transmitPackets") == 500);
+            Assert.assertTrue(portStat.getInt("receiveBytes") == 1000);
+            Assert.assertTrue(portStat.getInt("transmitBytes") == 5000);
+            Assert.assertTrue(portStat.getInt("receiveDrops") == 2);
+            Assert.assertTrue(portStat.getInt("transmitDrops") == 50);
+            Assert.assertTrue(portStat.getInt("receiveErrors") == 3);
+            Assert.assertTrue(portStat.getInt("transmitErrors") == 10);
+            Assert.assertTrue(portStat.getInt("receiveFrameError") == 5);
+            Assert.assertTrue(portStat.getInt("receiveOverRunError") == 6);
+            Assert.assertTrue(portStat.getInt("receiveCrcError") == 1);
+            Assert.assertTrue(portStat.getInt("collisionCount") == 4);
 
         } catch (Exception e) {
             // Got an unexpected exception
@@ -291,6 +239,100 @@ public class NorthboundIntegrationTest {
         }
     }
 
+    private void testFlowStat(JSONObject flowStat, String actionType) {
+        try {
+            Assert.assertTrue(flowStat.getInt("tableId") == 1);
+            Assert.assertTrue(flowStat.getInt("durationSeconds") == 40);
+            Assert.assertTrue(flowStat.getInt("durationNanoseconds") == 400);
+            Assert.assertTrue(flowStat.getInt("packetCount") == 200);
+            Assert.assertTrue(flowStat.getInt("byteCount") == 100);
+
+            // test that flow information is correct
+            JSONObject flow = flowStat.getJSONObject("flow");
+            Assert.assertTrue(flow.getInt("priority") == 3500);
+            Assert.assertTrue(flow.getInt("idleTimeout") == 1000);
+            Assert.assertTrue(flow.getInt("hardTimeout") == 2000);
+            Assert.assertTrue(flow.getInt("id") == 12345);
+
+            JSONObject match = (flow.getJSONObject("match")
+                    .getJSONObject("matchField"));
+            Assert.assertTrue(match.getString("type").equals("NW_DST"));
+            Assert.assertTrue(match.getString("value").equals("1.1.1.1"));
+
+            JSONObject act = flow.getJSONObject("actions");
+            Assert.assertTrue(act.getString("@type").equals(actionType));
+
+            if (act.getString("@type").equals("output")) {
+                JSONObject port = act.getJSONObject("port");
+                JSONObject port_node = port.getJSONObject("node");
+                Assert.assertTrue(port.getInt("@id") == 51966);
+                Assert.assertTrue(port.getString("@type").equals("STUB"));
+                Assert.assertTrue(port_node.getInt("@id") == 51966);
+                Assert.assertTrue(port_node.getString("@type").equals("STUB"));
+            }
+
+            if (act.getString("@type").equals("setDlSrc")) {
+                byte srcMatch[] = { (byte) 5, (byte) 4, (byte) 3, (byte) 2,
+                        (byte) 1 };
+                String src = act.getString("address");
+                byte srcBytes[] = new byte[5];
+                srcBytes[0] = Byte.parseByte(src.substring(0, 2));
+                srcBytes[1] = Byte.parseByte(src.substring(2, 4));
+                srcBytes[2] = Byte.parseByte(src.substring(4, 6));
+                srcBytes[3] = Byte.parseByte(src.substring(6, 8));
+                srcBytes[4] = Byte.parseByte(src.substring(8, 10));
+                Assert.assertTrue(Arrays.equals(srcBytes, srcMatch));
+            }
+
+            if (act.getString("@type").equals("setDlDst")) {
+                byte dstMatch[] = { (byte) 1, (byte) 2, (byte) 3, (byte) 4,
+                        (byte) 5 };
+                String dst = act.getString("address");
+                byte dstBytes[] = new byte[5];
+                dstBytes[0] = Byte.parseByte(dst.substring(0, 2));
+                dstBytes[1] = Byte.parseByte(dst.substring(2, 4));
+                dstBytes[2] = Byte.parseByte(dst.substring(4, 6));
+                dstBytes[3] = Byte.parseByte(dst.substring(6, 8));
+                dstBytes[4] = Byte.parseByte(dst.substring(8, 10));
+                Assert.assertTrue(Arrays.equals(dstBytes, dstMatch));
+            }
+            if (act.getString("@type").equals("setDlType"))
+                Assert.assertTrue(act.getInt("dlType") == 10);
+            if (act.getString("@type").equals("setVlanId"))
+                Assert.assertTrue(act.getInt("vlanId") == 2);
+            if (act.getString("@type").equals("setVlanPcp"))
+                Assert.assertTrue(act.getInt("pcp") == 3);
+            if (act.getString("@type").equals("setVlanCfi"))
+                Assert.assertTrue(act.getInt("cfi") == 1);
+
+            if (act.getString("@type").equals("setNwSrc"))
+                Assert.assertTrue(act.getString("address").equals("2.2.2.2"));
+            if (act.getString("@type").equals("setNwDst"))
+                Assert.assertTrue(act.getString("address").equals("1.1.1.1"));
+
+            if (act.getString("@type").equals("pushVlan")) {
+                int head = act.getInt("VlanHeader");
+                // parsing vlan header
+                int id = head & 0xfff;
+                int cfi = (head >> 12) & 0x1;
+                int pcp = (head >> 13) & 0x7;
+                int tag = (head >> 16) & 0xffff;
+                Assert.assertTrue(id == 1234);
+                Assert.assertTrue(cfi == 1);
+                Assert.assertTrue(pcp == 1);
+                Assert.assertTrue(tag == 0x8100);
+            }
+            if (act.getString("@type").equals("setNwTos"))
+                Assert.assertTrue(act.getInt("tos") == 16);
+            if (act.getString("@type").equals("setTpSrc"))
+                Assert.assertTrue(act.getInt("port") == 4201);
+            if (act.getString("@type").equals("setTpDst"))
+                Assert.assertTrue(act.getInt("port") == 8080);
+        } catch (Exception e) {
+            Assert.assertTrue(false);
+        }
+    }
+
     // Configure the OSGi container
     @Configuration
     public Option[] config() {
index ff44fd44670d70a876d664ee89f096c90c3cca74..9c47b3b9839dec497ff8dc0d6a23d3e896aad35d 100644 (file)
@@ -7,6 +7,7 @@ import org.apache.felix.dm.Component;
 
 import org.opendaylight.controller.sal.core.ComponentActivatorAbstractBase;
 import org.opendaylight.controller.sal.core.IContainerListener;
+import org.opendaylight.controller.sal.utils.INodeFactory;
 import org.opendaylight.controller.sal.core.Node;
 import org.opendaylight.controller.sal.core.NodeConnector;
 import org.opendaylight.controller.sal.discovery.IDiscoveryService;
@@ -103,7 +104,7 @@ public class Activator extends ComponentActivatorAbstractBase {
     }
     
     public Object[] getGlobalImplementations() {
-        Object[] res = { FlowProgrammerService.class };
+        Object[] res = { FlowProgrammerService.class, StubNodeFactory.class };
         return res;
     }
     
@@ -116,5 +117,14 @@ public class Activator extends ComponentActivatorAbstractBase {
             props.put("protocolPluginType", "STUB");
             c.setInterface(IPluginInFlowProgrammerService.class.getName(), props);
         }
+        if (imp.equals(StubNodeFactory.class)) {
+            // export the service to be used by SAL
+            Dictionary<String, Object> props = new Hashtable<String, Object>();
+            // Set the protocolPluginType property which will be used
+            // by SAL
+            props.put("protocolPluginType", "STUB");
+            props.put("protocolName", "STUB");
+            c.setInterface(INodeFactory.class.getName(), props);
+        }
     }
 }
diff --git a/opendaylight/protocol_plugins/stub/src/main/java/org/opendaylight/controller/protocol_plugins/stub/internal/StubNodeFactory.java b/opendaylight/protocol_plugins/stub/src/main/java/org/opendaylight/controller/protocol_plugins/stub/internal/StubNodeFactory.java
new file mode 100644 (file)
index 0000000..c2ce473
--- /dev/null
@@ -0,0 +1,48 @@
+package org.opendaylight.controller.protocol_plugins.stub.internal;
+
+import org.opendaylight.controller.sal.core.ConstructionException;
+import org.opendaylight.controller.sal.utils.INodeFactory;
+import org.opendaylight.controller.sal.core.Node;
+
+public class StubNodeFactory implements INodeFactory
+    {
+      void init() {
+      }
+
+      /**
+       * Function called by the dependency manager when at least one dependency
+       * become unsatisfied or when the component is shutting down because for
+       * example bundle is being stopped.
+       * 
+       */
+      void destroy() {
+      }
+
+      /**
+       * Function called by dependency manager after "init ()" is called and after
+       * the services provided by the class are registered in the service registry
+       * 
+       */
+      void start() {
+      }
+
+      /**
+       * Function called by the dependency manager before the services exported by
+       * the component are unregistered, this will be followed by a "destroy ()"
+       * calls
+       * 
+       */
+      void stop() {
+      }
+      
+      public Node fromString(String nodeId, String nodeType){
+          if(nodeType.equals("STUB"))
+              try{
+                  return new Node("STUB", Integer.parseInt(nodeId));
+              } catch(ConstructionException e)
+              {
+                  return null;
+              }
+          return null;
+      }
+}
index ea9d93bdb6f0774b2d5c72128648f4431c72b2a8..4c7f278209096e16c857f57c6f49d9da7ea94c9f 100644 (file)
@@ -30,6 +30,8 @@ import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlRootElement;
 
 import org.opendaylight.controller.sal.utils.HexEncode;
+import org.opendaylight.controller.sal.utils.INodeFactory;
+import org.opendaylight.controller.sal.utils.ServiceHelper;
 
 /**
  * Describe a generic network element in multiple SDNs technologies. A
@@ -437,9 +439,13 @@ public class Node implements Serializable {
                 return null;
             }
         } else {
-            // We need to lookup via OSGi service registry for an
-            // handler for this
+            //Use INodeFactory to create a Node of registered Node type.
+            //The protocol plugin being used depends on typeStr.
+            INodeFactory f = (INodeFactory) ServiceHelper
+                    .getGlobalInstance(INodeFactory.class, new Node(), "(protocolName="+typeStr+")");
+            if(f==null)
+                return null;
+            return f.fromString(IDStr, typeStr);
         }
-        return null;
     }
 }
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/INodeFactory.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/INodeFactory.java
new file mode 100644 (file)
index 0000000..29ba7d6
--- /dev/null
@@ -0,0 +1,27 @@
+
+/*
+ * 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.sal.utils;
+
+import org.opendaylight.controller.sal.core.Node;
+
+/**
+ * @file   INodeFactory.java
+ *
+ * @brief  Define the interface to be called when looking up custom node types
+ *
+ */
+
+public interface INodeFactory {
+    /**
+     * Method to get custom node types from protocol plugins
+     *
+     */
+    public Node fromString(String nodeId, String nodeType);
+}