Merge "Fixed NetconfDevice to store capability info."
authorEd Warnicke <eaw@cisco.com>
Sat, 18 Jan 2014 17:52:45 +0000 (17:52 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Sat, 18 Jan 2014 17:52:45 +0000 (17:52 +0000)
opendaylight/md-sal/model/model-inventory/src/main/yang/netconf-node-inventory.yang
opendaylight/md-sal/model/model-inventory/src/main/yang/node-inventory.yang
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/InventoryUtils.java
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDevice.xtend

index b5cde6ee5b09b11f672b8182475572286f7eadc8..7914de0f66339d4dcf1b524ec30776d46f1eded4 100644 (file)
@@ -10,6 +10,10 @@ module netconf-node-inventory {
     }
     
     grouping netconf-node-fields {
+        leaf connected {
+            type boolean; 
+        }
+    
         leaf-list initial-capability {
             type string;
         }
index 1ffc88732774ea561fcf7a486524363a134836fc..77c92f91ce4358883513079f209c0d5098d9b2aa 100644 (file)
@@ -63,7 +63,6 @@ module opendaylight-inventory {
 
             uses node-connector;
         }
-
     }
 
     grouping node-connector {
index 8350e39c210e1eb4c6a97f280eb16005521dc3c1..f2a09d9608efc10daaff7a10846244f53998231b 100644 (file)
@@ -3,7 +3,6 @@ package org.opendaylight.controller.sal.connect.netconf;
 import java.net.URI;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
-import java.util.Calendar;
 import java.util.Date;
 
 import org.opendaylight.yangtools.yang.common.QName;
@@ -12,28 +11,33 @@ import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
 public class InventoryUtils {
 
     private static final URI INVENTORY_NAMESPACE = URI.create("urn:opendaylight:inventory");
-    private static final Date INVENTORY_REVISION = date();
+    private static final URI NETCONF_INVENTORY_NAMESPACE = URI.create("urn:opendaylight:netconf-node-inventory");
+    private static final Date INVENTORY_REVISION = dateFromString("2013-08-19");
+    private static final Date NETCONF_INVENTORY_REVISION = dateFromString("2014-01-08");
     public static final QName INVENTORY_NODES = new QName(INVENTORY_NAMESPACE, INVENTORY_REVISION, "nodes");
     public static final QName INVENTORY_NODE = new QName(INVENTORY_NAMESPACE, INVENTORY_REVISION, "node");
     public static final QName INVENTORY_ID = new QName(INVENTORY_NAMESPACE, INVENTORY_REVISION, "id");
+    public static final QName INVENTORY_CONNECTED = new QName(NETCONF_INVENTORY_NAMESPACE, NETCONF_INVENTORY_REVISION,
+            "connected");
+    public static final QName NETCONF_INVENTORY_INITIAL_CAPABILITY = new QName(NETCONF_INVENTORY_NAMESPACE,
+            NETCONF_INVENTORY_REVISION, "initial-capability");
 
     public static final InstanceIdentifier INVENTORY_PATH = InstanceIdentifier.builder().node(INVENTORY_NODES)
             .toInstance();
     public static final QName NETCONF_INVENTORY_MOUNT = null;
-    
-    
-    
-    private static Date date() {
+
+    /**
+     * Converts date in string format yyyy-MM-dd to java.util.Date.
+     * 
+     * @return java.util.Date conformant to string formatted date yyyy-MM-dd.
+     */
+    private static Date dateFromString(final String date) {
         SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
         try {
-            return formatter.parse("2013-08-19");
+            return formatter.parse(date);
         } catch (ParseException e) {
-            // TODO Auto-generated catch block
             e.printStackTrace();
         }
         return null;
     }
-
-    
-    
 }
index 21500e1da6441540344daf741dd6becec70ed5a6..3799dd245e2eaf96921e4df3dd1b29b531232750 100644 (file)
@@ -17,6 +17,7 @@ import org.opendaylight.controller.md.sal.common.api.data.DataReader
 import org.opendaylight.controller.netconf.api.NetconfMessage
 import org.opendaylight.controller.netconf.client.NetconfClient
 import org.opendaylight.controller.netconf.client.NetconfClientDispatcher
+import org.opendaylight.controller.netconf.util.xml.XmlUtil
 import org.opendaylight.controller.sal.core.api.Broker.ProviderSession
 import org.opendaylight.controller.sal.core.api.Provider
 import org.opendaylight.controller.sal.core.api.RpcImplementation
@@ -25,7 +26,6 @@ import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction
 import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance
 import org.opendaylight.controller.sal.core.api.mount.MountProvisionService
 import org.opendaylight.protocol.framework.ReconnectStrategy
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.NetconfState
 import org.opendaylight.yangtools.concepts.Registration
 import org.opendaylight.yangtools.yang.common.QName
 import org.opendaylight.yangtools.yang.data.api.CompositeNode
@@ -39,7 +39,6 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContext
 import org.opendaylight.yangtools.yang.model.util.repo.AbstractCachingSchemaSourceProvider
 import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProvider
 import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProviders
-import org.opendaylight.yangtools.yang.model.util.repo.SourceIdentifier
 import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl
 import org.opendaylight.yangtools.yang.parser.impl.util.YangSourceContext
 import org.slf4j.Logger
@@ -49,7 +48,6 @@ import static com.google.common.base.Preconditions.*
 import static org.opendaylight.controller.sal.connect.netconf.InventoryUtils.*
 
 import static extension org.opendaylight.controller.sal.connect.netconf.NetconfMapping.*
-import org.opendaylight.controller.netconf.util.xml.XmlUtil
 
 class NetconfDevice implements Provider, // 
 DataReader<InstanceIdentifier, CompositeNode>, //
@@ -105,6 +103,8 @@ AutoCloseable {
 
     @Property
     var SchemaSourceProvider<InputStream> remoteSourceProvider
+    
+    DataBrokerService dataBroker
 
     public new(String name) {
         this.name = name;
@@ -121,8 +121,6 @@ AutoCloseable {
         val listener = new NetconfDeviceListener(this, eventExecutor);
         val task = startClientTask(dispatcher, listener)
         if (mountInstance != null) {
-            confReaderReg = mountInstance.registerConfigurationReader(ROOT_PATH, this);
-            operReaderReg = mountInstance.registerOperationalReader(ROOT_PATH, this);
             commitHandlerReg = mountInstance.registerCommitHandler(ROOT_PATH, this)
         }
         return processingExecutor.submit(task) as Future<Void>;
@@ -138,29 +136,63 @@ AutoCloseable {
     }
 
     private def Runnable startClientTask(NetconfClientDispatcher dispatcher, NetconfDeviceListener listener) {
-
         return [ |
-            logger.info("Starting Netconf Client on: {}", socketAddress);
-            client = NetconfClient.clientFor(name, socketAddress, reconnectStrategy, dispatcher, listener);
-            logger.debug("Initial capabilities {}", initialCapabilities);
-            var SchemaSourceProvider<String> delegate;
-            if (NetconfRemoteSchemaSourceProvider.isSupportedFor(initialCapabilities)) {
-                delegate = new NetconfRemoteSchemaSourceProvider(this);
-            }  else if(client.capabilities.contains(NetconfRemoteSchemaSourceProvider.IETF_NETCONF_MONITORING.namespace.toString)) {
-                delegate = new NetconfRemoteSchemaSourceProvider(this);
-            } else {
-                logger.info("Netconf server {} does not support IETF Netconf Monitoring", socketAddress);
-                delegate = SchemaSourceProviders.<String>noopProvider();
-            }
-            remoteSourceProvider = schemaSourceProvider.createInstanceFor(delegate);
-            deviceContextProvider = new NetconfDeviceSchemaContextProvider(this, remoteSourceProvider);
-            deviceContextProvider.createContextFromCapabilities(initialCapabilities);
-            if (mountInstance != null && schemaContext.isPresent) {
-                mountInstance.schemaContext = schemaContext.get();
+            try {
+                logger.info("Starting Netconf Client on: {}", socketAddress);
+                client = NetconfClient.clientFor(name, socketAddress, reconnectStrategy, dispatcher, listener);
+                logger.debug("Initial capabilities {}", initialCapabilities);
+                var SchemaSourceProvider<String> delegate;
+                if (NetconfRemoteSchemaSourceProvider.isSupportedFor(initialCapabilities)) {
+                    delegate = new NetconfRemoteSchemaSourceProvider(this);
+                }  else if(client.capabilities.contains(NetconfRemoteSchemaSourceProvider.IETF_NETCONF_MONITORING.namespace.toString)) {
+                    delegate = new NetconfRemoteSchemaSourceProvider(this);
+                } else {
+                    logger.info("Netconf server {} does not support IETF Netconf Monitoring", socketAddress);
+                    delegate = SchemaSourceProviders.<String>noopProvider();
+                }
+                remoteSourceProvider = schemaSourceProvider.createInstanceFor(delegate);
+                deviceContextProvider = new NetconfDeviceSchemaContextProvider(this, remoteSourceProvider);
+                deviceContextProvider.createContextFromCapabilities(initialCapabilities);
+                if (mountInstance != null && schemaContext.isPresent) {
+                    mountInstance.schemaContext = schemaContext.get();
+                }
+                updateDeviceState()
+                if (mountInstance != null && confReaderReg == null && operReaderReg == null) {
+                    confReaderReg = mountInstance.registerConfigurationReader(ROOT_PATH, this);
+                    operReaderReg = mountInstance.registerOperationalReader(ROOT_PATH, this);
+                }
+            } catch (Exception e) {
+                logger.error("Netconf client NOT started. ", e)
             }
         ]
     }
 
+    private def updateDeviceState() {
+        val transaction = dataBroker.beginTransaction
+
+        val it = ImmutableCompositeNode.builder
+        setQName(INVENTORY_NODE)
+        addLeaf(INVENTORY_ID, name)
+        addLeaf(INVENTORY_CONNECTED, client.clientSession.up)
+
+        logger.debug("Client capabilities {}", client.capabilities)
+        for (capability : client.capabilities) {
+            addLeaf(NETCONF_INVENTORY_INITIAL_CAPABILITY, capability)
+        }
+
+        logger.debug("Update device state transaction " + transaction.identifier + " putting operational data started.")
+        transaction.putOperationalData(path, it.toInstance)
+        logger.debug("Update device state transaction " + transaction.identifier + " putting operational data ended.")
+        val transactionStatus = transaction.commit.get;
+
+        if (transactionStatus.successful) {
+            logger.debug("Update device state transaction " + transaction.identifier + " SUCCESSFUL.")
+        } else {
+            logger.debug("Update device state transaction " + transaction.identifier + " FAILED!")
+            logger.debug("Update device state transaction status " + transaction.status)
+        }
+    }
+
     override readConfigurationData(InstanceIdentifier path) {
         val result = invokeRpc(NETCONF_GET_CONFIG_QNAME,
             wrap(NETCONF_GET_CONFIG_QNAME, CONFIG_SOURCE_RUNNING, path.toFilterStructure()));
@@ -209,7 +241,7 @@ AutoCloseable {
     }
 
     override onSessionInitiated(ProviderSession session) {
-        val dataBroker = session.getService(DataBrokerService);
+        dataBroker = session.getService(DataBrokerService);
 
         val transaction = dataBroker.beginTransaction
         if (transaction.operationalNodeNotExisting) {