BUG 2920: Extend and simplify netconf connector topology model. 16/25416/26
authorTomas Cere <tcere@cisco.com>
Mon, 17 Aug 2015 13:14:29 +0000 (15:14 +0200)
committerTomas Cere <tcere@cisco.com>
Thu, 15 Oct 2015 10:28:53 +0000 (12:28 +0200)
Add shared schema repository and netconf topology binding.
Create a default schema repository instance.
Add topology config.
Simplifiy netconf connector model to use new netconf
topology with backwards compatibility.
Bump netconf connector schema revision.

Change-Id: I3978a0a7e6e3c08dba52e65912bfe33ad46b4cf8
Signed-off-by: Tomas Cere <tcere@cisco.com>
25 files changed:
features/netconf-connector/pom.xml
features/netconf-connector/src/main/resources/features.xml
opendaylight/netconf/netconf-artifacts/pom.xml
opendaylight/netconf/netconf-connector-config/src/main/resources/initial/99-netconf-connector.xml
opendaylight/netconf/netconf-topology-config/pom.xml [new file with mode: 0644]
opendaylight/netconf/netconf-topology-config/src/main/resources/initial/02-netconf-topology.xml [new file with mode: 0644]
opendaylight/netconf/netconf-topology/pom.xml [new file with mode: 0644]
opendaylight/netconf/netconf-topology/src/main/java/org/opendaylight/controller/config/yang/netconf/topology/NetconfTopologyModule.java [new file with mode: 0644]
opendaylight/netconf/netconf-topology/src/main/java/org/opendaylight/controller/config/yang/netconf/topology/NetconfTopologyModuleFactory.java [new file with mode: 0644]
opendaylight/netconf/netconf-topology/src/main/java/org/opendaylight/controller/config/yang/netconf/topology/shared/schema/repository/SchemaRepositoryImplModule.java [new file with mode: 0644]
opendaylight/netconf/netconf-topology/src/main/java/org/opendaylight/controller/config/yang/netconf/topology/shared/schema/repository/SchemaRepositoryImplModuleFactory.java [new file with mode: 0644]
opendaylight/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/NetconfTopology.java [new file with mode: 0644]
opendaylight/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/SchemaRepositoryProvider.java [new file with mode: 0644]
opendaylight/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/TopologyMountPointFacade.java [new file with mode: 0644]
opendaylight/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/impl/NetconfTopologyImpl.java [new file with mode: 0644]
opendaylight/netconf/netconf-topology/src/main/yang/netconf-topology.yang [new file with mode: 0644]
opendaylight/netconf/netconf-topology/src/main/yang/shared-schema-repository.yang [new file with mode: 0644]
opendaylight/netconf/pom.xml
opendaylight/netconf/sal-netconf-connector/pom.xml
opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/connector/netconf/NetconfConnectorModule.java
opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/connector/netconf/NetconfConnectorModuleFactory.java
opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceDataBroker.java
opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceNotificationService.java
opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceSalProvider.java
opendaylight/netconf/sal-netconf-connector/src/main/yang/odl-sal-netconf-connector-cfg.yang

index fe50cec1e41f1ca79cd2a7ffca692263bb9679a6..479309522b3d27b327e33551464f0dd14d403cd4 100644 (file)
@@ -19,6 +19,7 @@
    <packaging>jar</packaging>
    <properties>
       <features.file>features.xml</features.file>
+      <netconf.connector.version>1.3.0-SNAPSHOT</netconf.connector.version>
    </properties>
 
    <dependencyManagement>
       <groupId>${project.groupId}</groupId>
       <artifactId>netconf-connector-config</artifactId>
     </dependency>
+    <dependency>
+       <groupId>${project.groupId}</groupId>
+       <artifactId>netconf-topology</artifactId>
+    </dependency>
+    <dependency>
+       <groupId>${project.groupId}</groupId>
+       <artifactId>netconf-topology-config</artifactId>
+       <classifier>config</classifier>
+       <type>xml</type>
+    </dependency>
     <dependency>
       <groupId>${project.groupId}</groupId>
       <artifactId>netconf-tcp</artifactId>
index eb8daa622e875f5e10e7bd12e95fcb87025e798c..0f8d35d669c9953abf8be245dce08af52ab084b4 100644 (file)
         <feature version='${yangtools.version}'>odl-mdsal-models</feature>
         <bundle>mvn:org.opendaylight.netconf/sal-netconf-connector/${controller.mdsal.version}</bundle>
         <bundle>mvn:org.opendaylight.controller.model/model-inventory/${controller.mdsal.version}</bundle>
+        <bundle>mvn:org.opendaylight.netconf/netconf-topology/${netconf.version}</bundle>
+        <bundle>mvn:org.opendaylight.netconf/sal-netconf-connector/${netconf.connector.version}</bundle>
+        <bundle>mvn:org.opendaylight.netconf/netconf-config-dispatcher/${netconf.version}</bundle>
+        <configfile finalname='${config.configfile.directory}/${config.netconf.client.configfile}'>mvn:org.opendaylight.netconf/netconf-config/${netconf.version}/xml/config</configfile>
+        <configfile finalname='${config.configfile.directory}/${config.netconf.topology.configfile}'>mvn:org.opendaylight.netconf/netconf-topology-config/${netconf.version}/xml/config</configfile>
     </feature>
 
     <feature name='odl-netconf-connector-ssh' version='${project.version}' description="OpenDaylight :: Netconf Connector :: Netconf Connector + Netconf SSH Server + loopback connection configuration">
index 00c55acf65a122b1952520f01ca9788de1fe0dd7..8a223c4317914720ae36cbd74fdf858a6427c600 100644 (file)
                 <artifactId>mdsal-netconf-notification</artifactId>
                 <version>${project.version}</version>
             </dependency>
+            <dependency>
+                <groupId>${project.groupId}</groupId>
+                <artifactId>netconf-topology</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>${project.groupId}</groupId>
+                <artifactId>netconf-topology-config</artifactId>
+                <version>${project.version}</version>
+                <classifier>config</classifier>
+                <type>xml</type>
+            </dependency>
             <dependency>
                 <groupId>${project.groupId}</groupId>
                 <artifactId>netconf-client</artifactId>
index d743bbcd40249da36e421733e9ad7224e43c2ae7..62b2c8de44b19fb3819af57f79cdde05eafbd5aa 100644 (file)
@@ -50,6 +50,6 @@
     </data>
   </configuration>
   <required-capabilities>
-      <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf?module=odl-sal-netconf-connector-cfg&amp;revision=2013-10-28</capability>
+      <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf?module=odl-sal-netconf-connector-cfg&amp;revision=2015-08-03</capability>
   </required-capabilities>
 </snapshot>
diff --git a/opendaylight/netconf/netconf-topology-config/pom.xml b/opendaylight/netconf/netconf-topology-config/pom.xml
new file mode 100644 (file)
index 0000000..9858f6c
--- /dev/null
@@ -0,0 +1,43 @@
+<?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">
+    <parent>
+        <artifactId>netconf-subsystem</artifactId>
+        <groupId>org.opendaylight.netconf</groupId>
+        <version>1.0.0-SNAPSHOT</version>
+        <relativePath>../</relativePath>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>netconf-topology-config</artifactId>
+    <description>Configuration files for netconf topology</description>
+    <packaging>jar</packaging>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>build-helper-maven-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>attach-artifacts</id>
+                        <goals>
+                            <goal>attach-artifact</goal>
+                        </goals>
+                        <phase>package</phase>
+                        <configuration>
+                            <artifacts>
+                                <artifact>
+                                    <file>${project.build.directory}/classes/initial/02-netconf-topology.xml</file>
+                                    <type>xml</type>
+                                    <classifier>config</classifier>
+                                </artifact>
+                            </artifacts>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file
diff --git a/opendaylight/netconf/netconf-topology-config/src/main/resources/initial/02-netconf-topology.xml b/opendaylight/netconf/netconf-topology-config/src/main/resources/initial/02-netconf-topology.xml
new file mode 100644 (file)
index 0000000..b4581c4
--- /dev/null
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<!--
+ Copyright (c) 2015 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
+-->
+<snapshot>
+    <configuration>
+        <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+            <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+                <module>
+                    <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netconf:topology">prefix:netconf-topology-impl</type>
+                    <name>default-netconf-topology</name>
+                    <event-executor xmlns="urn:opendaylight:params:xml:ns:yang:controller:netconf:topology">
+                        <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty">prefix:netty-event-executor</type>
+                        <name>global-event-executor</name>
+                    </event-executor>
+                    <binding-registry xmlns="urn:opendaylight:params:xml:ns:yang:controller:netconf:topology">
+                        <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">prefix:binding-broker-osgi-registry</type>
+                        <name>binding-osgi-broker</name>
+                    </binding-registry>
+                    <dom-registry xmlns="urn:opendaylight:params:xml:ns:yang:controller:netconf:topology">
+                        <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">prefix:dom-broker-osgi-registry</type>
+                        <name>dom-broker</name>
+                    </dom-registry>
+                    <client-dispatcher xmlns="urn:opendaylight:params:xml:ns:yang:controller:netconf:topology">
+                        <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:netconf">prefix:netconf-client-dispatcher</type>
+                        <name>global-netconf-dispatcher</name>
+                    </client-dispatcher>
+                    <processing-executor xmlns="urn:opendaylight:params:xml:ns:yang:controller:netconf:topology">
+                        <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool">prefix:threadpool</type>
+                        <name>global-netconf-processing-executor</name>
+                    </processing-executor>
+                    <keepalive-executor xmlns="urn:opendaylight:params:xml:ns:yang:controller:netconf:topology">
+                        <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool">prefix:scheduled-threadpool</type>
+                        <name>global-netconf-ssh-scheduled-executor</name>
+                    </keepalive-executor>
+                    <shared-schema-repository xmlns="urn:opendaylight:params:xml:ns:yang:controller:netconf:topology">
+                        <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netconf:topology:shared:schema:repository">prefix:shared-schema-repository</type>
+                        <name>default-shared-schema-repository</name>
+                    </shared-schema-repository>
+                </module>
+            </modules>
+
+            <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+                <service>
+                    <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netconf:topology">prefix:netconf-topology</type>
+                    <instance>
+                        <name>default-netconf-topology</name>
+                        <provider>/modules/module[type='netconf-topology-impl'][name='default-netconf-topology']</provider>
+                    </instance>
+                </service>
+            </services>
+        </data>
+    </configuration>
+    <required-capabilities>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:netconf:topology?module=netconf-topology&amp;revision=2015-07-27</capability>
+    </required-capabilities>
+</snapshot>
\ No newline at end of file
diff --git a/opendaylight/netconf/netconf-topology/pom.xml b/opendaylight/netconf/netconf-topology/pom.xml
new file mode 100644 (file)
index 0000000..89202d8
--- /dev/null
@@ -0,0 +1,123 @@
+<?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">
+    <parent>
+        <artifactId>netconf-subsystem</artifactId>
+        <groupId>org.opendaylight.netconf</groupId>
+        <version>1.0.0-SNAPSHOT</version>
+        <relativePath>../</relativePath>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>netconf-topology</artifactId>
+    <packaging>bundle</packaging>
+    <dependencies>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>sal-binding-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>sal-binding-config</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.mdsal</groupId>
+            <artifactId>mdsal-binding-generator-impl</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>netconf-config-dispatcher</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>sal-core-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>threadpool-config-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.yangtools</groupId>
+            <artifactId>yang-parser-impl</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>yang-jmx-generator-plugin</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.netconf</groupId>
+            <artifactId>sal-netconf-connector</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <configuration>
+                    <instructions>
+                        <Import-Package>*</Import-Package>
+                    </instructions>
+                </configuration>
+            </plugin>
+
+            <plugin>
+                <groupId>org.opendaylight.yangtools</groupId>
+                <artifactId>yang-maven-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>config</id>
+                        <goals>
+                            <goal>generate-sources</goal>
+                        </goals>
+                        <configuration>
+                            <codeGenerators>
+                                <generator>
+                                    <codeGeneratorClass>org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator</codeGeneratorClass>
+                                    <outputBaseDir>${jmxGeneratorPath}</outputBaseDir>
+                                    <additionalConfiguration>
+                                        <namespaceToPackage1>urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang</namespaceToPackage1>
+                                    </additionalConfiguration>
+                                </generator>
+                                <generator>
+                                    <codeGeneratorClass>org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl</codeGeneratorClass>
+                                    <outputBaseDir>${salGeneratorPath}</outputBaseDir>
+                                </generator>
+                            </codeGenerators>
+                            <inspectDependencies>true</inspectDependencies>
+                        </configuration>
+                    </execution>
+                </executions>
+                <dependencies>
+                    <dependency>
+                        <groupId>org.opendaylight.controller</groupId>
+                        <artifactId>yang-jmx-generator-plugin</artifactId>
+                        <version>${config.version}</version>
+                    </dependency>
+                </dependencies>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>build-helper-maven-plugin</artifactId>
+                <version>1.8</version>
+                <executions>
+                    <execution>
+                        <id>add-source</id>
+                        <phase>generate-sources</phase>
+                        <goals>
+                            <goal>add-source</goal>
+                        </goals>
+                        <configuration>
+                            <sources>
+                                <source>${project.build.directory}/generated-sources/config</source>;
+                            </sources>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file
diff --git a/opendaylight/netconf/netconf-topology/src/main/java/org/opendaylight/controller/config/yang/netconf/topology/NetconfTopologyModule.java b/opendaylight/netconf/netconf-topology/src/main/java/org/opendaylight/controller/config/yang/netconf/topology/NetconfTopologyModule.java
new file mode 100644 (file)
index 0000000..e4321b7
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2015 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.config.yang.netconf.topology;
+
+import org.opendaylight.netconf.topology.impl.NetconfTopologyImpl;
+
+public class NetconfTopologyModule extends org.opendaylight.controller.config.yang.netconf.topology.AbstractNetconfTopologyModule {
+    public NetconfTopologyModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+        super(identifier, dependencyResolver);
+    }
+
+    public NetconfTopologyModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.controller.config.yang.netconf.topology.NetconfTopologyModule oldModule, AutoCloseable oldInstance) {
+        super(identifier, dependencyResolver, oldModule, oldInstance);
+    }
+
+    @Override
+    public void customValidation() {
+        // add custom validation form module attributes here.
+        this.getClientDispatcherDependency();
+    }
+
+    @Override
+    public AutoCloseable createInstance() {
+        return new NetconfTopologyImpl(getTopologyId(), getClientDispatcherDependency(), getBindingRegistryDependency(),
+                getDomRegistryDependency(), getEventExecutorDependency(), getKeepaliveExecutorDependency(),
+                getProcessingExecutorDependency(), getSharedSchemaRepositoryDependency());
+    }
+
+}
diff --git a/opendaylight/netconf/netconf-topology/src/main/java/org/opendaylight/controller/config/yang/netconf/topology/NetconfTopologyModuleFactory.java b/opendaylight/netconf/netconf-topology/src/main/java/org/opendaylight/controller/config/yang/netconf/topology/NetconfTopologyModuleFactory.java
new file mode 100644 (file)
index 0000000..f8dd199
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2015 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
+ */
+/*
+* Generated file
+*
+* Generated from: yang module name: netconf-topology yang module local name: netconf-topology-impl
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Tue Jul 28 15:33:44 CEST 2015
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.controller.config.yang.netconf.topology;
+
+public class NetconfTopologyModuleFactory extends org.opendaylight.controller.config.yang.netconf.topology.AbstractNetconfTopologyModuleFactory {
+
+}
diff --git a/opendaylight/netconf/netconf-topology/src/main/java/org/opendaylight/controller/config/yang/netconf/topology/shared/schema/repository/SchemaRepositoryImplModule.java b/opendaylight/netconf/netconf-topology/src/main/java/org/opendaylight/controller/config/yang/netconf/topology/shared/schema/repository/SchemaRepositoryImplModule.java
new file mode 100644 (file)
index 0000000..5ea2f50
--- /dev/null
@@ -0,0 +1,43 @@
+package org.opendaylight.controller.config.yang.netconf.topology.shared.schema.repository;
+
+import org.opendaylight.netconf.topology.SchemaRepositoryProvider;
+import org.opendaylight.yangtools.yang.parser.repo.SharedSchemaRepository;
+
+public class SchemaRepositoryImplModule extends org.opendaylight.controller.config.yang.netconf.topology.shared.schema.repository.AbstractSchemaRepositoryImplModule {
+    public SchemaRepositoryImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+        super(identifier, dependencyResolver);
+    }
+
+    public SchemaRepositoryImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.controller.config.yang.netconf.topology.shared.schema.repository.SchemaRepositoryImplModule oldModule, java.lang.AutoCloseable oldInstance) {
+        super(identifier, dependencyResolver, oldModule, oldInstance);
+    }
+
+    @Override
+    public void customValidation() {
+        // add custom validation form module attributes here.
+    }
+
+    @Override
+    public java.lang.AutoCloseable createInstance() {
+        return new SchemaRepositoryProviderAutoCloseAble(this);
+    }
+
+    private static class SchemaRepositoryProviderAutoCloseAble implements SchemaRepositoryProvider, AutoCloseable {
+
+        private final SharedSchemaRepository schemaRepository;
+
+        public SchemaRepositoryProviderAutoCloseAble(SchemaRepositoryImplModule module) {
+            schemaRepository = new SharedSchemaRepository(module.getIdentifier().getInstanceName());
+        }
+
+        @Override
+        public void close() throws Exception {
+            //NOOP
+        }
+
+        @Override
+        public SharedSchemaRepository getSharedSchemaRepository() {
+            return schemaRepository;
+        }
+    }
+}
diff --git a/opendaylight/netconf/netconf-topology/src/main/java/org/opendaylight/controller/config/yang/netconf/topology/shared/schema/repository/SchemaRepositoryImplModuleFactory.java b/opendaylight/netconf/netconf-topology/src/main/java/org/opendaylight/controller/config/yang/netconf/topology/shared/schema/repository/SchemaRepositoryImplModuleFactory.java
new file mode 100644 (file)
index 0000000..b3a64d4
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+* Generated file
+*
+* Generated from: yang module name: shared-schema-repository yang module local name: shared-schema-repository-impl
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Tue Sep 08 13:43:39 CEST 2015
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.controller.config.yang.netconf.topology.shared.schema.repository;
+
+import com.google.common.collect.Sets;
+import java.util.Set;
+import org.opendaylight.controller.config.api.DependencyResolverFactory;
+import org.opendaylight.controller.config.api.ModuleIdentifier;
+import org.osgi.framework.BundleContext;
+
+public class SchemaRepositoryImplModuleFactory extends org.opendaylight.controller.config.yang.netconf.topology.shared.schema.repository.AbstractSchemaRepositoryImplModuleFactory {
+
+    public static final ModuleIdentifier defaultInstanceId = new ModuleIdentifier(NAME, "default-shared-schema-repository");
+
+    @Override
+    public Set<SchemaRepositoryImplModule> getDefaultModules(DependencyResolverFactory dependencyResolverFactory, BundleContext bundleContext) {
+        SchemaRepositoryImplModule defaultModule = new SchemaRepositoryImplModule(
+                defaultInstanceId, dependencyResolverFactory.createDependencyResolver(defaultInstanceId));
+        return Sets.newHashSet(defaultModule);
+    }
+}
diff --git a/opendaylight/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/NetconfTopology.java b/opendaylight/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/NetconfTopology.java
new file mode 100644 (file)
index 0000000..d9ad804
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2015 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.netconf.topology;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.netconf.sal.connect.api.RemoteDeviceHandler;
+import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfDeviceCapabilities;
+import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+
+// TODO maybe rename to NetconfTopologyDispatcher?
+public interface NetconfTopology {
+
+    String getTopologyId();
+
+    DataBroker getDataBroker();
+
+    ListenableFuture<NetconfDeviceCapabilities> connectNode(NodeId nodeId, Node configNode);
+
+    ListenableFuture<Void> disconnectNode(NodeId nodeId);
+
+    void registerConnectionStatusListener(NodeId node, RemoteDeviceHandler<NetconfSessionPreferences> listener);
+}
diff --git a/opendaylight/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/SchemaRepositoryProvider.java b/opendaylight/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/SchemaRepositoryProvider.java
new file mode 100644 (file)
index 0000000..e4664d6
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2015 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.netconf.topology;
+
+import org.opendaylight.yangtools.yang.parser.repo.SharedSchemaRepository;
+
+public interface SchemaRepositoryProvider{
+
+    SharedSchemaRepository getSharedSchemaRepository();
+}
diff --git a/opendaylight/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/TopologyMountPointFacade.java b/opendaylight/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/TopologyMountPointFacade.java
new file mode 100644 (file)
index 0000000..f590006
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2015 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.netconf.topology;
+
+import com.google.common.base.Preconditions;
+import java.util.ArrayList;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+import org.opendaylight.controller.md.sal.dom.api.DOMNotification;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
+import org.opendaylight.controller.sal.core.api.Broker;
+import org.opendaylight.netconf.sal.connect.api.RemoteDeviceHandler;
+import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences;
+import org.opendaylight.netconf.sal.connect.netconf.sal.NetconfDeviceDataBroker;
+import org.opendaylight.netconf.sal.connect.netconf.sal.NetconfDeviceNotificationService;
+import org.opendaylight.netconf.sal.connect.netconf.sal.NetconfDeviceSalProvider;
+import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class TopologyMountPointFacade implements AutoCloseable, RemoteDeviceHandler<NetconfSessionPreferences> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(TopologyMountPointFacade.class);
+
+    private final RemoteDeviceId id;
+    private final Broker domBroker;
+    private final BindingAwareBroker bindingBroker;
+    private final long defaultRequestTimeoutMillis;
+
+    private SchemaContext remoteSchemaContext = null;
+    private NetconfSessionPreferences netconfSessionPreferences = null;
+    private DOMRpcService deviceRpc = null;
+    private final NetconfDeviceSalProvider salProvider;
+
+    private final ArrayList<RemoteDeviceHandler<NetconfSessionPreferences>> connectionStatusListeners = new ArrayList<>();
+
+    public TopologyMountPointFacade(final RemoteDeviceId id,
+                                    final Broker domBroker,
+                                    final BindingAwareBroker bindingBroker,
+                                    long defaultRequestTimeoutMillis) {
+
+        this.id = id;
+        this.domBroker = domBroker;
+        this.bindingBroker = bindingBroker;
+        this.defaultRequestTimeoutMillis = defaultRequestTimeoutMillis;
+        this.salProvider = new NetconfDeviceSalProvider(id);
+        registerToSal(domBroker, bindingBroker);
+    }
+
+    public void registerToSal(final Broker domRegistryDependency, final BindingAwareBroker bindingBroker) {
+        domRegistryDependency.registerProvider(salProvider);
+        bindingBroker.registerProvider(salProvider);
+    }
+
+    @Override
+    public void onDeviceConnected(final SchemaContext remoteSchemaContext,
+                                  final NetconfSessionPreferences netconfSessionPreferences,
+                                  final DOMRpcService deviceRpc) {
+        // prepare our prerequisites for mountpoint
+        this.remoteSchemaContext = remoteSchemaContext;
+        this.netconfSessionPreferences = netconfSessionPreferences;
+        this.deviceRpc = deviceRpc;
+        for (RemoteDeviceHandler<NetconfSessionPreferences> listener : connectionStatusListeners) {
+            listener.onDeviceConnected(remoteSchemaContext, netconfSessionPreferences, deviceRpc);
+        }
+    }
+
+    @Override
+    public void onDeviceDisconnected() {
+        salProvider.getMountInstance().onTopologyDeviceDisconnected();
+        for (RemoteDeviceHandler<NetconfSessionPreferences> listener : connectionStatusListeners) {
+            listener.onDeviceDisconnected();
+        }
+    }
+
+    @Override
+    public void onDeviceFailed(Throwable throwable) {
+        salProvider.getMountInstance().onTopologyDeviceDisconnected();
+        for (RemoteDeviceHandler<NetconfSessionPreferences> listener : connectionStatusListeners) {
+            listener.onDeviceFailed(throwable);
+        }
+    }
+
+    @Override
+    public void onNotification(DOMNotification domNotification) {
+        salProvider.getMountInstance().publish(domNotification);
+    }
+
+    public void registerMountPoint() {
+        Preconditions.checkNotNull(id);
+        Preconditions.checkNotNull(remoteSchemaContext);
+        Preconditions.checkNotNull(netconfSessionPreferences);
+
+        final DOMDataBroker netconfDeviceDataBroker = new NetconfDeviceDataBroker(id, remoteSchemaContext, deviceRpc, netconfSessionPreferences, defaultRequestTimeoutMillis);
+        final NetconfDeviceNotificationService notificationService = new NetconfDeviceNotificationService();
+
+        salProvider.getMountInstance().onTopologyDeviceConnected(remoteSchemaContext, netconfDeviceDataBroker, deviceRpc, notificationService);
+    }
+
+    public void unregisterMountPoint() {
+        salProvider.getMountInstance().onTopologyDeviceDisconnected();
+    }
+
+    public void registerConnectionStatusListener(final RemoteDeviceHandler<NetconfSessionPreferences> listener) {
+        connectionStatusListeners.add(listener);
+    }
+
+    @Override
+    public void close() {
+        closeGracefully(salProvider);
+    }
+
+    private void closeGracefully(final AutoCloseable resource) {
+        if (resource != null) {
+            try {
+                resource.close();
+            } catch (final Exception e) {
+                LOG.warn("{}: Ignoring exception while closing {}", id, resource, e);
+            }
+        }
+    }
+}
diff --git a/opendaylight/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/impl/NetconfTopologyImpl.java b/opendaylight/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/impl/NetconfTopologyImpl.java
new file mode 100644 (file)
index 0000000..0278369
--- /dev/null
@@ -0,0 +1,296 @@
+/*
+ * Copyright (c) 2015 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.netconf.topology.impl;
+
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import io.netty.util.concurrent.EventExecutor;
+import java.math.BigDecimal;
+import java.net.InetSocketAddress;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import org.opendaylight.controller.config.threadpool.ScheduledThreadPool;
+import org.opendaylight.controller.config.threadpool.ThreadPool;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
+import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
+import org.opendaylight.controller.sal.core.api.Broker;
+import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
+import org.opendaylight.controller.sal.core.api.Provider;
+import org.opendaylight.netconf.client.NetconfClientDispatcher;
+import org.opendaylight.netconf.client.conf.NetconfClientConfiguration;
+import org.opendaylight.netconf.client.conf.NetconfReconnectingClientConfiguration;
+import org.opendaylight.netconf.client.conf.NetconfReconnectingClientConfigurationBuilder;
+import org.opendaylight.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
+import org.opendaylight.netconf.nettyutil.handler.ssh.authentication.LoginPassword;
+import org.opendaylight.netconf.sal.connect.api.RemoteDeviceHandler;
+import org.opendaylight.netconf.sal.connect.netconf.NetconfDevice;
+import org.opendaylight.netconf.sal.connect.netconf.NetconfStateSchemas;
+import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfDeviceCapabilities;
+import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfDeviceCommunicator;
+import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences;
+import org.opendaylight.netconf.sal.connect.netconf.sal.KeepaliveSalFacade;
+import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
+import org.opendaylight.netconf.topology.NetconfTopology;
+import org.opendaylight.netconf.topology.SchemaRepositoryProvider;
+import org.opendaylight.netconf.topology.TopologyMountPointFacade;
+import org.opendaylight.protocol.framework.ReconnectStrategy;
+import org.opendaylight.protocol.framework.ReconnectStrategyFactory;
+import org.opendaylight.protocol.framework.TimedReconnectStrategy;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Host;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.credentials.Credentials;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yangtools.yang.model.repo.api.SchemaContextFactory;
+import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceRegistry;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NetconfTopologyImpl implements NetconfTopology, BindingAwareProvider, Provider, AutoCloseable {
+
+    private static final Logger LOG = LoggerFactory.getLogger(NetconfTopologyImpl.class);
+
+    private final String topologyId;
+    private final NetconfClientDispatcher clientDispatcher;
+    private final BindingAwareBroker bindingAwareBroker;
+    private final Broker domBroker;
+    private final EventExecutor eventExecutor;
+    private final ScheduledThreadPool keepaliveExecutor;
+    private final ThreadPool processingExecutor;
+    private final SchemaRepositoryProvider sharedSchemaRepository;
+
+    private SchemaSourceRegistry schemaSourceRegistry = null;
+    private SchemaContextFactory schemaContextFactory = null;
+
+    private DOMMountPointService mountPointService = null;
+    private DataBroker dataBroker = null;
+    private final HashMap<NodeId, NetconfConnectorDTO> activeConnectors = new HashMap<>();
+
+    public NetconfTopologyImpl(final String topologyId, final NetconfClientDispatcher clientDispatcher,
+                               final BindingAwareBroker bindingAwareBroker, final Broker domBroker,
+                               final EventExecutor eventExecutor, final ScheduledThreadPool keepaliveExecutor,
+                               final ThreadPool processingExecutor, final SchemaRepositoryProvider sharedSchemaRepository) {
+        this.topologyId = topologyId;
+        this.clientDispatcher = clientDispatcher;
+        this.bindingAwareBroker = bindingAwareBroker;
+        this.domBroker = domBroker;
+        this.eventExecutor = eventExecutor;
+        this.keepaliveExecutor = keepaliveExecutor;
+        this.processingExecutor = processingExecutor;
+        this.sharedSchemaRepository = sharedSchemaRepository;
+
+        registerToSal(this, this);
+    }
+
+    private void registerToSal(BindingAwareProvider baProvider, Provider provider) {
+        domBroker.registerProvider(provider);
+        bindingAwareBroker.registerProvider(baProvider);
+    }
+
+    @Override
+    public void close() throws Exception {
+        // close all existing connectors, delete whole topology in datastore?
+        for (NetconfConnectorDTO connectorDTO : activeConnectors.values()) {
+            connectorDTO.getCommunicator().disconnect();
+        }
+        activeConnectors.clear();
+    }
+
+    @Override
+    public String getTopologyId() {
+        return topologyId;
+    }
+
+    @Override
+    public DataBroker getDataBroker() {
+        return Preconditions.checkNotNull(dataBroker, "DataBroker not initialized yet");
+    }
+
+    @Override
+    public ListenableFuture<NetconfDeviceCapabilities> connectNode(NodeId nodeId, Node configNode) {
+        return setupConnection(nodeId, configNode);
+    }
+
+    @Override
+    public ListenableFuture<Void> disconnectNode(NodeId nodeId) {
+        if (!activeConnectors.containsKey(nodeId)) {
+            return Futures.immediateFailedFuture(new IllegalStateException("Unable to disconnect device that is not connected"));
+        }
+
+        // retrieve connection, and disconnect it
+        activeConnectors.remove(nodeId).getCommunicator().disconnect();
+        return Futures.immediateFuture(null);
+    }
+
+    @Override
+    public void registerConnectionStatusListener(NodeId node, RemoteDeviceHandler<NetconfSessionPreferences> listener) {
+        activeConnectors.get(node).getMountPointFacade().registerConnectionStatusListener(listener);
+    }
+
+    private ListenableFuture<NetconfDeviceCapabilities> setupConnection(final NodeId nodeId,
+                                                                        final Node configNode) {
+        final NetconfNode netconfNode = configNode.getAugmentation(NetconfNode.class);
+
+        final NetconfConnectorDTO deviceCommunicatorDTO = createDeviceCommunicator(nodeId, netconfNode);
+        final NetconfDeviceCommunicator deviceCommunicator = deviceCommunicatorDTO.getCommunicator();
+        final NetconfReconnectingClientConfiguration clientConfig = getClientConfig(deviceCommunicator, netconfNode);
+        final ListenableFuture<NetconfDeviceCapabilities> future = deviceCommunicator.initializeRemoteConnection(clientDispatcher, clientConfig);
+
+        Futures.addCallback(future, new FutureCallback<NetconfDeviceCapabilities>() {
+            @Override
+            public void onSuccess(NetconfDeviceCapabilities result) {
+                LOG.debug("Connector for : " + nodeId.getValue() + " started succesfully");
+                activeConnectors.put(nodeId, deviceCommunicatorDTO);
+            }
+
+            @Override
+            public void onFailure(Throwable t) {
+                LOG.error("Connector for : " + nodeId.getValue() + " failed");
+                // remove this node from active connectors?
+            }
+        });
+
+        return future;
+    }
+
+    private NetconfConnectorDTO createDeviceCommunicator(final NodeId nodeId,
+                                                         final NetconfNode node) {
+        IpAddress ipAddress = node.getHost().getIpAddress();
+        InetSocketAddress address = new InetSocketAddress(ipAddress.getIpv4Address() != null ?
+                ipAddress.getIpv4Address().getValue() : ipAddress.getIpv6Address().getValue(),
+                node.getPort().getValue());
+        RemoteDeviceId remoteDeviceId = new RemoteDeviceId(nodeId.getValue(), address);
+
+        // we might need to create a new SalFacade to maintain backwards compatibility with special case loopback connection
+        TopologyMountPointFacade mountPointFacade =
+                new TopologyMountPointFacade(remoteDeviceId, domBroker, bindingAwareBroker, node.getDefaultRequestTimeoutMillis());
+        RemoteDeviceHandler<NetconfSessionPreferences> salFacade = mountPointFacade;
+        if (node.getKeepaliveDelay() > 0) {
+            salFacade = new KeepaliveSalFacade(remoteDeviceId, mountPointFacade, keepaliveExecutor.getExecutor(), node.getKeepaliveDelay());
+        }
+
+        NetconfDevice.SchemaResourcesDTO schemaResourcesDTO =
+                new NetconfDevice.SchemaResourcesDTO(schemaSourceRegistry, schemaContextFactory, new NetconfStateSchemas.NetconfStateSchemasResolverImpl());
+
+        NetconfDevice device = new NetconfDevice(schemaResourcesDTO, remoteDeviceId, salFacade,
+                processingExecutor.getExecutor(), node.isReconnectOnChangedSchema());
+
+        return new NetconfConnectorDTO(new NetconfDeviceCommunicator(remoteDeviceId, device), mountPointFacade);
+    }
+
+    public NetconfReconnectingClientConfiguration getClientConfig(final NetconfDeviceCommunicator listener, NetconfNode node) {
+        final InetSocketAddress socketAddress = getSocketAddress(node.getHost(), node.getPort().getValue());
+        final long clientConnectionTimeoutMillis = node.getDefaultRequestTimeoutMillis();
+
+        final ReconnectStrategyFactory sf = new TimedReconnectStrategyFactory(eventExecutor,
+                node.getMaxConnectionAttempts(), node.getBetweenAttemptsTimeoutMillis(), node.getSleepFactor());
+        final ReconnectStrategy strategy = sf.createReconnectStrategy();
+
+        final AuthenticationHandler authHandler;
+        final Credentials credentials = node.getCredentials();
+        if (credentials instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.credentials.credentials.LoginPassword) {
+            authHandler = new LoginPassword(
+                    ((org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.credentials.credentials.LoginPassword) credentials).getUsername(),
+                    ((org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.credentials.credentials.LoginPassword) credentials).getPassword());
+        } else {
+            throw new IllegalStateException("Only login/password authentification is supported");
+        }
+
+        return NetconfReconnectingClientConfigurationBuilder.create()
+                .withAddress(socketAddress)
+                .withConnectionTimeoutMillis(clientConnectionTimeoutMillis)
+                .withReconnectStrategy(strategy)
+                .withAuthHandler(authHandler)
+                .withProtocol(node.isTcpOnly() ?
+                        NetconfClientConfiguration.NetconfClientProtocol.TCP :
+                        NetconfClientConfiguration.NetconfClientProtocol.SSH)
+                .withConnectStrategyFactory(sf)
+                .withSessionListener(listener)
+                .build();
+    }
+
+    @Override
+    public void onSessionInitiated(ProviderSession session) {
+        mountPointService = session.getService(DOMMountPointService.class);
+    }
+
+    @Override
+    public Collection<ProviderFunctionality> getProviderFunctionality() {
+        return Collections.emptySet();
+    }
+
+    @Override
+    public void onSessionInitiated(ProviderContext session) {
+        dataBroker = session.getSALService(DataBroker.class);
+    }
+
+    private static final class NetconfConnectorDTO {
+
+        private final NetconfDeviceCommunicator communicator;
+        private final TopologyMountPointFacade mountPointFacade;
+
+        private NetconfConnectorDTO(final NetconfDeviceCommunicator communicator, final TopologyMountPointFacade mountPointFacade) {
+            this.communicator = communicator;
+            this.mountPointFacade = mountPointFacade;
+        }
+
+        public NetconfDeviceCommunicator getCommunicator() {
+            return communicator;
+        }
+
+        public TopologyMountPointFacade getMountPointFacade() {
+            return mountPointFacade;
+        }
+    }
+
+    private static final class TimedReconnectStrategyFactory implements ReconnectStrategyFactory {
+        private final Long connectionAttempts;
+        private final EventExecutor executor;
+        private final double sleepFactor;
+        private final int minSleep;
+
+        TimedReconnectStrategyFactory(final EventExecutor executor, final Long maxConnectionAttempts, final int minSleep, final BigDecimal sleepFactor) {
+            if (maxConnectionAttempts != null && maxConnectionAttempts > 0) {
+                connectionAttempts = maxConnectionAttempts;
+            } else {
+                connectionAttempts = null;
+            }
+
+            this.sleepFactor = sleepFactor.doubleValue();
+            this.executor = executor;
+            this.minSleep = minSleep;
+        }
+
+        @Override
+        public ReconnectStrategy createReconnectStrategy() {
+            final Long maxSleep = null;
+            final Long deadline = null;
+
+            return new TimedReconnectStrategy(executor, minSleep,
+                    minSleep, sleepFactor, maxSleep, connectionAttempts, deadline);
+        }
+    }
+
+    private InetSocketAddress getSocketAddress(final Host host, int port) {
+        if(host.getDomainName() != null) {
+            return new InetSocketAddress(host.getDomainName().getValue(), port);
+        } else {
+            final IpAddress ipAddress = host.getIpAddress();
+            final String ip = ipAddress.getIpv4Address() != null ? ipAddress.getIpv4Address().getValue() : ipAddress.getIpv6Address().getValue();
+            return new InetSocketAddress(ip, port);
+        }
+    }
+}
diff --git a/opendaylight/netconf/netconf-topology/src/main/yang/netconf-topology.yang b/opendaylight/netconf/netconf-topology/src/main/yang/netconf-topology.yang
new file mode 100644 (file)
index 0000000..8f55e63
--- /dev/null
@@ -0,0 +1,111 @@
+module netconf-topology {
+
+    yang-version 1;
+    namespace "urn:opendaylight:params:xml:ns:yang:controller:netconf:topology";
+    prefix "nt";
+
+    import config { prefix config; revision-date 2013-04-05; }
+    import threadpool {prefix th;}
+    import netty {prefix netty;}
+    import opendaylight-md-sal-dom {prefix dom;}
+    import opendaylight-md-sal-binding {prefix md-sal-binding; revision-date 2013-10-28;}
+    import odl-netconf-cfg { prefix cfg-net; revision-date 2014-04-08; }
+    import shared-schema-repository { prefix sh; revision-date 2015-07-27; }
+
+    description
+            "Module definition for Netconf topolgy. Netconf topology provides a set of common configuration ";
+
+    revision "2015-07-27" {
+        description
+            "Initial revision";
+    }
+
+    identity netconf-topology {
+        base config:service-type;
+        config:java-class "org.opendaylight.netconf.topology.NetconfTopology";
+    }
+
+    identity netconf-topology-impl {
+        base config:module-type;
+        config:java-name-prefix NetconfTopology;
+        config:provided-service netconf-topology;
+    }
+
+    augment "/config:modules/config:module/config:configuration" {
+        case netconf-topology-impl {
+            when "/config:modules/config:module/config:type = 'netconf-topology-impl'";
+
+            leaf topology-id {
+                mandatory true;
+                type string;
+            }
+
+            container dom-registry {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity dom:dom-broker-osgi-registry;
+                    }
+                }
+            }
+
+            container binding-registry {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity md-sal-binding:binding-broker-osgi-registry;
+                    }
+                }
+            }
+
+            container event-executor {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity netty:netty-event-executor;
+                    }
+                }
+            }
+
+            container processing-executor {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity th:threadpool;
+                    }
+                }
+
+                description "Makes up for flaws in netty threading design";
+            }
+
+            container client-dispatcher {
+                uses config:service-ref {
+                    refine type {
+                        mandatory false;
+                        config:required-identity cfg-net:netconf-client-dispatcher;
+                    }
+                }
+            }
+
+            container keepalive-executor {
+                uses config:service-ref {
+                    refine type {
+                        mandatory false;
+                        config:required-identity th:scheduled-threadpool;
+                    }
+                }
+
+                description "Dedicated solely to keepalive execution";
+            }
+
+            container shared-schema-repository {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity sh:shared-schema-repository;
+                    }
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/netconf/netconf-topology/src/main/yang/shared-schema-repository.yang b/opendaylight/netconf/netconf-topology/src/main/yang/shared-schema-repository.yang
new file mode 100644 (file)
index 0000000..e5d1f07
--- /dev/null
@@ -0,0 +1,41 @@
+module shared-schema-repository {
+
+    yang-version 1;
+    namespace "urn:opendaylight:params:xml:ns:yang:controller:netconf:topology:shared:schema:repository";
+    prefix "ssr";
+
+    import config { prefix config; revision-date 2013-04-05; }
+
+    description
+            "Module definition for Shared schema repository.";
+
+    revision "2015-07-27" {
+        description
+            "Initial revision";
+    }
+
+    identity shared-schema-repository {
+        base "config:service-type";
+        config:java-class "org.opendaylight.netconf.topology.SchemaRepositoryProvider";
+    }
+
+    identity shared-schema-repository-impl {
+        base "config:module-type";
+        config:provided-service shared-schema-repository;
+        config:java-name-prefix SchemaRepositoryImpl;
+    }
+
+    augment "/config:modules/config:module/config:configuration" {
+        case shared-schema-repository-impl {
+            when "/config:modules/config:module/config:type = 'shared-schema-repository-impl'";
+
+            container schema-repository-fallbacks {
+                list schema-repository-fallback {
+                    leaf repository-url {
+                        type string;
+                    }
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
index f2027d53ea5e2b9d53f36468bd3b0a232b1c2961..f1474e11b436e5b97675bd2235b421a0df4e2aa4 100644 (file)
@@ -35,6 +35,8 @@
     <module>aaa-authn-odl-plugin</module>
     <module>netconf-notifications-impl</module>
     <module>netconf-notifications-api</module>
+    <module>netconf-topology</module>
+    <module>netconf-topology-config</module>
     <module>sal-netconf-connector</module>
     <module>messagebus-netconf</module>
     <module>models</module>
index 5dbd9e1d7f57c03412ff33738682004345d1543d..418cfc3de6de610de550ba1ac7759f2f4d76052a 100644 (file)
       <groupId>org.opendaylight.yangtools</groupId>
       <artifactId>yang-data-impl</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.yangtools</groupId>
+      <artifactId>yang-model-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.yangtools</groupId>
+      <artifactId>yang-model-util</artifactId>
+    </dependency>
     <dependency>
       <groupId>org.opendaylight.yangtools</groupId>
       <artifactId>yang-parser-impl</artifactId>
       <plugin>
         <groupId>org.apache.felix</groupId>
         <artifactId>maven-bundle-plugin</artifactId>
+        <configuration>
+          <instructions>
+            <Import-Package>*</Import-Package>
+          </instructions>
+        </configuration>
       </plugin>
+
       <plugin>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>yang-maven-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>config</id>
+            <goals>
+              <goal>generate-sources</goal>
+            </goals>
+            <configuration>
+              <codeGenerators>
+                <generator>
+                  <codeGeneratorClass>org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator</codeGeneratorClass>
+                  <outputBaseDir>${jmxGeneratorPath}</outputBaseDir>
+                  <additionalConfiguration>
+                    <namespaceToPackage1>urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang</namespaceToPackage1>
+                  </additionalConfiguration>
+                </generator>
+                <generator>
+                  <codeGeneratorClass>org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl</codeGeneratorClass>
+                  <outputBaseDir>${salGeneratorPath}</outputBaseDir>
+                </generator>
+              </codeGenerators>
+              <inspectDependencies>true</inspectDependencies>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>build-helper-maven-plugin</artifactId>
+        <version>1.8</version>
+        <executions>
+          <execution>
+            <id>add-source</id>
+            <phase>generate-sources</phase>
+            <goals>
+              <goal>add-source</goal>
+            </goals>
+            <configuration>
+              <sources>
+                <source>${project.build.directory}/generated-sources/config</source>;
+              </sources>
+            </configuration>
+          </execution>
+        </executions>
       </plugin>
     </plugins>
   </build>
index ed0be0d96d55960397fe6bccab893cb2246a2b0e..40e4fe233163d25d35e4ffee07baefdfb13cb3a5 100644 (file)
@@ -12,14 +12,19 @@ import static org.opendaylight.controller.config.api.JmxAttributeValidationExcep
 
 import com.google.common.base.Optional;
 import io.netty.util.concurrent.EventExecutor;
+import java.io.File;
 import java.math.BigDecimal;
 import java.net.InetSocketAddress;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.ThreadFactory;
 import org.opendaylight.controller.config.api.JmxAttributeValidationException;
+import org.opendaylight.controller.config.threadpool.ScheduledThreadPool;
+import org.opendaylight.controller.config.threadpool.ThreadPool;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
 import org.opendaylight.controller.sal.core.api.Broker;
 import org.opendaylight.netconf.client.NetconfClientDispatcher;
@@ -41,7 +46,13 @@ import org.opendaylight.protocol.framework.TimedReconnectStrategy;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Host;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
 import org.opendaylight.yangtools.yang.model.repo.api.SchemaContextFactory;
+import org.opendaylight.yangtools.yang.model.repo.api.SchemaRepository;
+import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceFilter;
+import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
 import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceRegistry;
+import org.opendaylight.yangtools.yang.model.repo.util.FilesystemSchemaSourceCache;
+import org.opendaylight.yangtools.yang.parser.repo.SharedSchemaRepository;
+import org.opendaylight.yangtools.yang.parser.util.TextToASTTransformer;
 import org.osgi.framework.BundleContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -53,11 +64,26 @@ public final class NetconfConnectorModule extends org.opendaylight.controller.co
 {
     private static final Logger LOG = LoggerFactory.getLogger(NetconfConnectorModule.class);
 
+    private static FilesystemSchemaSourceCache<YangTextSchemaSource> CACHE = null;
+    //when no topology is defined in connector config, we need to add a default schema repository to mantain backwards compatibility
+    private static SharedSchemaRepository DEFAULT_SCHEMA_REPOSITORY = null;
+
+    //keep track of already initialized repositories to avoid adding redundant listeners
+    private static final Set<SchemaRepository> INITIALIZED_SCHEMA_REPOSITORIES = new HashSet<>();
+
     private BundleContext bundleContext;
     private Optional<NetconfSessionPreferences> userCapabilities;
     private SchemaSourceRegistry schemaRegistry;
     private SchemaContextFactory schemaContextFactory;
 
+    private Broker domRegistry;
+    private NetconfClientDispatcher clientDispatcher;
+    private BindingAwareBroker bindingRegistry;
+    private ThreadPool processingExecutor;
+    private ScheduledThreadPool keepaliveExecutor;
+    private SharedSchemaRepository sharedSchemaRepository;
+    private EventExecutor eventExecutor;
+
     public NetconfConnectorModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier, final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
         super(identifier, dependencyResolver);
     }
@@ -71,8 +97,6 @@ public final class NetconfConnectorModule extends org.opendaylight.controller.co
         checkNotNull(getAddress(), addressJmxAttribute);
         checkCondition(isHostAddressPresent(getAddress()), "Host address not present in " + getAddress(), addressJmxAttribute);
         checkNotNull(getPort(), portJmxAttribute);
-        checkNotNull(getDomRegistry(), portJmxAttribute);
-        checkNotNull(getDomRegistry(), domRegistryJmxAttribute);
 
         checkNotNull(getConnectionTimeoutMillis(), connectionTimeoutMillisJmxAttribute);
         checkCondition(getConnectionTimeoutMillis() > 0, "must be > 0", connectionTimeoutMillisJmxAttribute);
@@ -83,9 +107,12 @@ public final class NetconfConnectorModule extends org.opendaylight.controller.co
         checkNotNull(getBetweenAttemptsTimeoutMillis(), betweenAttemptsTimeoutMillisJmxAttribute);
         checkCondition(getBetweenAttemptsTimeoutMillis() > 0, "must be > 0", betweenAttemptsTimeoutMillisJmxAttribute);
 
-        checkNotNull(getClientDispatcher(), clientDispatcherJmxAttribute);
-        checkNotNull(getBindingRegistry(), bindingRegistryJmxAttribute);
-        checkNotNull(getProcessingExecutor(), processingExecutorJmxAttribute);
+//        if (getNetconfTopology() == null) {
+//            checkNotNull(getDomRegistry(), domRegistryJmxAttribute);
+//            checkNotNull(getClientDispatcher(), clientDispatcherJmxAttribute);
+//            checkNotNull(getBindingRegistry(), bindingRegistryJmxAttribute);
+//            checkNotNull(getProcessingExecutor(), processingExecutorJmxAttribute);
+//        }
 
         // Check username + password in case of ssh
         if(getTcpOnly() == false) {
@@ -94,23 +121,6 @@ public final class NetconfConnectorModule extends org.opendaylight.controller.co
         }
 
         userCapabilities = getUserCapabilities();
-
-        if(getKeepaliveExecutor() == null) {
-            LOG.warn("Keepalive executor missing. Using default instance for now, the configuration needs to be updated");
-
-            // Instantiate the default executor, now we know its necessary
-            if(DEFAULT_KEEPALIVE_EXECUTOR == null) {
-                DEFAULT_KEEPALIVE_EXECUTOR = Executors.newScheduledThreadPool(2, new ThreadFactory() {
-                    @Override
-                    public Thread newThread(final Runnable r) {
-                        final Thread thread = new Thread(r);
-                        thread.setName("netconf-southound-keepalives-" + thread.getId());
-                        thread.setDaemon(true);
-                        return thread;
-                    }
-                });
-            }
-        }
     }
 
     private boolean isHostAddressPresent(final Host address) {
@@ -123,21 +133,19 @@ public final class NetconfConnectorModule extends org.opendaylight.controller.co
 
     @Override
     public java.lang.AutoCloseable createInstance() {
+        initDependenciesFromTopology();
         final RemoteDeviceId id = new RemoteDeviceId(getIdentifier(), getSocketAddress());
 
-        final ExecutorService globalProcessingExecutor = getProcessingExecutorDependency().getExecutor();
-
-        final Broker domBroker = getDomRegistryDependency();
-        final BindingAwareBroker bindingBroker = getBindingRegistryDependency();
+        final ExecutorService globalProcessingExecutor = processingExecutor.getExecutor();
 
         RemoteDeviceHandler<NetconfSessionPreferences> salFacade
-                = new NetconfDeviceSalFacade(id, domBroker, bindingBroker, getDefaultRequestTimeoutMillis());
+                = new NetconfDeviceSalFacade(id, domRegistry, bindingRegistry, getDefaultRequestTimeoutMillis());
 
         final Long keepaliveDelay = getKeepaliveDelay();
-        if(shouldSendKeepalive()) {
+        if (shouldSendKeepalive()) {
             // Keepalive executor is optional for now and a default instance is supported
-            final ScheduledExecutorService executor = getKeepaliveExecutor() == null ?
-                    DEFAULT_KEEPALIVE_EXECUTOR : getKeepaliveExecutorDependency().getExecutor();
+            final ScheduledExecutorService executor = keepaliveExecutor == null ? DEFAULT_KEEPALIVE_EXECUTOR : keepaliveExecutor.getExecutor();
+
             salFacade = new KeepaliveSalFacade(id, salFacade, executor, keepaliveDelay);
         }
 
@@ -150,18 +158,72 @@ public final class NetconfConnectorModule extends org.opendaylight.controller.co
         final NetconfDeviceCommunicator listener = userCapabilities.isPresent() ?
                 new NetconfDeviceCommunicator(id, device, userCapabilities.get()) : new NetconfDeviceCommunicator(id, device);
 
-        if(shouldSendKeepalive()) {
+        if (shouldSendKeepalive()) {
             ((KeepaliveSalFacade) salFacade).setListener(listener);
         }
 
         final NetconfReconnectingClientConfiguration clientConfig = getClientConfig(listener);
-        final NetconfClientDispatcher dispatcher = getClientDispatcherDependency();
-
-        listener.initializeRemoteConnection(dispatcher, clientConfig);
+        listener.initializeRemoteConnection(clientDispatcher, clientConfig);
 
         return new SalConnectorCloseable(listener, salFacade);
     }
 
+    private void initDependenciesFromTopology() {
+//            topology = getNetconfTopologyDependency();
+
+//            domRegistry = topology.getDomRegistryDependency();
+//            clientDispatcher = topology.getNetconfClientDispatcherDependency();
+//            bindingRegistry = topology.getBindingAwareBroker();
+//            processingExecutor = topology.getProcessingExecutorDependency();
+//            keepaliveExecutor = topology.getKeepaliveExecutorDependency();
+//            sharedSchemaRepository = topology.getSharedSchemaRepository().getSharedSchemaRepository();
+//            eventExecutor = topology.getEventExecutorDependency();
+
+//            initFilesystemSchemaSourceCache(sharedSchemaRepository);
+        domRegistry = getDomRegistryDependency();
+        clientDispatcher = getClientDispatcherDependency();
+        bindingRegistry = getBindingRegistryDependency();
+        processingExecutor = getProcessingExecutorDependency();
+        eventExecutor = getEventExecutorDependency();
+
+        if(getKeepaliveExecutor() == null) {
+            LOG.warn("Keepalive executor missing. Using default instance for now, the configuration needs to be updated");
+
+            // Instantiate the default executor, now we know its necessary
+            if(DEFAULT_KEEPALIVE_EXECUTOR == null) {
+                DEFAULT_KEEPALIVE_EXECUTOR = Executors.newScheduledThreadPool(2, new ThreadFactory() {
+                    @Override
+                    public Thread newThread(final Runnable r) {
+                        final Thread thread = new Thread(r);
+                        thread.setName("netconf-southound-keepalives-" + thread.getId());
+                        thread.setDaemon(true);
+                        return thread;
+                    }
+                });
+            }
+        }
+
+        LOG.warn("No topology defined in config, using default-shared-schema-repo");
+        if (DEFAULT_SCHEMA_REPOSITORY == null) {
+            DEFAULT_SCHEMA_REPOSITORY = new SharedSchemaRepository("default shared schema repo");
+        }
+        initFilesystemSchemaSourceCache(DEFAULT_SCHEMA_REPOSITORY);
+    }
+
+    private void initFilesystemSchemaSourceCache(SharedSchemaRepository repository) {
+        LOG.warn("Schema repository used: {}", repository.getIdentifier());
+        if (CACHE == null) {
+            CACHE = new FilesystemSchemaSourceCache<>(repository, YangTextSchemaSource.class, new File("cache/schema"));
+        }
+        if (!INITIALIZED_SCHEMA_REPOSITORIES.contains(repository)) {
+            repository.registerSchemaSourceListener(CACHE);
+            repository.registerSchemaSourceListener(TextToASTTransformer.create(repository, repository));
+            INITIALIZED_SCHEMA_REPOSITORIES.add(repository);
+        }
+        setSchemaRegistry(repository);
+        setSchemaContextFactory(repository.createSchemaContextFactory(SchemaSourceFilter.ALWAYS_ACCEPT));
+    }
+
     private boolean shouldSendKeepalive() {
         return getKeepaliveDelay() > 0;
     }
@@ -190,8 +252,8 @@ public final class NetconfConnectorModule extends org.opendaylight.controller.co
         final InetSocketAddress socketAddress = getSocketAddress();
         final long clientConnectionTimeoutMillis = getConnectionTimeoutMillis();
 
-        final ReconnectStrategyFactory sf = new TimedReconnectStrategyFactory(
-            getEventExecutorDependency(), getMaxConnectionAttempts(), getBetweenAttemptsTimeoutMillis(), getSleepFactor());
+        final ReconnectStrategyFactory sf = new TimedReconnectStrategyFactory(eventExecutor,
+                getMaxConnectionAttempts(), getBetweenAttemptsTimeoutMillis(), getSleepFactor());
         final ReconnectStrategy strategy = sf.createReconnectStrategy();
 
         return NetconfReconnectingClientConfigurationBuilder.create()
index 70261b2b10cee0b32be6cc83e481e0d9fd69c337..2b31fe05d0e8bba5aea24b984ea62ae287de4b62 100644 (file)
@@ -7,16 +7,9 @@
  */
 package org.opendaylight.controller.config.yang.md.sal.connector.netconf;
 
-import java.io.File;
 import org.opendaylight.controller.config.api.DependencyResolver;
 import org.opendaylight.controller.config.api.DynamicMBeanWithInstance;
 import org.opendaylight.controller.config.spi.Module;
-import org.opendaylight.yangtools.yang.model.repo.api.SchemaContextFactory;
-import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceFilter;
-import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
-import org.opendaylight.yangtools.yang.model.repo.util.FilesystemSchemaSourceCache;
-import org.opendaylight.yangtools.yang.parser.repo.SharedSchemaRepository;
-import org.opendaylight.yangtools.yang.parser.util.TextToASTTransformer;
 import org.osgi.framework.BundleContext;
 
 /**
@@ -25,27 +18,11 @@ import org.osgi.framework.BundleContext;
 public class NetconfConnectorModuleFactory extends
         org.opendaylight.controller.config.yang.md.sal.connector.netconf.AbstractNetconfConnectorModuleFactory {
 
-    // TODO this should be injected
-    // Netconf devices have separated schema registry + factory from controller
-    private final SharedSchemaRepository repository = new SharedSchemaRepository(NAME);
-    private final SchemaContextFactory schemaContextFactory
-            = repository.createSchemaContextFactory(SchemaSourceFilter.ALWAYS_ACCEPT);
-
-    public NetconfConnectorModuleFactory() {
-        // Start cache and Text to AST transformer
-        final FilesystemSchemaSourceCache<YangTextSchemaSource> cache = new FilesystemSchemaSourceCache<>(repository, YangTextSchemaSource.class, new File("cache/schema"));
-        repository.registerSchemaSourceListener(cache);
-        repository.registerSchemaSourceListener(TextToASTTransformer.create(repository, repository));
-    }
-
     @Override
     public Module createModule(final String instanceName, final DependencyResolver dependencyResolver,
             final DynamicMBeanWithInstance old, final BundleContext bundleContext) throws Exception {
         final NetconfConnectorModule module = (NetconfConnectorModule) super.createModule(instanceName, dependencyResolver,
                 old, bundleContext);
-
-        module.setSchemaRegistry(repository);
-        module.setSchemaContextFactory(schemaContextFactory);
         return module;
     }
 
@@ -53,8 +30,6 @@ public class NetconfConnectorModuleFactory extends
     public Module createModule(final String instanceName, final DependencyResolver dependencyResolver, final BundleContext bundleContext) {
         final NetconfConnectorModule module = (NetconfConnectorModule) super.createModule(instanceName, dependencyResolver,
                 bundleContext);
-        module.setSchemaRegistry(repository);
-        module.setSchemaContextFactory(schemaContextFactory);
         return module;
     }
 }
index 0782739b99b0c0c414f56c69b04a90eee29c427c..093abde49d4b24c24c7ada62c40019a9f52e55e3 100644 (file)
@@ -33,7 +33,7 @@ import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
-final class NetconfDeviceDataBroker implements DOMDataBroker {
+public final class NetconfDeviceDataBroker implements DOMDataBroker {
     private final RemoteDeviceId id;
     private final NetconfBaseOps netconfOps;
     private final long requestTimeoutMillis;
index 555d1741c0c761f0adac2bc589bc456a7a41658d..6cb51966bace09853cb871a6324ddc4fa2692fe2 100644 (file)
@@ -19,7 +19,7 @@ import org.opendaylight.controller.md.sal.dom.api.DOMNotificationService;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
 
-class NetconfDeviceNotificationService implements DOMNotificationService {
+public class NetconfDeviceNotificationService implements DOMNotificationService {
 
     private final Multimap<SchemaPath, DOMNotificationListener> listeners = HashMultimap.create();
 
index 8cb34c15daeeda9a2b540010eac8bac4a24832c6..ef13e0484f405936b330472cebfb3085d4b8175b 100644 (file)
@@ -27,7 +27,7 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-final class NetconfDeviceSalProvider implements AutoCloseable, Provider, BindingAwareProvider {
+public final class NetconfDeviceSalProvider implements AutoCloseable, Provider, BindingAwareProvider {
 
     private static final Logger logger = LoggerFactory.getLogger(NetconfDeviceSalProvider.class);
 
@@ -92,7 +92,7 @@ final class NetconfDeviceSalProvider implements AutoCloseable, Provider, Binding
         topologyDatastoreAdapter = null;
     }
 
-    static final class MountInstance implements AutoCloseable {
+    public static final class MountInstance implements AutoCloseable {
 
         private DOMMountPointService mountService;
         private final RemoteDeviceId id;
@@ -144,7 +144,7 @@ final class NetconfDeviceSalProvider implements AutoCloseable, Provider, Binding
             }
         }
 
-        synchronized void onTopologyDeviceConnected(final SchemaContext initialCtx,
+        public synchronized void onTopologyDeviceConnected(final SchemaContext initialCtx,
                                                     final DOMDataBroker broker, final DOMRpcService rpc,
                                                     final NetconfDeviceNotificationService notificationService) {
 
@@ -163,7 +163,7 @@ final class NetconfDeviceSalProvider implements AutoCloseable, Provider, Binding
 
         }
 
-        synchronized void onTopologyDeviceDisconnected() {
+        public synchronized void onTopologyDeviceDisconnected() {
             if(topologyRegistration == null) {
                 logger.trace("{}: Not removing TOPOLOGY mountpoint from MD-SAL, mountpoint was not registered yet", id);
                 return;
@@ -181,7 +181,7 @@ final class NetconfDeviceSalProvider implements AutoCloseable, Provider, Binding
         }
 
         @Override
-        synchronized public void close() throws Exception {
+        public synchronized void close() throws Exception {
             onDeviceDisconnected();
             onTopologyDeviceDisconnected();
             mountService = null;
index 799c9c89995d414b410f1aa1ad02f4a4b4756e80..62cd4514e63bb2d47fb2b2e1262b8ea98637e858 100644 (file)
@@ -14,6 +14,12 @@ module odl-sal-netconf-connector-cfg {
     description
         "Service definition for Binding Aware MD-SAL.";
 
+    revision "2015-08-03" {
+        description
+            "Add netconf topology from which dependencies are inherited, change
+            existing dependencies to non-mandatory to preserve backwards compatibility";
+    }
+
     revision "2013-10-28" {
         description
             "Initial revision";
@@ -76,7 +82,7 @@ module odl-sal-netconf-connector-cfg {
             container dom-registry {
                 uses config:service-ref {
                     refine type {
-                        mandatory true;
+                        mandatory false;
                         config:required-identity dom:dom-broker-osgi-registry;
                     }
                 }
@@ -85,7 +91,7 @@ module odl-sal-netconf-connector-cfg {
             container binding-registry {
                 uses config:service-ref {
                     refine type {
-                        mandatory true;
+                        mandatory false;
                         config:required-identity md-sal-binding:binding-broker-osgi-registry;
                     }
                 }
@@ -94,7 +100,7 @@ module odl-sal-netconf-connector-cfg {
             container event-executor {
                 uses config:service-ref {
                     refine type {
-                        mandatory true;
+                        mandatory false;
                         config:required-identity netty:netty-event-executor;
                     }
                 }
@@ -103,7 +109,7 @@ module odl-sal-netconf-connector-cfg {
             container processing-executor {
                 uses config:service-ref {
                     refine type {
-                        mandatory true;
+                        mandatory false;
                         config:required-identity th:threadpool;
                     }
                 }