Merge "Fix odl-model-project pom to include correct version of yang-bindings"
authorAlessandro Boch <aboch@cisco.com>
Tue, 12 Nov 2013 20:00:12 +0000 (20:00 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Tue, 12 Nov 2013 20:00:12 +0000 (20:00 +0000)
25 files changed:
opendaylight/distribution/opendaylight/opendaylight-assembleit-fast.launch
opendaylight/distribution/opendaylight/opendaylight-assembleit-full.launch [new file with mode: 0644]
opendaylight/distribution/opendaylight/opendaylight-assembleit-noclean.launch
opendaylight/distribution/opendaylight/opendaylight-assembleit-skiput.launch
opendaylight/distribution/opendaylight/opendaylight-assembleit-sonar.launch
opendaylight/distribution/opendaylight/opendaylight-assembleit.launch
opendaylight/distribution/opendaylight/opendaylight-sonar-fast.launch
opendaylight/distribution/opendaylight/opendaylight-sonar.launch
opendaylight/distribution/opendaylight/pom.xml
opendaylight/md-sal/model/model-flow-statistics/src/main/yang/group-statistics.yang [new file with mode: 0644]
opendaylight/md-sal/model/model-flow-statistics/src/main/yang/meter-statistics.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonMapper.java
opendaylight/netconf/config-persister-impl/pom.xml
opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/ConfigPersisterNotificationHandler.java
opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/AbstractNetconfClientNotifySessionListener.java [new file with mode: 0644]
opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClientDispatcher.java
opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfSshClientDispatcher.java
opendaylight/netconf/netconf-impl/pom.xml
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerDispatcher.java
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfImplActivator.java
opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/ConcurrentClientsTest.java
opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/NetconfDispatcherImplTest.java
opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITSecureTest.java
opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlNetconfConstants.java

index d5e89afe723714a10b9cca31a0ede2fdda9abdb0..bc5c53ca954325ec57242e7d8daf537e06980bf8 100644 (file)
@@ -12,7 +12,7 @@
 <booleanAttribute key="M2_SKIP_TESTS" value="false"/>
 <intAttribute key="M2_THREADS" value="1"/>
 <booleanAttribute key="M2_UPDATE_SNAPSHOTS" value="false"/>
-<booleanAttribute key="M2_WORKSPACE_RESOLUTION" value="true"/>
+<booleanAttribute key="M2_WORKSPACE_RESOLUTION" value="false"/>
 <stringAttribute key="org.eclipse.debug.core.ATTR_REFRESH_SCOPE" value="${working_set:&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;resources&gt;&#10;&lt;item path=&quot;/distribution.opendaylight&quot; type=&quot;4&quot;/&gt;&#10;&lt;/resources&gt;}"/>
 <listAttribute key="org.eclipse.debug.ui.favoriteGroups">
 <listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
diff --git a/opendaylight/distribution/opendaylight/opendaylight-assembleit-full.launch b/opendaylight/distribution/opendaylight/opendaylight-assembleit-full.launch
new file mode 100644 (file)
index 0000000..82b9fe2
--- /dev/null
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<launchConfiguration type="org.eclipse.m2e.Maven2LaunchConfigurationType">
+<booleanAttribute key="M2_DEBUG_OUTPUT" value="false"/>
+<stringAttribute key="M2_GOALS" value="clean install"/>
+<booleanAttribute key="M2_NON_RECURSIVE" value="false"/>
+<booleanAttribute key="M2_OFFLINE" value="false"/>
+<stringAttribute key="M2_PROFILES" value="docs,integrationtests"/>
+<listAttribute key="M2_PROPERTIES"/>
+<stringAttribute key="M2_RUNTIME" value="EMBEDDED"/>
+<booleanAttribute key="M2_SKIP_TESTS" value="false"/>
+<intAttribute key="M2_THREADS" value="1"/>
+<booleanAttribute key="M2_UPDATE_SNAPSHOTS" value="false"/>
+<booleanAttribute key="M2_WORKSPACE_RESOLUTION" value="false"/>
+<stringAttribute key="org.eclipse.debug.core.ATTR_REFRESH_SCOPE" value="${working_set:&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;resources&gt;&#10;&lt;item path=&quot;/distribution.opendaylight&quot; type=&quot;4&quot;/&gt;&#10;&lt;/resources&gt;}"/>
+<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
+<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
+<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
+</listAttribute>
+<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx768m -XX:MaxPermSize=256m"/>
+<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${workspace_loc:/releasepom}"/>
+</launchConfiguration>
index 6900327793271c2e49af306fa79565249fd5fbbe..f42f6577f0fc3359dc3e1b639dab6b3b04f84223 100644 (file)
@@ -10,7 +10,7 @@
 <booleanAttribute key="M2_SKIP_TESTS" value="true"/>
 <intAttribute key="M2_THREADS" value="1"/>
 <booleanAttribute key="M2_UPDATE_SNAPSHOTS" value="false"/>
-<booleanAttribute key="M2_WORKSPACE_RESOLUTION" value="true"/>
+<booleanAttribute key="M2_WORKSPACE_RESOLUTION" value="false"/>
 <stringAttribute key="org.eclipse.debug.core.ATTR_REFRESH_SCOPE" value="${working_set:&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;resources&gt;&#10;&lt;item path=&quot;/distribution.opendaylight&quot; type=&quot;4&quot;/&gt;&#10;&lt;/resources&gt;}"/>
 <listAttribute key="org.eclipse.debug.ui.favoriteGroups">
 <listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
index 15762702a32f1075e68256fd90ea09d2820b5540..753839c0bbe284bae126a5b0fb84391bb18b50a2 100644 (file)
@@ -14,7 +14,7 @@
 <booleanAttribute key="M2_SKIP_TESTS" value="false"/>
 <intAttribute key="M2_THREADS" value="1"/>
 <booleanAttribute key="M2_UPDATE_SNAPSHOTS" value="false"/>
-<booleanAttribute key="M2_WORKSPACE_RESOLUTION" value="true"/>
+<booleanAttribute key="M2_WORKSPACE_RESOLUTION" value="false"/>
 <stringAttribute key="org.eclipse.debug.core.ATTR_REFRESH_SCOPE" value="${working_set:&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;resources&gt;&#10;&lt;item path=&quot;/distribution.opendaylight&quot; type=&quot;4&quot;/&gt;&#10;&lt;/resources&gt;}"/>
 <listAttribute key="org.eclipse.debug.ui.favoriteGroups">
 <listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
index 9134816463f6c707ca01fb0cc9380d3f60cc5e9c..b498f908f2184d6d01c9770fa00779689220b554 100644 (file)
@@ -12,7 +12,7 @@
 <booleanAttribute key="M2_SKIP_TESTS" value="false"/>
 <intAttribute key="M2_THREADS" value="1"/>
 <booleanAttribute key="M2_UPDATE_SNAPSHOTS" value="false"/>
-<booleanAttribute key="M2_WORKSPACE_RESOLUTION" value="true"/>
+<booleanAttribute key="M2_WORKSPACE_RESOLUTION" value="false"/>
 <stringAttribute key="org.eclipse.debug.core.ATTR_REFRESH_SCOPE" value="${working_set:&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;resources&gt;&#10;&lt;item path=&quot;/distribution.opendaylight&quot; type=&quot;4&quot;/&gt;&#10;&lt;/resources&gt;}"/>
 <listAttribute key="org.eclipse.debug.ui.favoriteGroups">
 <listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
index 7d9433399b7fa1cfe6696f5c9feead5fc922904f..0edd2a734ab1cddb92786cf9c7acab8b2a7733df 100644 (file)
@@ -10,7 +10,7 @@
 <booleanAttribute key="M2_SKIP_TESTS" value="false"/>
 <intAttribute key="M2_THREADS" value="1"/>
 <booleanAttribute key="M2_UPDATE_SNAPSHOTS" value="false"/>
-<booleanAttribute key="M2_WORKSPACE_RESOLUTION" value="true"/>
+<booleanAttribute key="M2_WORKSPACE_RESOLUTION" value="false"/>
 <stringAttribute key="org.eclipse.debug.core.ATTR_REFRESH_SCOPE" value="${working_set:&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;resources&gt;&#10;&lt;item path=&quot;/distribution.opendaylight&quot; type=&quot;4&quot;/&gt;&#10;&lt;/resources&gt;}"/>
 <listAttribute key="org.eclipse.debug.ui.favoriteGroups">
 <listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
index 64c3167c540205756635a96811b4b57ad124051e..6d5a588441c02631659daedb915a59e3cab387ea 100644 (file)
@@ -10,7 +10,7 @@
 <booleanAttribute key="M2_SKIP_TESTS" value="false"/>
 <intAttribute key="M2_THREADS" value="1"/>
 <booleanAttribute key="M2_UPDATE_SNAPSHOTS" value="false"/>
-<booleanAttribute key="M2_WORKSPACE_RESOLUTION" value="true"/>
+<booleanAttribute key="M2_WORKSPACE_RESOLUTION" value="false"/>
 <stringAttribute key="org.eclipse.debug.core.ATTR_REFRESH_SCOPE" value="${working_set:&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;resources&gt;&#10;&lt;item path=&quot;/distribution.opendaylight&quot; type=&quot;4&quot;/&gt;&#10;&lt;/resources&gt;}"/>
 <listAttribute key="org.eclipse.debug.ui.favoriteGroups">
 <listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
index e63b9f1133879c640a7c6582402e8439eb14a6e7..bb66bd8a92c2a95cddb193baa0ad1d63fe3c105c 100644 (file)
@@ -10,7 +10,7 @@
 <booleanAttribute key="M2_SKIP_TESTS" value="false"/>
 <intAttribute key="M2_THREADS" value="1"/>
 <booleanAttribute key="M2_UPDATE_SNAPSHOTS" value="false"/>
-<booleanAttribute key="M2_WORKSPACE_RESOLUTION" value="true"/>
+<booleanAttribute key="M2_WORKSPACE_RESOLUTION" value="false"/>
 <stringAttribute key="org.eclipse.debug.core.ATTR_REFRESH_SCOPE" value="${working_set:&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;resources&gt;&#10;&lt;item path=&quot;/distribution.opendaylight&quot; type=&quot;4&quot;/&gt;&#10;&lt;/resources&gt;}"/>
 <listAttribute key="org.eclipse.debug.ui.favoriteGroups">
 <listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
index db4efef0300bf0271b513fd2d5c5d1201e0ab66e..7092f1344137311a3e0c33b40308f53e733af12f 100644 (file)
           <artifactId>sample-toaster-provider</artifactId>
           <version>${mdsal.version}</version>
          </dependency>
-         <dependency>
-          <groupId>org.opendaylight.controller.samples</groupId>
-          <artifactId>sample-toaster-it</artifactId>
-          <version>${mdsal.version}</version>
-         </dependency>
-
          <!-- yangtools dependencies I'm pretty sure we can trim -->
          <dependency>
           <groupId>org.opendaylight.yangtools</groupId>
diff --git a/opendaylight/md-sal/model/model-flow-statistics/src/main/yang/group-statistics.yang b/opendaylight/md-sal/model/model-flow-statistics/src/main/yang/group-statistics.yang
new file mode 100644 (file)
index 0000000..d589f45
--- /dev/null
@@ -0,0 +1,85 @@
+module opendaylight-group-statistics {
+    namespace "urn:opendaylight:group:statistics";
+    prefix groupstat;
+
+    import yang-ext {prefix ext; revision-date "2013-07-09";}
+    import opendaylight-inventory {prefix inv;revision-date "2013-08-19";}
+    import opendaylight-group-types {prefix group-types;revision-date "2013-10-18";}
+    import flow-capable-transaction {prefix tr;}
+    
+    revision "2013-11-11" {
+        description "Initial revision of group statistics service";
+    }
+
+       // RPC calls
+       rpc get-all-group-statistics {
+               input {
+            uses inv:node-context-ref;
+        }
+        output {
+            list group-statistics {
+                uses group-types:group-statistics;
+            }
+            uses tr:transaction-aware;
+        }
+       
+       }
+       
+       rpc get-group-statistics {
+               input {
+            uses inv:node-context-ref;
+            leaf group-id{
+               type group-types:group-id;
+            }
+        }
+        output {
+            uses group-types:group-statistics;
+            uses tr:transaction-aware;
+        }
+       
+       }
+       
+       rpc get-group-description {
+               input {
+            uses inv:node-context-ref;
+            leaf group-id{
+               type group-types:group-id;
+            }
+        }
+        output {
+               uses group-types:group-desc-stats;
+            uses tr:transaction-aware;
+        }
+       }
+       
+       rpc get-group-features {
+               input {
+            uses inv:node-context-ref;
+            leaf group-id{
+               type group-types:group-id;
+            }
+        }
+        output {
+               uses group-types:group-features;
+            uses tr:transaction-aware;
+        }
+       }
+       
+
+       //Notification calls
+       
+       notification group-statistics-updated {
+               uses group-types:group-statistics;
+        uses tr:transaction-aware;
+       }
+       
+       notification group-desc-stats-updated {
+               uses group-types:group-desc-stats;
+        uses tr:transaction-aware;
+       }
+
+       notification group-features {
+               uses group-types:group-features;
+        uses tr:transaction-aware;
+       }
+}
diff --git a/opendaylight/md-sal/model/model-flow-statistics/src/main/yang/meter-statistics.yang b/opendaylight/md-sal/model/model-flow-statistics/src/main/yang/meter-statistics.yang
new file mode 100644 (file)
index 0000000..5aea6b7
--- /dev/null
@@ -0,0 +1,87 @@
+module opendaylight-meter-statistics {
+    namespace "urn:opendaylight:meter:statistics";
+    prefix meterstat;
+
+    import yang-ext {prefix ext; revision-date "2013-07-09";}
+    import opendaylight-inventory {prefix inv;revision-date "2013-08-19";}
+    import opendaylight-meter-types {prefix meter-types;revision-date "2013-09-18";}
+    import flow-capable-transaction {prefix tr;}
+    
+
+    revision "2013-11-11" {
+        description "Initial revision of meter statistics service";
+    }
+
+       // RPC calls
+       rpc get-all-meter-statistics {
+               input {
+            uses inv:node-context-ref;
+        }
+        output {
+            list meter-statistics {
+                uses meter-types:meter-statistics;
+                uses tr:transaction-aware;
+            }
+        }
+       
+       }
+       
+       rpc get-meter-statistics {
+               description "RPC Method to send meter statistics request to the give switch for specific meter"; 
+               input {
+            uses inv:node-context-ref;
+            leaf meter-id{
+               type meter-types:meter-id;
+            }
+        }
+        output {
+            uses meter-types:meter-statistics;
+            uses tr:transaction-aware;
+        }
+       
+       }
+       
+       rpc get-meter-config-statistics {
+               input {
+            uses inv:node-context-ref;
+            leaf meter-id{
+               type meter-types:meter-id;
+            }
+        }
+        output {
+               uses meter-types:meter-config-stats;
+            uses tr:transaction-aware;
+        }
+       }
+       
+       rpc get-meter-features {
+               input {
+            uses inv:node-context-ref;
+            leaf meter-id{
+               type meter-types:meter-id;
+               }
+        }
+        output {
+               uses meter-types:meter-features;
+            uses tr:transaction-aware;
+        }
+       }
+       
+
+       //Notification calls
+       
+       notification meter-statistics-updated {
+               uses meter-types:meter-statistics;
+        uses tr:transaction-aware;
+       }
+       
+       notification meter-config-stats-updated {
+               uses meter-types:meter-config-stats;
+        uses tr:transaction-aware;
+       }
+
+       notification meter-features {
+               uses meter-types:meter-features;
+        uses tr:transaction-aware;
+       }
+}
index 55751e5ac7c33a583ea8d4ea36fdf2a4dbe2ce14..04556bbe547a8d22acd9d8584be1ff4386c1ed5f 100644 (file)
@@ -7,6 +7,8 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
+import javax.activation.UnsupportedDataTypeException;
+
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.opendaylight.yangtools.yang.data.api.Node;
 import org.opendaylight.yangtools.yang.data.api.SimpleNode;
@@ -33,8 +35,18 @@ class JsonMapper {
     
     public void write(JsonWriter writer, CompositeNode data, DataNodeContainer schema) throws IOException {
         writer.beginObject();
-        writeChildrenOfParent(writer, data, schema);
+        
+        if (schema instanceof ContainerSchemaNode) {
+            writeContainer(writer, (CompositeNode) data, (ContainerSchemaNode) schema);
+        } else if (schema instanceof ListSchemaNode) {
+            writeList(writer, (CompositeNode) data, (ListSchemaNode) schema);
+        } else {
+            throw new UnsupportedDataTypeException(
+                    "Schema can be ContainerSchemaNode or ListSchemaNode. Other types are not supported yet.");
+        }
+        
         writer.endObject();
+        
         foundLeafLists.clear();
         foundLists.clear();
     }
@@ -45,6 +57,11 @@ class JsonMapper {
         
         for (Node<?> child : parent.getChildren()) {
             DataSchemaNode childSchema = findSchemaForNode(child, parentSchema.getChildNodes());
+            if (childSchema == null) {
+                throw new UnsupportedDataTypeException("Probably the data node \"" + child.getNodeType().getLocalName()
+                        + "\" is not conform to schema");
+            }
+            
             if (childSchema instanceof ContainerSchemaNode) {
                 writeContainer(writer, (CompositeNode) child, (ContainerSchemaNode) childSchema);
             } else if (childSchema instanceof ListSchemaNode) {
@@ -59,6 +76,9 @@ class JsonMapper {
                 }
             } else if (childSchema instanceof LeafSchemaNode) {
                 writeLeaf(writer, (SimpleNode<?>) child, (LeafSchemaNode) childSchema);
+            } else {
+                throw new UnsupportedDataTypeException("Schema can be ContainerSchemaNode, ListSchemaNode, "
+                        + "LeafListSchemaNode, or LeafSchemaNode. Other types are not supported yet.");
             }
         }
         
@@ -145,7 +165,9 @@ class JsonMapper {
         } else if (type instanceof BooleanTypeDefinition) {
             writer.value(Boolean.parseBoolean(value));
         } else if (type instanceof EmptyTypeDefinition) {
-            writer.value("[null]");
+            writer.beginArray();
+            writer.nullValue();
+            writer.endArray();
         } else {
             writer.value(value);
         }
index 85592e5aa209a717f32c1144a839e8c23eed4e47..21ecd3133949f2665a7132a417b929951692efc5 100644 (file)
@@ -78,6 +78,9 @@
                             org.opendaylight.controller.netconf.client,
                             org.opendaylight.controller.netconf.util.osgi,
                             org.opendaylight.controller.netconf.util.xml,
+                            io.netty.channel,
+                            io.netty.channel.nio,
+                            io.netty.util.concurrent,
                             org.osgi.framework,
                             org.slf4j,
                             org.w3c.dom,
index d390161affd49ac510ac66fe7cca699b2418f2eb..a20e00bcffcc114ab9849b821898280bc743b4b2 100644 (file)
@@ -11,6 +11,8 @@ package org.opendaylight.controller.netconf.persist.impl;
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.Sets;
+import io.netty.channel.EventLoopGroup;
+import io.netty.channel.nio.NioEventLoopGroup;
 import org.opendaylight.controller.config.persist.api.Persister;
 import org.opendaylight.controller.netconf.api.NetconfMessage;
 import org.opendaylight.controller.netconf.api.jmx.CommitJMXNotification;
@@ -53,6 +55,7 @@ public class ConfigPersisterNotificationHandler implements NotificationListener,
 
     private final InetSocketAddress address;
     private final NetconfClientDispatcher dispatcher;
+    private final EventLoopGroup nettyThreadgroup;
 
     private NetconfClient netconfClient;
 
@@ -76,7 +79,9 @@ public class ConfigPersisterNotificationHandler implements NotificationListener,
         this.address = address;
         this.mbeanServer = mbeanServer;
         this.timeout = timeout;
-        this.dispatcher = new NetconfClientDispatcher(Optional.<SSLContext>absent());
+
+        this.nettyThreadgroup = new NioEventLoopGroup();
+        this.dispatcher = new NetconfClientDispatcher(Optional.<SSLContext>absent(), nettyThreadgroup, nettyThreadgroup);
     }
 
     public void init() throws InterruptedException {
@@ -314,9 +319,9 @@ public class ConfigPersisterNotificationHandler implements NotificationListener,
         }
 
         try {
-            dispatcher.close();
+            nettyThreadgroup.shutdownGracefully();
         } catch (Exception e) {
-            logger.warn("Unable to close netconf client dispatcher {}", dispatcher, e);
+            logger.warn("Unable to close netconf client thread group {}", dispatcher, e);
         }
 
         // unregister from JMX
diff --git a/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/AbstractNetconfClientNotifySessionListener.java b/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/AbstractNetconfClientNotifySessionListener.java
new file mode 100644 (file)
index 0000000..48109d1
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * 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.client;
+
+import org.opendaylight.controller.netconf.api.NetconfMessage;
+import org.opendaylight.controller.netconf.util.xml.XmlElement;
+import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
+
+/**
+ * Class extending {@link NetconfClientSessionListener} to provide notification capability.
+ */
+public abstract class AbstractNetconfClientNotifySessionListener extends NetconfClientSessionListener {
+    /*
+     * Maybe some capabilities could be expressed as internal NetconfClientSessionListener handlers.
+     * It would enable NetconfClient functionality to be extended by using namespace handlers.
+     * So far let just enable notification capability by extending and let parent class intact.
+     */
+
+    /**
+     * As class purpose is to provide notification capability to session listener
+     * onMessage method is not allowed to be further overridden.
+     * {@see #onNotification(NetconfClientSession, NetconfMessage)}
+     *
+     * @param session {@see NetconfClientSessionListener#onMessage(NetconfClientSession, NetconfMessage)}
+     * @param message {@see NetconfClientSessionListener#onMessage(NetconfClientSession, NetconfMessage)}
+     */
+    @Override
+    public final synchronized void onMessage(NetconfClientSession session, NetconfMessage message) {
+        if (isNotification(message)) {
+            onNotification(session, message);
+        } else {
+            super.onMessage(session, message);
+        }
+    }
+
+    /**
+     * Method intended to customize notification processing.
+     *
+     * @param session {@see NetconfClientSessionListener#onMessage(NetconfClientSession, NetconfMessage)}
+     * @param message {@see NetconfClientSessionListener#onMessage(NetconfClientSession, NetconfMessage)}
+     */
+    public abstract void onNotification(NetconfClientSession session, NetconfMessage message);
+
+    private boolean isNotification(NetconfMessage message) {
+        XmlElement xmle = XmlElement.fromDomDocument(message.getDocument());
+        return XmlNetconfConstants.NOTIFICATION_ELEMENT_NAME.equals(xmle.getName()) ;
+    }
+}
index d18f0208d4288d87abef3dc7b8de7c1451c1826d..6fc4da026f38acc3add7538f3c172e2c6ee01a0f 100644 (file)
@@ -10,6 +10,7 @@ package org.opendaylight.controller.netconf.client;
 
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
+import io.netty.channel.EventLoopGroup;
 import io.netty.channel.socket.SocketChannel;
 import io.netty.util.HashedWheelTimer;
 import io.netty.util.concurrent.Future;
@@ -32,7 +33,8 @@ public class NetconfClientDispatcher extends AbstractDispatcher<NetconfClientSes
     private final Optional<SSLContext> maybeContext;
     private final NetconfClientSessionNegotiatorFactory negotatorFactory;
 
-    public NetconfClientDispatcher(final Optional<SSLContext> maybeContext) {
+    public NetconfClientDispatcher(final Optional<SSLContext> maybeContext, EventLoopGroup bossGroup, EventLoopGroup workerGroup) {
+        super(bossGroup, workerGroup);
         this.maybeContext = Preconditions.checkNotNull(maybeContext);
         this.negotatorFactory = new NetconfClientSessionNegotiatorFactory(new HashedWheelTimer());
     }
index a42618118335067aca75e88e7566b30ca100fef1..ce0f4274757ac37a1791569b29b95906ec26cd6b 100644 (file)
@@ -8,8 +8,11 @@
 
 package org.opendaylight.controller.netconf.client;
 
+import io.netty.channel.EventLoopGroup;
+
 public class NetconfSshClientDispatcher extends NetconfClientDispatcher {
-    public NetconfSshClientDispatcher() {
-        super(null);
+
+    public NetconfSshClientDispatcher(EventLoopGroup bossGroup, EventLoopGroup workerGroup) {
+        super(null, bossGroup, workerGroup);
     }
 }
index 33fa675a926677245ae6583acc5106c9327f179c..f1e3f891ee3ff70bda9cfd9fefcc73c714a824e3 100644 (file)
                             io.netty.util.concurrent,
                             io.netty.buffer,
                             io.netty.handler.codec,
+                            io.netty.channel.nio,
                             javax.management,
                             javax.net.ssl,
                             javax.xml.namespace,
index c73840132f67856b296de749cbe60a961a6a2023..882d368a1af3648b06579903769d48026ecdf38c 100644 (file)
@@ -10,6 +10,7 @@ package org.opendaylight.controller.netconf.impl;
 
 import com.google.common.base.Optional;
 import io.netty.channel.ChannelFuture;
+import io.netty.channel.EventLoopGroup;
 import io.netty.channel.socket.SocketChannel;
 import io.netty.util.concurrent.Promise;
 import org.opendaylight.controller.netconf.api.NetconfSession;
@@ -25,14 +26,12 @@ public class NetconfServerDispatcher extends AbstractDispatcher<NetconfSession,
 
     private final ServerSslChannelInitializer initializer;
 
-    public NetconfServerDispatcher(final Optional<SSLContext> maybeContext,
-            NetconfServerSessionNegotiatorFactory serverNegotiatorFactory,
-            NetconfServerSessionListenerFactory listenerFactory) {
-        this.initializer = new ServerSslChannelInitializer(maybeContext, serverNegotiatorFactory, listenerFactory);
+    public NetconfServerDispatcher(ServerSslChannelInitializer serverChannelInitializer, EventLoopGroup bossGroup,
+            EventLoopGroup workerGroup) {
+        super(bossGroup, workerGroup);
+        this.initializer = serverChannelInitializer;
     }
 
-    // FIXME change headers for all new source code files
-
     // TODO test create server with same address twice
     public ChannelFuture createServer(InetSocketAddress address) {
 
@@ -44,12 +43,12 @@ public class NetconfServerDispatcher extends AbstractDispatcher<NetconfSession,
         });
     }
 
-    private static class ServerSslChannelInitializer extends AbstractSslChannelInitializer {
+    public static class ServerSslChannelInitializer extends AbstractSslChannelInitializer {
 
         private final NetconfServerSessionNegotiatorFactory negotiatorFactory;
         private final NetconfServerSessionListenerFactory listenerFactory;
 
-        private ServerSslChannelInitializer(Optional<SSLContext> maybeContext,
+        public ServerSslChannelInitializer(Optional<SSLContext> maybeContext,
                                             NetconfServerSessionNegotiatorFactory negotiatorFactory,
                                             NetconfServerSessionListenerFactory listenerFactory) {
             super(maybeContext);
index fc240f91c9d168397a82c82f42577310aeb5b408..1a4888ba93b69081ab0d584a1730c7b74d84ed37 100644 (file)
@@ -8,6 +8,7 @@
 package org.opendaylight.controller.netconf.impl.osgi;
 
 import com.google.common.base.Optional;
+import io.netty.channel.nio.NioEventLoopGroup;
 import io.netty.util.HashedWheelTimer;
 import org.opendaylight.controller.netconf.impl.DefaultCommitNotificationProducer;
 import org.opendaylight.controller.netconf.impl.NetconfServerDispatcher;
@@ -35,6 +36,7 @@ public class NetconfImplActivator implements BundleActivator {
     private NetconfOperationServiceFactoryTracker factoriesTracker;
     private DefaultCommitNotificationProducer commitNot;
     private NetconfServerDispatcher dispatch;
+    private NioEventLoopGroup eventLoopGroup;
 
     @Override
     public void start(final BundleContext context) throws Exception {
@@ -56,10 +58,14 @@ public class NetconfImplActivator implements BundleActivator {
         NetconfServerSessionListenerFactory listenerFactory = new NetconfServerSessionListenerFactory(
                 factoriesListener, commitNot, idProvider);
 
+        eventLoopGroup = new NioEventLoopGroup();
+
         if (maybeTCPAddress.isPresent()) {
             Optional<SSLContext> maybeSSLContext = Optional.absent();
             InetSocketAddress address = maybeTCPAddress.get();
-            dispatch = new NetconfServerDispatcher(maybeSSLContext, serverNegotiatorFactory, listenerFactory);
+            NetconfServerDispatcher.ServerSslChannelInitializer serverChannelInitializer = new NetconfServerDispatcher.ServerSslChannelInitializer(
+                    maybeSSLContext, serverNegotiatorFactory, listenerFactory);
+            dispatch = new NetconfServerDispatcher(serverChannelInitializer, eventLoopGroup, eventLoopGroup);
 
             logger.info("Starting TCP netconf server at {}", address);
             dispatch.createServer(address);
@@ -67,7 +73,9 @@ public class NetconfImplActivator implements BundleActivator {
         if (maybeTLSConfiguration.isPresent()) {
             Optional<SSLContext> maybeSSLContext = Optional.of(maybeTLSConfiguration.get().getSslContext());
             InetSocketAddress address = maybeTLSConfiguration.get().getAddress();
-            dispatch = new NetconfServerDispatcher(maybeSSLContext, serverNegotiatorFactory, listenerFactory);
+            NetconfServerDispatcher.ServerSslChannelInitializer serverChannelInitializer = new NetconfServerDispatcher.ServerSslChannelInitializer(
+                    maybeSSLContext, serverNegotiatorFactory, listenerFactory);
+            dispatch = new NetconfServerDispatcher(serverChannelInitializer, eventLoopGroup, eventLoopGroup);
 
             logger.info("Starting TLS netconf server at {}", address);
             dispatch.createServer(address);
@@ -79,6 +87,6 @@ public class NetconfImplActivator implements BundleActivator {
         logger.info("Shutting down netconf because YangStoreService service was removed");
 
         commitNot.close();
-        dispatch.close();
+        eventLoopGroup.shutdownGracefully();
     }
 }
index 1295149c0262a7982226c3ae71195b5538fe0155..b363976aaed6b6afd8f3aa4c9844ffb5357a661c 100644 (file)
@@ -11,6 +11,8 @@ package org.opendaylight.controller.netconf.impl;
 import com.google.common.base.Optional;
 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 org.apache.commons.io.IOUtils;
 import org.junit.After;
@@ -64,7 +66,10 @@ import static org.mockito.Mockito.mock;
 public class ConcurrentClientsTest {
 
     private static final int CONCURRENCY = 16;
-    public static final NetconfClientDispatcher NETCONF_CLIENT_DISPATCHER = new NetconfClientDispatcher(Optional.<SSLContext>absent());
+    private static EventLoopGroup nettyGroup = new NioEventLoopGroup();
+    public static final NetconfClientDispatcher NETCONF_CLIENT_DISPATCHER = new NetconfClientDispatcher(
+            Optional.<SSLContext> absent(), nettyGroup, nettyGroup);
+
     @Mock
     private YangStoreService yangStoreService;
     @Mock
@@ -77,6 +82,7 @@ public class ConcurrentClientsTest {
     private DefaultCommitNotificationProducer commitNot;
     private NetconfServerDispatcher dispatch;
 
+
     @Before
     public void setUp() throws Exception {
         { // init mocks
@@ -103,7 +109,9 @@ public class ConcurrentClientsTest {
 
         NetconfServerSessionListenerFactory listenerFactory = new NetconfServerSessionListenerFactory(
                 factoriesListener, commitNot, idProvider);
-        dispatch = new NetconfServerDispatcher(Optional.<SSLContext> absent(), serverNegotiatorFactory, listenerFactory);
+        NetconfServerDispatcher.ServerSslChannelInitializer serverChannelInitializer = new NetconfServerDispatcher.ServerSslChannelInitializer(
+                Optional.<SSLContext> absent(), serverNegotiatorFactory, listenerFactory);
+        dispatch = new NetconfServerDispatcher(serverChannelInitializer, nettyGroup, nettyGroup);
 
         ChannelFuture s = dispatch.createServer(netconfAddress);
         s.await();
@@ -111,7 +119,7 @@ public class ConcurrentClientsTest {
 
     @AfterClass
     public static void tearDownStatic() {
-        NETCONF_CLIENT_DISPATCHER.close();
+        nettyGroup.shutdownGracefully();
     }
 
     private NetconfOperationServiceFactory mockOpF() {
@@ -160,7 +168,6 @@ public class ConcurrentClientsTest {
     @After
     public void cleanUp() throws Exception {
         commitNot.close();
-        dispatch.close();
     }
 
     @Test
index 233fffda024a30deedcd2bd9ad5a9a343ea327c7..e43febec793f6ad43029169ed083c7ede7f22a4d 100644 (file)
@@ -8,22 +8,35 @@
 
 package org.opendaylight.controller.netconf.impl;
 
-import java.lang.management.ManagementFactory;
-import java.net.InetSocketAddress;
-
-import javax.net.ssl.SSLContext;
-
+import com.google.common.base.Optional;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.EventLoopGroup;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.util.HashedWheelTimer;
+import org.junit.After;
+import org.junit.Before;
 import org.junit.Test;
 import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceFactoryListener;
 import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceFactoryListenerImpl;
 
-import com.google.common.base.Optional;
-
-import io.netty.channel.ChannelFuture;
-import io.netty.util.HashedWheelTimer;
+import javax.net.ssl.SSLContext;
+import java.lang.management.ManagementFactory;
+import java.net.InetSocketAddress;
 
 public class NetconfDispatcherImplTest {
 
+    private EventLoopGroup nettyGroup;
+
+    @Before
+    public void setUp() throws Exception {
+        nettyGroup = new NioEventLoopGroup();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        nettyGroup.shutdownGracefully();
+    }
+
     @Test
     public void test() throws Exception {
 
@@ -37,13 +50,15 @@ public class NetconfDispatcherImplTest {
 
         NetconfServerSessionListenerFactory listenerFactory = new NetconfServerSessionListenerFactory(
                 factoriesListener, commitNot, idProvider);
-        NetconfServerDispatcher dispatch = new NetconfServerDispatcher(Optional.<SSLContext> absent(),
-                serverNegotiatorFactory, listenerFactory);
+        NetconfServerDispatcher.ServerSslChannelInitializer serverChannelInitializer = new NetconfServerDispatcher.ServerSslChannelInitializer(Optional.<SSLContext>absent(), serverNegotiatorFactory, listenerFactory);
+
+
+        NetconfServerDispatcher dispatch = new NetconfServerDispatcher(
+                serverChannelInitializer, nettyGroup, nettyGroup);
 
         InetSocketAddress addr = new InetSocketAddress("127.0.0.1", 8333);
         ChannelFuture s = dispatch.createServer(addr);
 
         commitNot.close();
-        dispatch.close();
     }
 }
index 9a4bc2aa5dee09092f7cf04412383d4f62d00dc1..0c22a71c6b38e20b96da5163a26bed1a1b94e30b 100644 (file)
@@ -10,6 +10,8 @@ package org.opendaylight.controller.netconf.it;
 
 import com.google.common.base.Optional;
 import io.netty.channel.ChannelFuture;
+import io.netty.channel.EventLoopGroup;
+import io.netty.channel.nio.NioEventLoopGroup;
 import io.netty.util.HashedWheelTimer;
 import org.junit.After;
 import org.junit.Before;
@@ -51,6 +53,8 @@ public class NetconfITSecureTest extends AbstractConfigTest {
 
     private DefaultCommitNotificationProducer commitNot;
     private NetconfServerDispatcher dispatchS;
+    private EventLoopGroup nettyThreadgroup;
+
 
     @Before
     public void setUp() throws Exception {
@@ -62,6 +66,8 @@ public class NetconfITSecureTest extends AbstractConfigTest {
 
         commitNot = new DefaultCommitNotificationProducer(ManagementFactory.getPlatformMBeanServer());
 
+        nettyThreadgroup = new NioEventLoopGroup();
+
         dispatchS = createDispatcher(Optional.of(getSslContext()), factoriesListener);
         ChannelFuture s = dispatchS.createServer(tlsAddress);
         s.await();
@@ -76,13 +82,15 @@ public class NetconfITSecureTest extends AbstractConfigTest {
         NetconfServerSessionListenerFactory listenerFactory = new NetconfServerSessionListenerFactory(
                 factoriesListener, commitNot, idProvider);
 
-        return new NetconfServerDispatcher(sslC, serverNegotiatorFactory, listenerFactory);
+        NetconfServerDispatcher.ServerSslChannelInitializer serverChannelInitializer = new NetconfServerDispatcher.ServerSslChannelInitializer(
+                sslC, serverNegotiatorFactory, listenerFactory);
+        return new NetconfServerDispatcher(serverChannelInitializer, nettyThreadgroup, nettyThreadgroup);
     }
 
     @After
     public void tearDown() throws Exception {
         commitNot.close();
-        dispatchS.close();
+        nettyThreadgroup.shutdownGracefully();
     }
 
     private SSLContext getSslContext() throws KeyStoreException, NoSuchAlgorithmException, CertificateException,
@@ -106,8 +114,8 @@ public class NetconfITSecureTest extends AbstractConfigTest {
 
     @Test
     public void testSecure() throws Exception {
-        try (NetconfClientDispatcher dispatch = new NetconfClientDispatcher(Optional.of(getSslContext()));
-             NetconfClient netconfClient = new NetconfClient("tls-client", tlsAddress, 4000, dispatch))  {
+        NetconfClientDispatcher dispatch = new NetconfClientDispatcher(Optional.of(getSslContext()), nettyThreadgroup, nettyThreadgroup);
+        try (NetconfClient netconfClient = new NetconfClient("tls-client", tlsAddress, 4000, dispatch))  {
 
         }
     }
index e9fe857bcac571501900dc2111edc2d4567bbe80..403ba3d0fc090ea06e9ce73c4ff4acc2b7fc32c5 100644 (file)
@@ -12,9 +12,10 @@ import com.google.common.base.Optional;
 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 org.junit.After;
-import org.junit.AfterClass;
 import org.junit.Before;
 import org.junit.Ignore;
 import org.junit.Test;
@@ -90,8 +91,9 @@ public class NetconfITTest extends AbstractConfigTest {
             closeSession, startExi, stopExi;
     private DefaultCommitNotificationProducer commitNot;
     private NetconfServerDispatcher dispatch;
+    private EventLoopGroup nettyThreadgroup;
 
-    private static NetconfClientDispatcher NETCONF_CLIENT_DISPATCHER = new NetconfClientDispatcher(Optional.<SSLContext>absent());
+    private NetconfClientDispatcher clientDispatcher;
 
     @Before
     public void setUp() throws Exception {
@@ -103,11 +105,15 @@ public class NetconfITTest extends AbstractConfigTest {
         NetconfOperationServiceFactoryListenerImpl factoriesListener = new NetconfOperationServiceFactoryListenerImpl();
         factoriesListener.onAddNetconfOperationServiceFactory(new NetconfOperationServiceFactoryImpl(getYangStore()));
 
+        nettyThreadgroup = new NioEventLoopGroup();
+
         commitNot = new DefaultCommitNotificationProducer(ManagementFactory.getPlatformMBeanServer());
 
         dispatch = createDispatcher(Optional.<SSLContext> absent(), factoriesListener);
         ChannelFuture s = dispatch.createServer(tcpAddress);
         s.await();
+
+        clientDispatcher = new NetconfClientDispatcher(Optional.<SSLContext>absent(), nettyThreadgroup, nettyThreadgroup);
     }
 
     private NetconfServerDispatcher createDispatcher(Optional<SSLContext> sslC,
@@ -119,18 +125,15 @@ public class NetconfITTest extends AbstractConfigTest {
         NetconfServerSessionListenerFactory listenerFactory = new NetconfServerSessionListenerFactory(
                 factoriesListener, commitNot, idProvider);
 
-        return new NetconfServerDispatcher(sslC, serverNegotiatorFactory, listenerFactory);
+        NetconfServerDispatcher.ServerSslChannelInitializer serverChannelInitializer = new NetconfServerDispatcher.ServerSslChannelInitializer(
+                sslC, serverNegotiatorFactory, listenerFactory);
+        return new NetconfServerDispatcher(serverChannelInitializer, nettyThreadgroup, nettyThreadgroup);
     }
 
     @After
     public void tearDown() throws Exception {
         commitNot.close();
-        dispatch.close();
-    }
-
-    @AfterClass
-    public static void tearDownStatic() {
-        NETCONF_CLIENT_DISPATCHER.close();
+        nettyThreadgroup.shutdownGracefully();
     }
 
     private void loadMessages() throws IOException, SAXException, ParserConfigurationException {
@@ -171,7 +174,7 @@ public class NetconfITTest extends AbstractConfigTest {
 
     @Test
     public void testNetconfClientDemonstration() throws Exception {
-        try (NetconfClient netconfClient = new NetconfClient("client", tcpAddress, 4000, NETCONF_CLIENT_DISPATCHER)) {
+        try (NetconfClient netconfClient = new NetconfClient("client", tcpAddress, 4000, clientDispatcher)) {
 
             Set<String> capabilitiesFromNetconfServer = netconfClient.getCapabilities();
             long sessionId = netconfClient.getSessionId();
@@ -186,8 +189,8 @@ public class NetconfITTest extends AbstractConfigTest {
 
     @Test
     public void testTwoSessions() throws Exception {
-        try (NetconfClient netconfClient = new NetconfClient("1", tcpAddress, 4000, NETCONF_CLIENT_DISPATCHER))  {
-            try (NetconfClient netconfClient2 = new NetconfClient("2", tcpAddress, 4000, NETCONF_CLIENT_DISPATCHER))  {
+        try (NetconfClient netconfClient = new NetconfClient("1", tcpAddress, 4000, clientDispatcher))  {
+            try (NetconfClient netconfClient2 = new NetconfClient("2", tcpAddress, 4000, clientDispatcher))  {
             }
         }
     }
@@ -387,7 +390,7 @@ public class NetconfITTest extends AbstractConfigTest {
         // final InputStream resourceAsStream =
         // AbstractListenerTest.class.getResourceAsStream(fileName);
         // assertNotNull(resourceAsStream);
-        try (NetconfClient netconfClient = new NetconfClient("test", tcpAddress, 5000, NETCONF_CLIENT_DISPATCHER)) {
+        try (NetconfClient netconfClient = new NetconfClient("test", tcpAddress, 5000, clientDispatcher)) {
             // IOUtils.copy(resourceAsStream, netconfClient.getStream());
             // netconfClient.getOutputStream().write(NetconfMessageFactory.endOfMessage);
             // server should not write anything back
@@ -436,7 +439,7 @@ public class NetconfITTest extends AbstractConfigTest {
     }
 
     private NetconfClient createSession(final InetSocketAddress address, final String expected) throws Exception {
-        final NetconfClient netconfClient = new NetconfClient("test " + address.toString(), address, 5000, NETCONF_CLIENT_DISPATCHER);
+        final NetconfClient netconfClient = new NetconfClient("test " + address.toString(), address, 5000, clientDispatcher);
         assertEquals(expected, Long.toString(netconfClient.getSessionId()));
         return netconfClient;
     }
index 3e862faa7b34c96378002d17d79350fb0d4f45d7..2a900e052bcf9ba378c5e7a39c1de8f8bfd0dbbf 100644 (file)
@@ -31,6 +31,8 @@ public class XmlNetconfConstants {
     public static final String RPC_REPLY_KEY = "rpc-reply";
     public static final String RPC_ERROR = "rpc-error";
     public static final String NAME_KEY = "name";
+    public static final String NOTIFICATION_ELEMENT_NAME = "notification";
+
     //
     //
     public static final String RFC4741_TARGET_NAMESPACE = "urn:ietf:params:xml:ns:netconf:base:1.0";