Merge "Enabled documentation generator for models."
authorEd Warnicke <eaw@cisco.com>
Wed, 27 Nov 2013 21:16:42 +0000 (21:16 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Wed, 27 Nov 2013 21:16:42 +0000 (21:16 +0000)
43 files changed:
opendaylight/distribution/opendaylight/pom.xml
opendaylight/md-sal/model/model-flow-base/src/main/yang/flow-types.yang
opendaylight/md-sal/model/model-flow-base/src/main/yang/table-types.yang
opendaylight/md-sal/model/model-flow-service/src/main/yang/port-service.yang
opendaylight/md-sal/pom.xml
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/impl/RuntimeGeneratedMappingServiceImpl.xtend
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentDataServiceConnector.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentMappingService.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/DeserializationException.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/DataReaderRouter.xtend
opendaylight/md-sal/sal-netconf-connector/pom.xml
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/connector/netconf/NetconfConnectorModule.java [new file with mode: 0644]
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/connector/netconf/NetconfConnectorModuleFactory.java [new file with mode: 0644]
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDevice.xtend
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceManager.xtend [deleted file]
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfProvider.java [deleted file]
opendaylight/md-sal/sal-netconf-connector/src/main/yang/odl-sal-netconf-connector-cfg.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/Draft01.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/RestconfService.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/RestconfServiceLegacy.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonMapper.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonToCompositeNodeProvider.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/StructuredDataToJsonProvider.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/StructuredDataToXmlProvider.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/XmlToCompositeNodeProvider.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/BrokerFacade.xtend
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ControllerContext.xtend
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/MediaTypes.java [deleted file]
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ResponseException.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.xtend
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/StructuredData.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/TestUtils.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ToJsonWithAugmentTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/XmlProvidersTest.java
opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/augment-container.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/augment-leaf.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/augment-leaflist.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/augment-list.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/xml/data.xml [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/yang.yang [new file with mode: 0644]
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsManagerActivator.java
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsProvider.java
opendaylight/md-sal/test/sal-rest-connector-it/src/test/java/org/opendaylight/controller/test/restconf/it/ServiceProviderController.java

index 55ab5caeeb2098cd00ed4095a46f8601a14536b1..5b08af79f835e39b0d729424d31cf522ea78c256 100644 (file)
           <artifactId>sal-common-util</artifactId>
           <version>${mdsal.version}</version>
         </dependency>
+        <dependency>
+          <groupId>org.opendaylight.controller</groupId>
+          <artifactId>sal-netconf-connector</artifactId>
+          <version>${mdsal.version}</version>
+        </dependency>
         <dependency>
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>sal-core-api</artifactId>
           <artifactId>forwardingrules-manager</artifactId>
           <version>${mdsal.version}</version>
         </dependency>
-
+        <dependency>
+          <groupId>org.opendaylight.controller.md</groupId>
+          <artifactId>statistics-manager</artifactId>
+          <version>${mdsal.version}</version>
+        </dependency>
         <dependency>
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>concepts</artifactId>
           <artifactId>yang-jmx-generator</artifactId>
           <version>${config.version}</version>
         </dependency>
+        <dependency>
+          <groupId>org.opendaylight.controller</groupId>
+          <artifactId>netty-event-executor-config</artifactId>
+          <version>${config.version}</version>
+        </dependency>
+        <dependency>
+          <groupId>org.opendaylight.controller</groupId>
+          <artifactId>netty-threadgroup-config</artifactId>
+          <version>${config.version}</version>
+        </dependency>
+        <dependency>
+          <groupId>org.opendaylight.controller</groupId>
+          <artifactId>threadpool-config-api</artifactId>
+          <version>${config.version}</version>
+        </dependency>
+        <dependency>
+          <groupId>org.opendaylight.controller</groupId>
+          <artifactId>threadpool-config-impl</artifactId>
+          <version>${config.version}</version>
+        </dependency>
+        <dependency>
+          <groupId>org.opendaylight.controller</groupId>
+          <artifactId>yang-store-api</artifactId>
+          <version>${config.version}</version>
+        </dependency>
         <dependency>
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>yang-store-api</artifactId>
index 67c6933cc7b3158d5435b2929cfae9bfaa99dad5..29ea8ddf1889bc8d3cfec6e37d070896fc0bd3ae 100644 (file)
@@ -4,7 +4,7 @@ module opendaylight-flow-types {
 
     import ietf-inet-types {prefix inet; revision-date "2010-09-24";}
     import ietf-yang-types {prefix yang; revision-date "2010-09-24";}    
-    import opendaylight-match-types {prefix match; revision-date 2013-10-26";}
+    import opendaylight-match-types {prefix match; revision-date "2013-10-26";}
     import opendaylight-action-types {prefix action;}
 
     revision "2013-10-26" {
index 2a16bfcf503e41369912ea646c0cc974737528a3..1b6a689750df8e3bd88e8ef632791b7a65384f3a 100644 (file)
@@ -4,7 +4,7 @@ module opendaylight-table-types {
 
     import ietf-inet-types {prefix inet; revision-date "2010-09-24";}
     import ietf-yang-types {prefix yang; revision-date "2010-09-24";}
-    import opendaylight-flow-types {prefix flow;revision-date 2013-10-26";}
+    import opendaylight-flow-types {prefix flow;revision-date "2013-10-26";}
     import opendaylight-action-types {prefix action;}
 
     revision "2013-10-26" {
index 9588652a1c6cdb8fb63901f8cb4ccf72228c7b9c..d49675ad39366bb3e8c9b3a5a191f2a677683ce7 100644 (file)
@@ -5,6 +5,7 @@ module sal-port {
     import yang-ext {prefix ext; revision-date "2013-07-09";}
     import opendaylight-inventory {prefix inv;revision-date "2013-08-19";}
     import opendaylight-port-types {prefix port-type;revision-date "2013-09-25";}
+    import flow-capable-transaction {prefix tr;}
 
     revision "2013-11-07" {
         description "Initial revision of port service";
@@ -31,6 +32,10 @@ module sal-port {
     rpc update-port {
         input {
             uses port-update;
+            uses tr:transaction-aware;
+        }
+        output {
+            uses tr:transaction-aware;
         }
     }
      
index bdbcce0950fa449dbc43a7be562fa22bbb7f3ade..94c31dd0411eb041fc11fd61adcab23dd369a105 100644 (file)
@@ -40,7 +40,8 @@
         <!-- Connectors -->
         <module>sal-connector-api</module>
         <module>sal-rest-connector</module>
-
+        <module>sal-netconf-connector</module>
+        
         <!-- Clustered Data Store -->
         <module>clustered-data-store/implementation</module>
 
index 0ddc2c88c8bd5bc99c85260bb13f7ce1c86f592b..ec69fd3b68c8ee84c39edde4e58207adb771b5bd 100644 (file)
@@ -33,6 +33,8 @@ import org.opendaylight.yangtools.binding.generator.util.Types
 import org.osgi.framework.BundleContext
 import java.util.Hashtable
 import org.osgi.framework.ServiceRegistration
+import org.opendaylight.controller.sal.binding.impl.connect.dom.DeserializationException
+import java.util.concurrent.Callable
 
 class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingService, SchemaServiceListener, AutoCloseable {
 
@@ -59,7 +61,7 @@ class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingSer
     val promisedTypeDefinitions = HashMultimap.<Type, SettableFuture<GeneratedTypeBuilder>>create;
 
     val promisedSchemas = HashMultimap.<Type, SettableFuture<SchemaNode>>create;
-    
+
     ServiceRegistration<SchemaServiceListener> listenerRegistration
 
     override onGlobalContextUpdated(SchemaContext arg0) {
@@ -79,7 +81,6 @@ class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingSer
             val context = entry.value;
             updateBindingFor(context.childNodes, schemaContext);
             updateBindingFor(context.cases, schemaContext);
-            
 
             val typedefs = context.typedefs;
             for (typedef : typedefs.values) {
@@ -89,7 +90,7 @@ class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingSer
             for (augmentation : augmentations) {
                 binding.typeToDefinition.put(augmentation, augmentation);
             }
-            
+
             binding.typeToAugmentation.putAll(context.typeToAugmentation);
         }
     }
@@ -127,22 +128,36 @@ class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingSer
     }
 
     override dataObjectFromDataDom(InstanceIdentifier<? extends DataObject> path, CompositeNode node) {
-        if (node == null) {
-            return null;
-        }
-        val targetType = path.targetType
-        val transformer = registry.getCodecForDataObject(targetType);
-        val ret = transformer.deserialize(node)?.value as DataObject;
-        return ret;
+        return tryDeserialization[ |
+            if (node == null) {
+                return null;
+            }
+            val targetType = path.targetType
+            val transformer = registry.getCodecForDataObject(targetType);
+            val ret = transformer.deserialize(node)?.value as DataObject;
+            return ret;
+        ]
     }
-    
+
     override fromDataDom(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier entry) {
-        return registry.instanceIdentifierCodec.deserialize(entry);
+        return tryDeserialization[ |
+            registry.instanceIdentifierCodec.deserialize(entry);
+        ]
+    }
+
+    private static def <T> T tryDeserialization(Callable<T> deserializationBlock) throws DeserializationException {
+        try {
+            deserializationBlock.call()
+        } catch (Exception e) {
+            // FIXME: Make this block providing more information.
+            throw new DeserializationException(e);
+        }
     }
 
     private def void updateBindingFor(Map<SchemaPath, GeneratedTypeBuilder> map, SchemaContext module) {
         for (entry : map.entrySet) {
             val schemaNode = SchemaContextUtil.findDataSchemaNode(module, entry.key);
+
             //LOG.info("{} : {}",entry.key,entry.value.fullyQualifiedName)
             if (schemaNode != null) {
                 typeToSchemaNode.put(entry.value, schemaNode);
@@ -162,8 +177,8 @@ class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingSer
         binding.typeToDefinition = typeToDefinition
         binding.typeToSchemaNode = typeToSchemaNode
         binding.typeDefinitions = typeDefinitions
-        if(ctx !== null) {
-            listenerRegistration = ctx.registerService(SchemaServiceListener,this,new Hashtable<String,String>());
+        if (ctx !== null) {
+            listenerRegistration = ctx.registerService(SchemaServiceListener, this, new Hashtable<String, String>());
         }
     }
 
@@ -217,9 +232,9 @@ class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingSer
         }
         promisedSchemas.removeAll(builder);
     }
-    
+
     override close() throws Exception {
         listenerRegistration?.unregister();
     }
-    
+
 }
index ccd6079cc997b00b9de8a2a6f5ee935155f01340..7a72afc88550b3871ea72286f5b791b4a90f568c 100644 (file)
@@ -32,7 +32,7 @@ import org.slf4j.LoggerFactory;
 
 public class BindingIndependentDataServiceConnector implements //
         RuntimeDataProvider, //
-        Provider {
+        Provider, AutoCloseable {
 
     private final Logger LOG = LoggerFactory.getLogger(BindingIndependentDataServiceConnector.class);
 
@@ -59,16 +59,24 @@ public class BindingIndependentDataServiceConnector implements //
 
     @Override
     public DataObject readOperationalData(InstanceIdentifier<? extends DataObject> path) {
-        org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath = mappingService.toDataDom(path);
-        CompositeNode result = biDataService.readOperationalData(biPath);
-        return mappingService.dataObjectFromDataDom(path, result);
+        try {
+            org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath = mappingService.toDataDom(path);
+            CompositeNode result = biDataService.readOperationalData(biPath);
+            return mappingService.dataObjectFromDataDom(path, result);
+        } catch (DeserializationException e) {
+            throw new IllegalStateException(e);
+        }
     }
 
     @Override
     public DataObject readConfigurationData(InstanceIdentifier<? extends DataObject> path) {
-        org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath = mappingService.toDataDom(path);
-        CompositeNode result = biDataService.readConfigurationData(biPath);
-        return mappingService.dataObjectFromDataDom(path, result);
+        try {
+            org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath = mappingService.toDataDom(path);
+            CompositeNode result = biDataService.readConfigurationData(biPath);
+            return mappingService.dataObjectFromDataDom(path, result);
+        } catch (DeserializationException e) {
+            throw new IllegalStateException(e);
+        }
     }
 
     private DataModificationTransaction createBindingToDomTransaction(
@@ -103,23 +111,42 @@ public class BindingIndependentDataServiceConnector implements //
                 .beginTransaction();
         for (Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> entry : source
                 .getUpdatedConfigurationData().entrySet()) {
-            InstanceIdentifier<?> baKey = mappingService.fromDataDom(entry.getKey());
-            DataObject baData = mappingService.dataObjectFromDataDom(baKey, entry.getValue());
-            target.putConfigurationData(baKey, baData);
+            try {
+                InstanceIdentifier<?> baKey = mappingService.fromDataDom(entry.getKey());
+                DataObject baData = mappingService.dataObjectFromDataDom(baKey, entry.getValue());
+                target.putConfigurationData(baKey, baData);
+            } catch (DeserializationException e) {
+                LOG.error("Ommiting from BA transaction: {}. Reason{}.", entry.getKey(), e);
+            }
         }
         for (Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> entry : source
                 .getUpdatedOperationalData().entrySet()) {
-            InstanceIdentifier<?> baKey = mappingService.fromDataDom(entry.getKey());
-            DataObject baData = mappingService.dataObjectFromDataDom(baKey, entry.getValue());
-            target.putOperationalData(baKey, baData);
+            try {
+
+                InstanceIdentifier<?> baKey = mappingService.fromDataDom(entry.getKey());
+                DataObject baData = mappingService.dataObjectFromDataDom(baKey, entry.getValue());
+                target.putOperationalData(baKey, baData);
+            } catch (DeserializationException e) {
+                LOG.error("Ommiting from BA transaction: {}. Reason{}.", entry.getKey(), e);
+            }
         }
         for (org.opendaylight.yangtools.yang.data.api.InstanceIdentifier entry : source.getRemovedConfigurationData()) {
-            InstanceIdentifier<?> baEntry = mappingService.fromDataDom(entry);
-            target.removeConfigurationData(baEntry);
+            try {
+
+                InstanceIdentifier<?> baEntry = mappingService.fromDataDom(entry);
+                target.removeConfigurationData(baEntry);
+            } catch (DeserializationException e) {
+                LOG.error("Ommiting from BA transaction: {}. Reason{}.", entry, e);
+            }
         }
         for (org.opendaylight.yangtools.yang.data.api.InstanceIdentifier entry : source.getRemovedOperationalData()) {
-            InstanceIdentifier<?> baEntry = mappingService.fromDataDom(entry);
-            target.removeOperationalData(baEntry);
+            try {
+
+                InstanceIdentifier<?> baEntry = mappingService.fromDataDom(entry);
+                target.removeOperationalData(baEntry);
+            } catch (DeserializationException e) {
+                LOG.error("Ommiting from BA transaction: {}. Reason{}.", entry, e);
+            }
         }
         return target;
     }
@@ -162,6 +189,18 @@ public class BindingIndependentDataServiceConnector implements //
         start();
     }
 
+    @Override
+    public void close() throws Exception {
+
+        if (baCommitHandlerRegistration != null) {
+            baCommitHandlerRegistration.close();
+        }
+        if (biCommitHandlerRegistration != null) {
+            biCommitHandlerRegistration.close();
+        }
+
+    }
+
     private class DomToBindingTransaction implements
             DataCommitTransaction<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> {
 
@@ -271,10 +310,11 @@ public class BindingIndependentDataServiceConnector implements //
 
         @Override
         public void onRegister(DataCommitHandlerRegistration<InstanceIdentifier<?>, DataObject> registration) {
-            
-            org.opendaylight.yangtools.yang.data.api.InstanceIdentifier domPath = mappingService.toDataDom(registration.getPath());
+
+            org.opendaylight.yangtools.yang.data.api.InstanceIdentifier domPath = mappingService.toDataDom(registration
+                    .getPath());
             // FIXME: do registration based on only active commit handlers.
-            
+
         }
 
         @Override
index 9e175b8cb0e0f6c5e79550218986e0f552ae3edd..b1983fe224d89da96f4445efa86469cc0e0e6b9d 100644 (file)
@@ -16,8 +16,8 @@ public interface BindingIndependentMappingService {
 
     org.opendaylight.yangtools.yang.data.api.InstanceIdentifier toDataDom(InstanceIdentifier<? extends DataObject> path);
 
-    DataObject dataObjectFromDataDom(InstanceIdentifier<? extends DataObject> path, CompositeNode result);
+    DataObject dataObjectFromDataDom(InstanceIdentifier<? extends DataObject> path, CompositeNode result) throws DeserializationException;
 
-    InstanceIdentifier<?> fromDataDom(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier entry);
+    InstanceIdentifier<?> fromDataDom(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier entry)  throws DeserializationException;
 
 }
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/DeserializationException.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/DeserializationException.java
new file mode 100644 (file)
index 0000000..9331899
--- /dev/null
@@ -0,0 +1,24 @@
+package org.opendaylight.controller.sal.binding.impl.connect.dom;
+
+public class DeserializationException extends Exception {
+
+    public DeserializationException() {
+    }
+
+    public DeserializationException(String message) {
+        super(message);
+    }
+
+    public DeserializationException(Throwable cause) {
+        super(cause);
+    }
+
+    public DeserializationException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public DeserializationException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
+        super(message, cause, enableSuppression, writableStackTrace);
+    }
+
+}
index fbed2ca113621c728dd00a5fa4b9ae932344d7db..504a3d639413f7f6b1b901297bbf215aa9825842 100644 (file)
@@ -4,15 +4,100 @@ import org.opendaylight.controller.md.sal.common.impl.routing.AbstractDataReadRo
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
 import org.opendaylight.yangtools.yang.data.api.CompositeNode
 import org.opendaylight.controller.md.sal.common.api.data.DataReader
+import org.opendaylight.yangtools.yang.common.QName
+import java.net.URI
+import java.util.List
+import org.opendaylight.yangtools.yang.data.api.Node
+import java.util.ArrayList
+import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl
+import java.util.Map
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier
+import org.opendaylight.yangtools.yang.data.api.SimpleNode
+import java.util.Collections
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates
+import java.util.HashMap
+import static com.google.common.base.Preconditions.*;
+import java.util.Collection
+import java.util.Set
+import java.util.Map.Entry
+import org.slf4j.LoggerFactory
+import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl
 
 class DataReaderRouter extends AbstractDataReadRouter<InstanceIdentifier, CompositeNode> {
+    private static val LOG = LoggerFactory.getLogger(DataReaderRouter);
+    private static val NETCONF_NAMESPACE = URI.create("urn:ietf:params:xml:ns:netconf:base:1.0")
+    private static val NETCONF_DATA = new QName(NETCONF_NAMESPACE,"data");
 
     override protected merge(InstanceIdentifier path, Iterable<CompositeNode> data) {
+        val pathArgument = path.path.last;
+        var empty = true;
+        var name = pathArgument?.nodeType;
+        val nodes = new ArrayList<Node<?>>();
+        val keyNodes = new HashMap<QName, SimpleNode<?>>();
         val iterator = data.iterator;
-        if(iterator.hasNext) {
-            return data.iterator.next
+        for(dataBit : data) {
+            try {
+                if(pathArgument != null && dataBit != null) {
+                    empty = false;
+                    val keyNodesLocal = getKeyNodes(pathArgument,dataBit);
+                    nodes.addAll(dataBit.childrenWithout(keyNodesLocal.entrySet));
+                } else if (dataBit != null) {
+                    empty = false;
+                    nodes.addAll(dataBit.children)
+                }
+            }   catch (IllegalStateException e) {
+                LOG.error("BUG: Readed data for path {} was invalid",path,e);
+            }
         }
-        return null;
+        if(empty) {
+            return null;
+        }
+        /**
+         * Reading from Root
+         * 
+         */
+        if(pathArgument == null) {
+            return new CompositeNodeTOImpl(NETCONF_DATA,null,nodes);
+        }
+        val finalNodes = new ArrayList<Node<?>>();
+        finalNodes.addAll(keyNodes.values);
+        finalNodes.addAll(nodes);
+        return new CompositeNodeTOImpl(name,null,finalNodes);
     }
-
+    
+    
+    
+    dispatch def Map<QName, SimpleNode<?>> getKeyNodes(PathArgument argument, CompositeNode node) {
+        return Collections.emptyMap();
+    }
+    
+    dispatch def getKeyNodes(NodeIdentifierWithPredicates argument, CompositeNode node) {
+        val ret = new HashMap<QName, SimpleNode<?>>();
+        for (keyValue : argument.keyValues.entrySet) {
+            val simpleNode = node.getSimpleNodesByName(keyValue.key);
+            if(simpleNode !== null && !simpleNode.empty) {
+                checkState(simpleNode.size <= 1,"Only one simple node for key $s is allowed in node $s",keyValue.key,node);
+                checkState(simpleNode.get(0).value == keyValue.value,"Key node must equals to instance identifier value");
+                ret.put(keyValue.key,simpleNode.get(0));
+            }
+            val compositeNode = node.getCompositesByName(keyValue.key);
+            checkState(compositeNode === null || compositeNode.empty,"Key node must be Simple Node, not composite node.");
+        }
+        return ret;
+    }
+    
+    def Collection<? extends Node<?>> childrenWithout(CompositeNode node, Set<Entry<QName, SimpleNode<?>>> entries) {
+        if(entries.empty) {
+            return node.children;
+        }
+        val filteredNodes = new ArrayList<Node<?>>();
+        for(scannedNode : node.children) {
+            if(!entries.contains(scannedNode.nodeType)) {
+                filteredNodes.add(scannedNode);
+            }
+        }
+        return filteredNodes;
+    }
+    
 }
index 6ef5780c8a577c1bc93c97bd95420a50d608f5fc..e790a9dbb1bbd396570445e0e58da1eee105e443 100644 (file)
             <groupId>org.eclipse.xtend</groupId>
             <artifactId>org.eclipse.xtend.lib</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>netty-threadgroup-config</artifactId>
+            <version>0.2.3-SNAPSHOT</version>
+        </dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>netconf-client</artifactId>
@@ -62,7 +67,7 @@
             <groupId>${project.groupId}</groupId>
             <artifactId>config-api</artifactId>
             <version>${netconf.version}</version>
-            <scope>test</scope>
+            <scope>provided</scope>
         </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
             <version>${netconf.version}</version>
             <scope>test</scope>
         </dependency>
-        <dependency>
-            <groupId>${project.groupId}</groupId>
-            <artifactId>netconf-api</artifactId>
-            <version>${netconf.version}</version>
-            <scope>test</scope>
-        </dependency>
         <dependency>
             <groupId>org.opendaylight.bgpcep</groupId>
             <artifactId>util</artifactId>
@@ -91,7 +90,6 @@
         <dependency>
             <groupId>${project.groupId}</groupId>
             <artifactId>netconf-client</artifactId>
-            <scope>test</scope>
             <version>${netconf.version}</version>
         </dependency>
         <dependency>
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-api</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.opendaylight.yangtools.model</groupId>
+            <artifactId>ietf-inet-types</artifactId>
+            <version>2010.09.24.2-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>threadpool-config-api</artifactId>
+            <version>0.2.3-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>netty-config-api</artifactId>
+            <version>0.2.3-SNAPSHOT</version>
+        </dependency>
     </dependencies>
 
     <packaging>bundle</packaging>
             <plugin>
                 <groupId>org.apache.felix</groupId>
                 <artifactId>maven-bundle-plugin</artifactId>
-                <configuration>
-                    <instructions>
-                        <Bundle-Activator>org.opendaylight.controller.sal.connect.netconf.NetconfProvider</Bundle-Activator>
-                    </instructions>
-                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.opendaylight.yangtools</groupId>
+                <artifactId>yang-maven-plugin</artifactId>
+                <version>0.5.9-SNAPSHOT</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>generate-sources</goal>
+                        </goals>
+                        <configuration>
+                            <codeGenerators>
+                                <generator>
+                                    <codeGeneratorClass>
+                                        org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+                                    </codeGeneratorClass>
+                                    <outputBaseDir>${project.build.directory}/generated-sources/config</outputBaseDir>
+                                    <additionalConfiguration>
+                                        <namespaceToPackage1>
+                                            urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang
+                                        </namespaceToPackage1>
+                                    </additionalConfiguration>
+                                </generator>
+                            </codeGenerators>
+                            <inspectDependencies>true</inspectDependencies>
+                        </configuration>
+                    </execution>
+                </executions>
+                <dependencies>
+                    <dependency>
+                        <groupId>org.opendaylight.controller</groupId>
+                        <artifactId>yang-jmx-generator-plugin</artifactId>
+                        <version>0.2.3-SNAPSHOT</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>
+
+            <plugin>
+                <groupId>org.eclipse.xtend</groupId>
+                <artifactId>xtend-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/connector/netconf/NetconfConnectorModule.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/connector/netconf/NetconfConnectorModule.java
new file mode 100644 (file)
index 0000000..2a556c9
--- /dev/null
@@ -0,0 +1,89 @@
+/**
+* Generated file
+
+* Generated from: yang module name: opendaylight-sal-netconf-connector  yang module local name: sal-netconf-connector
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Mon Nov 18 09:44:16 CET 2013
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.controller.config.yang.md.sal.connector.netconf;
+
+import io.netty.channel.EventLoopGroup;
+
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+
+import javax.net.ssl.SSLContext;
+
+import org.opendaylight.controller.netconf.client.NetconfClientDispatcher;
+import org.opendaylight.controller.sal.connect.netconf.NetconfDevice;
+import org.osgi.framework.BundleContext;
+
+import static com.google.common.base.Preconditions.*;
+
+import com.google.common.base.Optional;
+import com.google.common.net.InetAddresses;
+
+/**
+*
+*/
+public final class NetconfConnectorModule extends org.opendaylight.controller.config.yang.md.sal.connector.netconf.AbstractNetconfConnectorModule
+{
+
+    private BundleContext bundleContext;
+
+    public NetconfConnectorModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+        super(identifier, dependencyResolver);
+    }
+
+    public NetconfConnectorModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, NetconfConnectorModule oldModule, java.lang.AutoCloseable oldInstance) {
+        super(identifier, dependencyResolver, oldModule, oldInstance);
+    }
+
+    @Override
+    public void validate(){
+        super.validate();
+        checkState(getAddress() != null,"Address must be set.");
+        //checkState(getAddress().getIpv4Address() != null || getAddress().getIpv6Address() != null,"Address must be set.");
+        checkState(getPort() != null,"Port must be set.");
+        checkState(getDomRegistry() != null,"Dom Registry must be provided.");
+    }
+
+
+    @Override
+    public java.lang.AutoCloseable createInstance() {
+        
+        getDomRegistryDependency();
+        NetconfDevice device = new NetconfDevice(getIdentifier().getInstanceName());
+        String addressValue = getAddress();
+        
+        
+        /*
+         * Uncomment after Switch to IP Address
+        if(getAddress().getIpv4Address() != null) {
+            addressValue = getAddress().getIpv4Address().getValue();
+        } else {
+            addressValue = getAddress().getIpv6Address().getValue();
+        }
+        
+        */
+        InetAddress addr = InetAddresses.forString(addressValue);
+        InetSocketAddress socketAddress = new InetSocketAddress(addr , getPort().intValue());
+        device.setSocketAddress(socketAddress);
+        
+        EventLoopGroup bossGroup = getBossThreadGroupDependency();
+        EventLoopGroup workerGroup = getWorkerThreadGroupDependency();
+        Optional<SSLContext> maybeContext = Optional.absent();
+        NetconfClientDispatcher dispatcher = new NetconfClientDispatcher(maybeContext , bossGroup, workerGroup);
+        
+        getDomRegistryDependency().registerProvider(device, bundleContext);
+        
+        device.start(dispatcher);
+        return device;
+    }
+
+    public void setBundleContext(BundleContext bundleContext) {
+        this.bundleContext = bundleContext;
+    }
+}
diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/connector/netconf/NetconfConnectorModuleFactory.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/connector/netconf/NetconfConnectorModuleFactory.java
new file mode 100644 (file)
index 0000000..51e288d
--- /dev/null
@@ -0,0 +1,39 @@
+/**
+ * Generated file
+
+ * Generated from: yang module name: opendaylight-sal-netconf-connector  yang module local name: sal-netconf-connector
+ * Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+ * Generated at: Mon Nov 18 09:44:16 CET 2013
+ *
+ * Do not modify this file unless it is present under src/main directory
+ */
+package org.opendaylight.controller.config.yang.md.sal.connector.netconf;
+
+import org.opendaylight.controller.config.api.DependencyResolver;
+import org.opendaylight.controller.config.api.DynamicMBeanWithInstance;
+import org.opendaylight.controller.config.spi.Module;
+import org.osgi.framework.BundleContext;
+
+/**
+*
+*/
+public class NetconfConnectorModuleFactory extends
+        org.opendaylight.controller.config.yang.md.sal.connector.netconf.AbstractNetconfConnectorModuleFactory {
+
+    @Override
+    public Module createModule(String instanceName, DependencyResolver dependencyResolver,
+            DynamicMBeanWithInstance old, BundleContext bundleContext) throws Exception {
+        NetconfConnectorModule module = (NetconfConnectorModule) super.createModule(instanceName, dependencyResolver,
+                old, bundleContext);
+        module.setBundleContext(bundleContext);
+        return module;
+    }
+
+    @Override
+    public Module createModule(String instanceName, DependencyResolver dependencyResolver, BundleContext bundleContext) {
+        NetconfConnectorModule module = (NetconfConnectorModule) super.createModule(instanceName, dependencyResolver,
+                bundleContext);
+        module.setBundleContext(bundleContext);
+        return module;
+    }
+}
index 0171c1f9e312b5020f26ee4dec1d0b23a8f34cf2..49d9757f421058cb05ffed90f81922f6509ff688 100644 (file)
@@ -14,8 +14,16 @@ import org.opendaylight.yangtools.yang.common.QName
 import java.util.Collections
 import org.opendaylight.controller.netconf.client.NetconfClientDispatcher
 import org.opendaylight.yangtools.concepts.Registration
+import org.opendaylight.controller.sal.core.api.Provider
+import org.opendaylight.controller.sal.core.api.Broker.ProviderSession
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionService
+import static org.opendaylight.controller.sal.connect.netconf.InventoryUtils.*;
+import org.opendaylight.controller.sal.core.api.data.DataBrokerService
+import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction
+import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl
+import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl
 
-class NetconfDevice implements DataReader<InstanceIdentifier, CompositeNode>, RpcImplementation {
+class NetconfDevice implements Provider, DataReader<InstanceIdentifier, CompositeNode>, RpcImplementation, AutoCloseable {
 
     var NetconfClient client;
 
@@ -23,25 +31,29 @@ class NetconfDevice implements DataReader<InstanceIdentifier, CompositeNode>, Rp
     var InetSocketAddress socketAddress;
 
     @Property
-    val MountProvisionInstance mountInstance;
+    var MountProvisionInstance mountInstance;
 
     @Property
-    val InstanceIdentifier path;
-    
-    Registration<DataReader<InstanceIdentifier,CompositeNode>> operReaderReg
-    
-    Registration<DataReader<InstanceIdentifier,CompositeNode>> confReaderReg
-    
-    public new(MountProvisionInstance mount,InstanceIdentifier path) {
-        _mountInstance = mount;
-        _path = path;
+    var InstanceIdentifier path;
+
+    Registration<DataReader<InstanceIdentifier, CompositeNode>> operReaderReg
+
+    Registration<DataReader<InstanceIdentifier, CompositeNode>> confReaderReg
+
+    String name
+
+    MountProvisionService mountService
+
+    public new(String name) {
+        this.name = name;
+        this.path = InstanceIdentifier.builder(INVENTORY_PATH).nodeWithKey(INVENTORY_NODE,
+            Collections.singletonMap(INVENTORY_ID, name)).toInstance;
     }
 
     def start(NetconfClientDispatcher dispatcher) {
-        client = new NetconfClient("sal-netconf-connector", socketAddress, dispatcher);
-        
-        confReaderReg = mountInstance.registerConfigurationReader(path,this);
-        operReaderReg = mountInstance.registerOperationalReader(path,this);
+        client = new NetconfClient(name, socketAddress, dispatcher);
+        confReaderReg = mountInstance.registerConfigurationReader(path, this);
+        operReaderReg = mountInstance.registerOperationalReader(path, this);
     }
 
     override readConfigurationData(InstanceIdentifier path) {
@@ -66,6 +78,40 @@ class NetconfDevice implements DataReader<InstanceIdentifier, CompositeNode>, Rp
         return result.toRpcResult();
     }
 
+    override getProviderFunctionality() {
+        Collections.emptySet
+    }
+
+    override onSessionInitiated(ProviderSession session) {
+        val dataBroker = session.getService(DataBrokerService);
+        
+        
+        
+        val transaction = dataBroker.beginTransaction
+        if(transaction.operationalNodeNotExisting) {
+            transaction.putOperationalData(path,nodeWithId)
+        }
+        if(transaction.configurationNodeNotExisting) {
+            transaction.putConfigurationData(path,nodeWithId)
+        }
+        transaction.commit().get();
+        mountService = session.getService(MountProvisionService);
+        mountInstance = mountService.createOrGetMountPoint(path);
+    }
+    
+    def getNodeWithId() {
+        val id = new SimpleNodeTOImpl(INVENTORY_ID,null,name);
+        return new CompositeNodeTOImpl(INVENTORY_NODE,null,Collections.singletonList(id));
+    }
+    
+    def boolean configurationNodeNotExisting(DataModificationTransaction transaction) {
+        return null === transaction.readConfigurationData(path);
+    }
+    
+    def boolean operationalNodeNotExisting(DataModificationTransaction transaction) {
+        return null === transaction.readOperationalData(path);
+    }
+
     def Node<?> findNode(CompositeNode node, InstanceIdentifier identifier) {
 
         var Node<?> current = node;
@@ -86,10 +132,11 @@ class NetconfDevice implements DataReader<InstanceIdentifier, CompositeNode>, Rp
         }
         return current;
     }
-    
-    public def stop() {
+
+    override close() {
         confReaderReg?.close()
         operReaderReg?.close()
+        client?.close()
     }
 
 }
diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceManager.xtend b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceManager.xtend
deleted file mode 100644 (file)
index 2fe145e..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-package org.opendaylight.controller.sal.connect.netconf
-
-import org.opendaylight.controller.sal.core.api.Broker.ProviderSession
-import org.opendaylight.controller.sal.core.api.mount.MountProvisionService
-import org.opendaylight.controller.md.sal.common.api.data.DataProvisionService
-import org.opendaylight.controller.sal.core.api.data.DataProviderService
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
-import org.opendaylight.yangtools.yang.common.QName
-import static org.opendaylight.controller.sal.connect.netconf.InventoryUtils.*;
-import static extension org.opendaylight.controller.sal.connect.netconf.NetconfInventoryUtils.*;
-
-import org.opendaylight.controller.sal.core.api.data.DataChangeListener
-import org.opendaylight.yangtools.yang.data.api.CompositeNode
-import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent
-import java.util.Map
-import java.util.concurrent.ConcurrentHashMap
-import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance
-import org.opendaylight.controller.netconf.client.NetconfClientDispatcher
-import java.io.OptionalDataException
-import com.google.common.base.Optional
-import java.net.SocketAddress
-import java.net.InetSocketAddress
-
-class NetconfDeviceManager {
-
-    val Map<InstanceIdentifier, NetconfDevice> devices = new ConcurrentHashMap;
-
-    var ProviderSession session;
-
-    @Property
-    var DataProviderService dataService;
-    
-    @Property
-    var MountProvisionService mountService;
-    
-    val nodeUpdateListener = new NetconfInventoryListener(this);
-
-
-    @Property
-    var NetconfClientDispatcher dispatcher;
-
-    def void start() {
-        dataService?.registerDataChangeListener(INVENTORY_PATH, nodeUpdateListener);
-        if(dispatcher == null) {
-        dispatcher = new NetconfClientDispatcher(Optional.absent);
-        }
-    }
-
-    def netconfNodeAdded(InstanceIdentifier path, CompositeNode node) {
-        val address = node.endpointAddress;
-        val port = Integer.parseInt(node.endpointPort);
-        netconfNodeAdded(path,new InetSocketAddress(address,port))
-
-    }
-    
-    def netconfNodeAdded(InstanceIdentifier path, InetSocketAddress address) {
-    
-        val mountPointPath = path;
-        val mountPoint = mountService.createOrGetMountPoint(mountPointPath);
-        val localPath = InstanceIdentifier.builder().toInstance;
-        val netconfDevice = new NetconfDevice(mountPoint,localPath);
-        netconfDevice.setSocketAddress(address);
-        netconfDevice.start(dispatcher);
-    }
-
-    def netconfNodeRemoved(InstanceIdentifier path) {
-    
-    }
-
-}
-
-class NetconfInventoryListener implements DataChangeListener {
-
-    val NetconfDeviceManager manager;
-
-    new(NetconfDeviceManager manager) {
-        this.manager = manager;
-    }
-
-    override onDataChanged(DataChangeEvent<InstanceIdentifier, CompositeNode> change) {
-        
-        //manager.netconfNodeAdded(path, change);
-    }
-}
diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfProvider.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfProvider.java
deleted file mode 100644 (file)
index 8cf5f02..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-package org.opendaylight.controller.sal.connect.netconf;
-
-import java.util.Hashtable;
-
-import org.opendaylight.controller.sal.core.api.AbstractProvider;
-import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
-import org.opendaylight.controller.sal.core.api.data.DataProviderService;
-import org.opendaylight.controller.sal.core.api.mount.MountProvisionService;
-import org.osgi.framework.BundleContext;
-
-public class NetconfProvider extends AbstractProvider {
-
-    private NetconfDeviceManager netconfDeviceManager;
-
-    @Override
-    protected void startImpl(BundleContext context) {
-        netconfDeviceManager = new NetconfDeviceManager();
-        context.registerService(NetconfDeviceManager.class, netconfDeviceManager, new Hashtable<String,String>());
-    }
-    
-    
-    @Override
-    public void onSessionInitiated(ProviderSession session) {
-        MountProvisionService mountService = session.getService(MountProvisionService.class);
-        
-        
-        netconfDeviceManager.setMountService(mountService);
-        netconfDeviceManager.start();
-    }
-
-    @Override
-    protected void stopImpl(BundleContext context) {
-        
-    }
-}
diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/yang/odl-sal-netconf-connector-cfg.yang b/opendaylight/md-sal/sal-netconf-connector/src/main/yang/odl-sal-netconf-connector-cfg.yang
new file mode 100644 (file)
index 0000000..45f1016
--- /dev/null
@@ -0,0 +1,75 @@
+module odl-sal-netconf-connector-cfg {
+    yang-version 1;
+    namespace "urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf";
+    prefix "sal-netconf";
+
+       import config { prefix config; revision-date 2013-04-05; }
+       import threadpool {prefix th;}
+       import netty {prefix netty;}
+       import ietf-inet-types {prefix inet;}
+       import opendaylight-md-sal-dom {prefix dom;}
+
+    description
+        "Service definition for Binding Aware MD-SAL.";
+    revision "2013-10-28" {
+        description
+            "Initial revision";
+    }
+
+    identity sal-netconf-connector {
+        base config:module-type;
+        config:java-name-prefix NetconfConnector;
+    }
+
+
+    grouping server {
+        leaf address {
+            type string;
+        }
+    
+        leaf port {
+            type uint32;
+        }
+    }
+
+
+    augment "/config:modules/config:module/config:configuration" {
+        case sal-netconf-connector {
+            when "/config:modules/config:module/config:type = 'sal-netconf-connector'";
+            
+            leaf address {
+                type string;
+            }
+
+            leaf port {
+                type uint32;
+            }
+
+            container dom-registry {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity dom:dom-broker-osgi-registry;
+                    }
+                }
+            }
+
+            container boss-thread-group {
+                uses config:service-ref {
+                    refine type {
+                        config:required-identity netty:netty-threadgroup;
+                    }
+                }
+            }
+
+            container worker-thread-group {
+                uses config:service-ref {
+                    refine type {
+                        config:required-identity netty:netty-threadgroup;
+                    }
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/Draft01.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/Draft01.java
new file mode 100644 (file)
index 0000000..557adb6
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.rest.api;
+
+public class Draft01 {
+    public static class MediaTypes {
+        public static final String API = "application/vnd.yang.api";
+        public static final String DATASTORE = "application/vnd.yang.datastore";
+        public static final String DATA = "application/vnd.yang.data";
+        public static final String EVENT = "application/vnd.yang.event";
+        public static final String OPERATION = "application/vnd.yang.operation";
+        public static final String PATCH = "application/vnd.yang.patch";
+    }
+}
index a22ea623975049cd3bd37c8af3103fecce4317e4..5d08b3e7b6cb27bec3e2bbb68c5c1f9927f603aa 100644 (file)
@@ -7,14 +7,13 @@
  */
 package org.opendaylight.controller.sal.rest.api;
 
-import static org.opendaylight.controller.sal.restconf.impl.MediaTypes.API;
-
 import javax.ws.rs.GET;
 import javax.ws.rs.POST;
 import javax.ws.rs.PUT;
 import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 
 import org.opendaylight.controller.sal.restconf.impl.StructuredData;
@@ -58,42 +57,51 @@ public interface RestconfService extends RestconfServiceLegacy {
 
     @GET
     @Path("/modules")
-    @Produces({API+JSON,API+XML})
+    @Produces({Draft01.MediaTypes.API+JSON,Draft01.MediaTypes.API+XML,
+               Draft02.MediaTypes.API+JSON,Draft02.MediaTypes.API+XML})
     public StructuredData getModules();
 
     @POST
     @Path("/operations/{identifier}")
-    @Produces({Draft02.MediaTypes.API+JSON,Draft02.MediaTypes.API+XML,API+JSON,API+XML})
+    @Produces({Draft01.MediaTypes.DATA+JSON,Draft01.MediaTypes.DATA+XML,
+               Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML, 
+               MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
     public StructuredData invokeRpc(@PathParam("identifier") String identifier, CompositeNode payload);
     
     @GET
     @Path("/config/{identifier:.+}")
-    @Produces({Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML})
+    @Produces({Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML, 
+               MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
     public StructuredData readConfigurationData(@PathParam("identifier") String identifier);
     
-    @PUT
+    @POST
     @Path("/config/{identifier:.+}")
-    @Produces({API+JSON,API+XML})
+    @Produces({Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML, 
+               MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
     public Response createConfigurationData(@PathParam("identifier") String identifier, CompositeNode payload);
 
-    @POST
+    @PUT
     @Path("/config/{identifier:.+}")
-    @Produces({API+JSON,API+XML})
+    @Produces({Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML, 
+               MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
     public Response updateConfigurationData(@PathParam("identifier") String identifier, CompositeNode payload);
 
     @GET
     @Path("/operational/{identifier:.+}")
-    @Produces({Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML})
+    @Produces({Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML, 
+               MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
     public StructuredData readOperationalData(@PathParam("identifier") String identifier);
 
-    @PUT
+    @POST
     @Path("/operational/{identifier:.+}")
-    @Produces({API+JSON,API+XML})
+    @Produces({Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML, 
+               MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
     public Response createOperationalData(@PathParam("identifier") String identifier, CompositeNode payload);
 
-    @POST
+    @PUT
     @Path("/operational/{identifier:.+}")
-    @Produces({API+JSON,API+XML})
+    @Produces({Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML, 
+               MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
     public Response updateOperationalData(@PathParam("identifier") String identifier, CompositeNode payload);
 
 }
index 242e7f3150d4b775ce56d957ae62ba947a080eba..35da98b1a0db82e72d6cb32de8e0e34c858e1a41 100644 (file)
@@ -1,13 +1,12 @@
 package org.opendaylight.controller.sal.rest.api;
 
-import static org.opendaylight.controller.sal.restconf.impl.MediaTypes.API;
-
 import javax.ws.rs.GET;
 import javax.ws.rs.POST;
 import javax.ws.rs.PUT;
 import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 
 import org.opendaylight.controller.sal.restconf.impl.StructuredData;
@@ -21,25 +20,28 @@ public interface RestconfServiceLegacy {
     @Deprecated
     @GET
     @Path("/datastore")
-    @Produces({API+JSON,API+XML})
+    @Produces({Draft01.MediaTypes.DATASTORE+JSON,Draft01.MediaTypes.DATASTORE+XML})
     public StructuredData readAllData();
 
     @Deprecated
     @GET
     @Path("/datastore/{identifier:.+}")
-    @Produces({API+JSON,API+XML})
+    @Produces({Draft01.MediaTypes.DATA+JSON,Draft01.MediaTypes.DATA+XML, 
+               MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
     public StructuredData readData(@PathParam("identifier") String identifier);
 
     @Deprecated
-    @PUT
+    @POST
     @Path("/datastore/{identifier:.+}")
-    @Produces({API+JSON,API+XML})
+    @Produces({Draft01.MediaTypes.DATA+JSON,Draft01.MediaTypes.DATA+XML, 
+               MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
     public Response createConfigurationDataLegacy(@PathParam("identifier") String identifier, CompositeNode payload);
 
     @Deprecated
-    @POST
+    @PUT
     @Path("/datastore/{identifier:.+}")
-    @Produces({API+JSON,API+XML})
+    @Produces({Draft01.MediaTypes.DATA+JSON,Draft01.MediaTypes.DATA+XML, 
+               MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
     public Response updateConfigurationDataLegacy(@PathParam("identifier") String identifier, CompositeNode payload);
 
 }
index 073b24e033914a1fe2e227d6e78c351b1c75b8a0..351ae6ebbee085614943d7608ec51669a204f1ff 100644 (file)
@@ -7,9 +7,8 @@ import java.util.*;
 
 import javax.activation.UnsupportedDataTypeException;
 
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.Node;
-import org.opendaylight.yangtools.yang.data.api.SimpleNode;
+import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
+import org.opendaylight.yangtools.yang.data.api.*;
 import org.opendaylight.yangtools.yang.model.api.*;
 import org.opendaylight.yangtools.yang.model.api.type.*;
 
@@ -103,14 +102,15 @@ class JsonMapper {
     }
 
     private void writeContainer(JsonWriter writer, CompositeNode node, ContainerSchemaNode schema) throws IOException {
-        writer.name(node.getNodeType().getLocalName());
+        writeName(node, schema, writer);
         writer.beginObject();
         writeChildrenOfParent(writer, node, schema);
         writer.endObject();
     }
 
-    private void writeList(JsonWriter writer, CompositeNode nodeParent, CompositeNode node, ListSchemaNode schema) throws IOException {
-        writer.name(node.getNodeType().getLocalName());
+    private void writeList(JsonWriter writer, CompositeNode nodeParent, CompositeNode node, ListSchemaNode schema)
+            throws IOException {
+        writeName(node, schema, writer);
         writer.beginArray();
 
         if (nodeParent != null) {
@@ -129,8 +129,9 @@ class JsonMapper {
         writer.endArray();
     }
 
-    private void writeLeafList(JsonWriter writer, CompositeNode nodeParent, SimpleNode<?> node, LeafListSchemaNode schema) throws IOException {
-        writer.name(node.getNodeType().getLocalName());
+    private void writeLeafList(JsonWriter writer, CompositeNode nodeParent, SimpleNode<?> node,
+            LeafListSchemaNode schema) throws IOException {
+        writeName(node, schema, writer);
         writer.beginArray();
 
         List<SimpleNode<?>> nodeLeafLists = nodeParent.getSimpleNodesByName(node.getNodeType());
@@ -142,17 +143,14 @@ class JsonMapper {
     }
 
     private void writeLeaf(JsonWriter writer, SimpleNode<?> node, LeafSchemaNode schema) throws IOException {
-        writer.name(node.getNodeType().getLocalName());
+        writeName(node, schema, writer);
         writeValueOfNodeByType(writer, node, schema.getType());
     }
 
     private void writeValueOfNodeByType(JsonWriter writer, SimpleNode<?> node, TypeDefinition<?> type)
             throws IOException {
-        if (!(node.getValue() instanceof String)) {
-            throw new IllegalStateException("Value in SimpleNode should be type String");
-        }
 
-        String value = (String) node.getValue();
+        String value = String.valueOf(node.getValue());
         // TODO check Leafref, InstanceIdentifierTypeDefinition,
         // IdentityrefTypeDefinition, UnionTypeDefinition
         TypeDefinition<?> baseType = resolveBaseTypeFrom(type);
@@ -168,7 +166,7 @@ class JsonMapper {
         } else if (baseType instanceof EmptyTypeDefinition) {
             writeEmptyDataTypeToJson(writer);
         } else {
-            writer.value(value != null ? value : "");
+            writer.value(value.equals("null") ? "" : value);
         }
     }
 
@@ -244,6 +242,19 @@ class JsonMapper {
         return type.getBaseType() != null ? resolveBaseTypeFrom(type.getBaseType()) : type;
     }
 
+    private void writeName(Node<?> node, DataSchemaNode schema, JsonWriter writer) throws IOException {
+        String nameForOutput = node.getNodeType().getLocalName();
+        if (schema.isAugmenting()) {
+            ControllerContext contContext = ControllerContext.getInstance();
+            CharSequence moduleName;
+            moduleName = contContext.toRestconfIdentifier(schema.getQName());
+            if (moduleName != null) {
+                nameForOutput = moduleName.toString();
+            }
+        }
+        writer.name(nameForOutput);
+    }
+
     private static final class NumberForJsonWriter extends Number {
 
         private static final long serialVersionUID = -3147729419814417666L;
index dea4a73cd17d23f53f7c88d9b2ace669b285a2a6..2b1abaa987a6488a5626b8c0e2d48f5517abf80a 100644 (file)
@@ -1,7 +1,5 @@
 package org.opendaylight.controller.sal.rest.impl;
 
-import static org.opendaylight.controller.sal.restconf.impl.MediaTypes.API;
-
 import java.io.IOException;
 import java.io.InputStream;
 import java.lang.annotation.Annotation;
@@ -15,14 +13,17 @@ import javax.ws.rs.core.Response;
 import javax.ws.rs.ext.MessageBodyReader;
 import javax.ws.rs.ext.Provider;
 
+import org.opendaylight.controller.sal.rest.api.Draft01;
+import org.opendaylight.controller.sal.rest.api.Draft02;
 import org.opendaylight.controller.sal.rest.api.RestconfService;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 
 @Provider
-@Consumes({API+RestconfService.JSON})
+@Consumes({ Draft01.MediaTypes.DATA + RestconfService.JSON, Draft02.MediaTypes.DATA + RestconfService.JSON,
+        MediaType.APPLICATION_JSON })
 public enum JsonToCompositeNodeProvider implements MessageBodyReader<CompositeNode> {
     INSTANCE;
-    
+
     @Override
     public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
         return true;
@@ -36,8 +37,8 @@ public enum JsonToCompositeNodeProvider implements MessageBodyReader<CompositeNo
         try {
             return jsonReader.read(entityStream);
         } catch (UnsupportedFormatException e) {
-            throw new WebApplicationException(e,Response.status(Response.Status.BAD_REQUEST)
-                    .entity(e.getMessage()).build());
+            throw new WebApplicationException(e, Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage())
+                    .build());
         }
     }
 
index 90e6d2affc5cde925d4adc941b24d42005aad117..7022db2bc9bba631b2b21f50f2bb2a20d395d7d5 100644 (file)
@@ -1,7 +1,5 @@
 package org.opendaylight.controller.sal.rest.impl;
 
-import static org.opendaylight.controller.sal.restconf.impl.MediaTypes.API;
-
 import java.io.IOException;
 import java.io.OutputStream;
 import java.io.OutputStreamWriter;
@@ -16,6 +14,8 @@ import javax.ws.rs.core.Response;
 import javax.ws.rs.ext.MessageBodyWriter;
 import javax.ws.rs.ext.Provider;
 
+import org.opendaylight.controller.sal.rest.api.Draft01;
+import org.opendaylight.controller.sal.rest.api.Draft02;
 import org.opendaylight.controller.sal.rest.api.RestconfService;
 import org.opendaylight.controller.sal.restconf.impl.StructuredData;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
@@ -24,10 +24,11 @@ import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
 import com.google.gson.stream.JsonWriter;
 
 @Provider
-@Produces({API+RestconfService.JSON})
+@Produces({ Draft01.MediaTypes.DATA + RestconfService.JSON, Draft02.MediaTypes.DATA + RestconfService.JSON,
+        MediaType.APPLICATION_JSON })
 public enum StructuredDataToJsonProvider implements MessageBodyWriter<StructuredData> {
     INSTANCE;
-    
+
     @Override
     public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
         return true;
index 9f41b571dade2dc5eb806e350a6e229d17598ded..d0c007795263be5d8777ebd9af29774a8b47d0d9 100644 (file)
@@ -1,7 +1,5 @@
 package org.opendaylight.controller.sal.rest.impl;
 
-import static org.opendaylight.controller.sal.restconf.impl.MediaTypes.API;
-
 import java.io.IOException;
 import java.io.OutputStream;
 import java.lang.annotation.Annotation;
@@ -21,7 +19,10 @@ import javax.xml.transform.TransformerFactory;
 import javax.xml.transform.dom.DOMSource;
 import javax.xml.transform.stream.StreamResult;
 
+import org.opendaylight.controller.sal.rest.api.Draft01;
+import org.opendaylight.controller.sal.rest.api.Draft02;
 import org.opendaylight.controller.sal.rest.api.RestconfService;
+import org.opendaylight.controller.sal.restconf.impl.ResponseException;
 import org.opendaylight.controller.sal.restconf.impl.StructuredData;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.opendaylight.yangtools.yang.data.impl.NodeUtils;
@@ -30,10 +31,11 @@ import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
 
 @Provider
-@Produces({API+RestconfService.XML})
+@Produces({ Draft01.MediaTypes.DATA + RestconfService.XML, Draft02.MediaTypes.DATA + RestconfService.XML,
+        MediaType.APPLICATION_XML, MediaType.TEXT_XML })
 public enum StructuredDataToXmlProvider implements MessageBodyWriter<StructuredData> {
     INSTANCE;
-    
+
     private final static Logger logger = LoggerFactory.getLogger(StructuredDataToXmlProvider.class);
 
     @Override
@@ -52,9 +54,9 @@ public enum StructuredDataToXmlProvider implements MessageBodyWriter<StructuredD
             throws IOException, WebApplicationException {
         CompositeNode data = t.getData();
         if (data == null) {
-            throw new WebApplicationException(Response.status(Response.Status.NOT_FOUND).build());
+            throw new ResponseException(Response.Status.NOT_FOUND, "No data exists.");
         }
-        
+
         Document domTree = NodeUtils.buildShadowDomTree(data);
         try {
             TransformerFactory tf = TransformerFactory.newInstance();
@@ -67,7 +69,7 @@ public enum StructuredDataToXmlProvider implements MessageBodyWriter<StructuredD
             transformer.transform(new DOMSource(domTree), new StreamResult(entityStream));
         } catch (TransformerException e) {
             logger.error("Error during translation of Document to OutputStream", e);
-            throw new WebApplicationException(Response.status(Response.Status.INTERNAL_SERVER_ERROR).build());
+            throw new ResponseException(Response.Status.INTERNAL_SERVER_ERROR, e.getMessage());
         }
     }
 
index 19720107d3b2e12a63e10cedec8ec173b7ea52e8..f09c3b4cc1769dfd02ff1b5e8666b14571673451 100644 (file)
@@ -1,7 +1,5 @@
 package org.opendaylight.controller.sal.rest.impl;
 
-import static org.opendaylight.controller.sal.restconf.impl.MediaTypes.API;
-
 import java.io.IOException;
 import java.io.InputStream;
 import java.lang.annotation.Annotation;
@@ -16,11 +14,15 @@ import javax.ws.rs.ext.MessageBodyReader;
 import javax.ws.rs.ext.Provider;
 import javax.xml.stream.XMLStreamException;
 
+import org.opendaylight.controller.sal.rest.api.Draft01;
+import org.opendaylight.controller.sal.rest.api.Draft02;
 import org.opendaylight.controller.sal.rest.api.RestconfService;
+import org.opendaylight.controller.sal.restconf.impl.ResponseException;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 
 @Provider
-@Consumes({ API + RestconfService.XML })
+@Consumes({ Draft01.MediaTypes.DATA + RestconfService.XML, Draft02.MediaTypes.DATA + RestconfService.XML,
+        MediaType.APPLICATION_XML, MediaType.TEXT_XML })
 public enum XmlToCompositeNodeProvider implements MessageBodyReader<CompositeNode> {
     INSTANCE;
 
@@ -37,8 +39,7 @@ public enum XmlToCompositeNodeProvider implements MessageBodyReader<CompositeNod
         try {
             return xmlReader.read(entityStream);
         } catch (XMLStreamException | UnsupportedFormatException e) {
-            throw new WebApplicationException(Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage())
-                    .build());
+            throw new ResponseException(Response.Status.BAD_REQUEST, e.getMessage());
         }
     }
 
index eb1f6165ca23c5bb17deac73f575a06bfc57fc57..29ad7522c43436891ec6cb717ee6cbc713a04abd 100644 (file)
@@ -33,8 +33,7 @@ class BrokerFacade implements DataReader<InstanceIdentifier, CompositeNode> {
 
     private def void checkPreconditions() {
         if (context === null || dataService === null) {
-            throw new WebApplicationException(Response.status(Response.Status.SERVICE_UNAVAILABLE)
-                    .entity(RestconfProvider::NOT_INITALIZED_MSG).build())
+            throw new ResponseException(Response.Status.SERVICE_UNAVAILABLE, RestconfProvider::NOT_INITALIZED_MSG)
         }
     }
 
index c2b0ae8bdbb716580b1197108d0e91168b3d6ef0..065d01e8e9405058f563189e6f5117d30eed4857 100644 (file)
@@ -9,7 +9,6 @@ import java.util.HashMap
 import java.util.List
 import java.util.Map
 import java.util.concurrent.ConcurrentHashMap
-import javax.ws.rs.WebApplicationException
 import javax.ws.rs.core.Response
 import org.opendaylight.controller.sal.core.api.model.SchemaServiceListener
 import org.opendaylight.controller.sal.rest.impl.RestconfProvider
@@ -57,8 +56,7 @@ class ControllerContext implements SchemaServiceListener {
     
     private def void checkPreconditions() {
         if (schemas === null) {
-            throw new WebApplicationException(Response.status(Response.Status.SERVICE_UNAVAILABLE)
-                    .entity(RestconfProvider::NOT_INITALIZED_MSG).build())
+            throw new ResponseException(Response.Status.SERVICE_UNAVAILABLE, RestconfProvider::NOT_INITALIZED_MSG)
         }
     }
 
@@ -196,6 +194,9 @@ class ControllerContext implements SchemaServiceListener {
     private def DataSchemaNode collectPathArguments(InstanceIdentifierBuilder builder, List<String> strings,
         DataNodeContainer parentNode) {
         checkNotNull(strings)
+        if (parentNode === null) {
+            return null;
+        }
         if (strings.empty) {
             return parentNode as DataSchemaNode;
         }
diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/MediaTypes.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/MediaTypes.java
deleted file mode 100644 (file)
index af18828..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.restconf.impl;
-
-public class MediaTypes {
-    public static final String API = "application/vnd.yang.api";
-    public static final String DATASTORE = "application/vnd.yang.datastore";
-    public static final String DATA = "application/vnd.yang.data";
-    public static final String EVENT = "application/vnd.yang.event";
-    public static final String OPERATION = "application/vnd.yang.operation";
-    public static final String PATCH = "application/vnd.yang.patch";
-}
diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ResponseException.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ResponseException.java
new file mode 100644 (file)
index 0000000..e2edd5d
--- /dev/null
@@ -0,0 +1,15 @@
+package org.opendaylight.controller.sal.restconf.impl;
+
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+
+public class ResponseException extends WebApplicationException {
+
+    private static final long serialVersionUID = -5320114450593021655L;
+
+    public ResponseException(Status status, String msg) {
+        super(Response.status(status).type(MediaType.TEXT_PLAIN_TYPE).entity(msg).build());
+    }
+}
index a4587fa787fdff3af7b5dedab4b22505375fe37c..8f6ca1685bbb4b0c6f81ec2dc85ae4fd4c92d5f2 100644 (file)
@@ -119,8 +119,7 @@ class RestconfImpl implements RestconfService {
     private def InstanceIdWithSchemaNode resolveInstanceIdentifier(String identifier) {
         val identifierWithSchemaNode = identifier.toInstanceIdentifier
         if (identifierWithSchemaNode === null) {
-            throw new WebApplicationException(Response.status(Response.Status.BAD_REQUEST).entity("URI has bad format")
-                    .build());
+            throw new ResponseException(Response.Status.BAD_REQUEST, "URI has bad format");
         }
         return identifierWithSchemaNode
     }
index 12f33d4562526b25feef31e8dd9e7c6a9dfa352c..62a9ae05814b3a2d7a7d259c0811d484c580f99e 100644 (file)
@@ -1,13 +1,13 @@
 package org.opendaylight.controller.sal.restconf.impl;
 
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.*;
 
 public class StructuredData {
-    
+
     private final CompositeNode data;
     private final DataSchemaNode schema;
-    
+
     public StructuredData(CompositeNode data, DataSchemaNode schema) {
         this.data = data;
         this.schema = schema;
@@ -20,5 +20,4 @@ public class StructuredData {
     public DataSchemaNode getSchema() {
         return schema;
     }
-    
 }
index c43de5d9e8525091eb535703381cb222ac42b9ca..bc941b997e35dd63c8a3250cb52e8ccf66e27314 100644 (file)
@@ -13,9 +13,7 @@ import java.util.*;
 import java.util.concurrent.Future;
 
 import javax.ws.rs.WebApplicationException;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.*;
 import javax.xml.stream.XMLStreamException;
 import javax.xml.transform.*;
 import javax.xml.transform.dom.DOMSource;
@@ -24,8 +22,7 @@ import javax.xml.transform.stream.StreamResult;
 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
 import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider;
 import org.opendaylight.controller.sal.restconf.impl.*;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.*;
 import org.opendaylight.yangtools.yang.data.api.*;
 import org.opendaylight.yangtools.yang.data.impl.XmlTreeBuilder;
 import org.opendaylight.yangtools.yang.model.api.*;
@@ -99,7 +96,7 @@ final class TestUtils {
         }
         return (CompositeNode) dataTree;
     }
-    
+
     public static Document loadDocumentFrom(InputStream inputStream) {
         try {
             DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
@@ -135,6 +132,11 @@ final class TestUtils {
     }
 
     static String convertCompositeNodeDataAndYangToJson(CompositeNode compositeNode, String yangPath, String outputPath) {
+        return convertCompositeNodeDataAndYangToJson(compositeNode, yangPath, outputPath, null, null);
+    }
+
+    static String convertCompositeNodeDataAndYangToJson(CompositeNode compositeNode, String yangPath,
+            String outputPath, String searchedModuleName, String searchedDataSchemaName) {
         String jsonResult = null;
         Set<Module> modules = null;
 
@@ -145,30 +147,54 @@ final class TestUtils {
         }
         assertNotNull("modules can't be null.", modules);
 
+        Module module = null;
+        if (searchedModuleName != null) {
+            for (Module m : modules) {
+                if (m.getName().equals(searchedModuleName)) {
+                    module = m;
+                    break;
+                }
+            }
+        } else if (modules.size() == 1) {
+            module = modules.iterator().next();
+        }
+        assertNotNull("Module is missing", module);
+
         assertNotNull("Composite node can't be null", compositeNode);
 
         StructuredDataToJsonProvider structuredDataToJsonProvider = StructuredDataToJsonProvider.INSTANCE;
-        for (Module module : modules) {
-            ByteArrayOutputStream byteArrayOS = new ByteArrayOutputStream();
-            for (DataSchemaNode dataSchemaNode : module.getChildNodes()) {
-                StructuredData structuredData = new StructuredData(compositeNode, dataSchemaNode);
-                try {
-                    structuredDataToJsonProvider.writeTo(structuredData, null, null, null, null, null, byteArrayOS);
-                } catch (WebApplicationException | IOException e) {
-                    e.printStackTrace();
+        ByteArrayOutputStream byteArrayOS = new ByteArrayOutputStream();
+        DataSchemaNode dataSchemaNode = null;
+        if (searchedDataSchemaName != null) {
+            for (DataSchemaNode dsn : module.getChildNodes()) {
+                if (dsn.getQName().getLocalName().equals(searchedDataSchemaName)) {
+                    dataSchemaNode = dsn;
                 }
-                assertFalse(
-                        "Returning JSON string can't be empty for node " + dataSchemaNode.getQName().getLocalName(),
-                        byteArrayOS.toString().isEmpty());
-            }
-            jsonResult = byteArrayOS.toString();
-            try {
-                outputToFile(byteArrayOS, outputPath);
-            } catch (IOException e) {
-                System.out.println("Output file wasn't cloased sucessfuly.");
             }
+        } else if (module.getChildNodes().size() == 1) {
+            dataSchemaNode = module.getChildNodes().iterator().next();
+        }
+        assertNotNull(dataSchemaNode);
+        // SchemaContextUtil.
 
+        ControllerContext controllerContext = ControllerContext.getInstance();
+        controllerContext.setSchemas(loadSchemaContext(modules));
+        StructuredData structuredData = new StructuredData(compositeNode, dataSchemaNode);
+        try {
+            structuredDataToJsonProvider.writeTo(structuredData, null, null, null, null, null, byteArrayOS);
+        } catch (WebApplicationException | IOException e) {
+            e.printStackTrace();
         }
+        assertFalse("Returning JSON string can't be empty for node " + dataSchemaNode.getQName().getLocalName(),
+                byteArrayOS.toString().isEmpty());
+
+        jsonResult = byteArrayOS.toString();
+        try {
+            outputToFile(byteArrayOS, outputPath);
+        } catch (IOException e) {
+            System.out.println("Output file wasn't cloased sucessfuly.");
+        }
+
         return jsonResult;
     }
 
@@ -296,7 +322,8 @@ final class TestUtils {
         RpcResult<TransactionStatus> rpcResult = DummyRpcResult.builder().result(TransactionStatus.COMMITED).build();
         Future<RpcResult<TransactionStatus>> future = DummyFuture.builder().rpcResult(rpcResult).build();
         when(controllerContext.toInstanceIdentifier(any(String.class))).thenReturn(instIdAndSchema);
-        when(broker.commitConfigurationDataPut(any(InstanceIdentifier.class), any(CompositeNode.class))).thenReturn(future);
+        when(broker.commitConfigurationDataPut(any(InstanceIdentifier.class), any(CompositeNode.class))).thenReturn(
+                future);
 
         restconf.setControllerContext(controllerContext);
         restconf.setBroker(broker);
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ToJsonWithAugmentTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ToJsonWithAugmentTest.java
new file mode 100644 (file)
index 0000000..994916d
--- /dev/null
@@ -0,0 +1,27 @@
+package org.opendaylight.controller.sal.restconf.impl.test;
+
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+public class ToJsonWithAugmentTest {
+
+    /**
+     * Test of json output when as input are specified composite node with empty
+     * data + YANG file
+     */
+    @Test
+    public void augmentedElementsToJson() {
+        String jsonOutput = TestUtils.convertCompositeNodeDataAndYangToJson(
+                TestUtils.loadCompositeNode("/yang-to-json-conversion/augmentation/xml/data.xml"),
+                "/yang-to-json-conversion/augmentation", "/yang-to-json-conversion/augmentation/xml", "yang", "cont");
+
+        assertTrue(jsonOutput.contains("\"augment-leaf:lf2\": \"lf2\""));
+        assertTrue(jsonOutput.contains("\"augment-container:cont1\": {"));
+        assertTrue(jsonOutput.contains("\"augment-container:lf11\": \"lf11\""));
+        assertTrue(jsonOutput.contains("\"augment-list:lst1\": ["));
+        assertTrue(jsonOutput.contains("\"augment-list:lf11\": \"lf1_1\""));
+        assertTrue(jsonOutput.contains("\"augment-list:lf11\": \"lf1_2\""));
+        assertTrue(jsonOutput.contains("\"augment-leaflist:lflst1\": ["));
+    }
+}
index 015dfc8ad99b022c61cf3f705fb2adf9e13a5d9d..4336ac8a8325b14ab883834a7e9b91a0a6fb7655 100644 (file)
@@ -29,12 +29,12 @@ import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Test;
 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
+import org.opendaylight.controller.sal.rest.api.Draft01;
 import org.opendaylight.controller.sal.rest.api.RestconfService;
 import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider;
 import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
 import org.opendaylight.controller.sal.restconf.impl.BrokerFacade;
 import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
-import org.opendaylight.controller.sal.restconf.impl.MediaTypes;
 import org.opendaylight.controller.sal.restconf.impl.RestconfImpl;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
@@ -49,7 +49,8 @@ public class XmlProvidersTest extends JerseyTest {
     private static ControllerContext controllerContext;
     private static BrokerFacade brokerFacade;
     private static RestconfImpl restconfImpl;
-    private static final MediaType MEDIA_TYPE = new MediaType("application", "vnd.yang.api+xml");
+    private static final MediaType MEDIA_TYPE = new MediaType("application", "vnd.yang.data+xml");
+    private static final MediaType MEDIA_TYPE_DRAFT02 = new MediaType("application", "yang.data+xml");
 
     @BeforeClass
     public static void init() throws FileNotFoundException {
@@ -87,11 +88,11 @@ public class XmlProvidersTest extends JerseyTest {
     public void testBadFormatXmlToCompositeNodeProvider() throws UnsupportedEncodingException, URISyntaxException {
         String uri = createUri("/operations/", "ietf-interfaces:interfaces/interface/eth0");
         
-        Response response = target(uri).request(MediaTypes.API + RestconfService.XML).post(
+        Response response = target(uri).request(Draft01.MediaTypes.DATA + RestconfService.XML).post(
                 Entity.entity("<SimpleNode/>", MEDIA_TYPE));
         assertEquals(400, response.getStatus());
         
-        response = target(uri).request(MediaTypes.API + RestconfService.XML).post(
+        response = target(uri).request(Draft01.MediaTypes.DATA + RestconfService.XML).post(
                 Entity.entity("<SimpleNode>", MEDIA_TYPE));
         assertEquals(400, response.getStatus());
     }
@@ -102,7 +103,7 @@ public class XmlProvidersTest extends JerseyTest {
         
         when(brokerFacade.readOperationalData(any(InstanceIdentifier.class))).thenReturn(null);
         
-        Response response = target(uri).request(MediaTypes.API+RestconfService.XML).get();
+        Response response = target(uri).request(Draft01.MediaTypes.DATA+RestconfService.XML).get();
         assertEquals(404, response.getStatus());
     }
     
@@ -112,7 +113,7 @@ public class XmlProvidersTest extends JerseyTest {
         
         when(brokerFacade.readOperationalData(any(InstanceIdentifier.class))).thenReturn(null);
         
-        Response response = target(uri).request(MediaTypes.API+RestconfService.XML).get();
+        Response response = target(uri).request(Draft01.MediaTypes.DATA+RestconfService.XML).get();
         assertEquals(400, response.getStatus());
     }
     
@@ -120,51 +121,51 @@ public class XmlProvidersTest extends JerseyTest {
     public void testRpcResultCommitedToStatusCodes() throws UnsupportedEncodingException {
         InputStream xmlStream = RestconfImplTest.class.getResourceAsStream("/parts/ietf-interfaces_interfaces.xml");
         String xml = TestUtils.getDocumentInPrintableForm(TestUtils.loadDocumentFrom(xmlStream));
-        Entity<String> entity = Entity.entity(xml, MEDIA_TYPE);
+        Entity<String> entity = Entity.entity(xml, MEDIA_TYPE_DRAFT02);
         RpcResult<TransactionStatus> rpcResult = DummyRpcResult.builder().result(TransactionStatus.COMMITED).build();
         Future<RpcResult<TransactionStatus>> dummyFuture = DummyFuture.builder().rpcResult(rpcResult).build();
         when(brokerFacade.commitOperationalDataPut(any(InstanceIdentifier.class), any(CompositeNode.class))).thenReturn(dummyFuture);
         when(brokerFacade.commitConfigurationDataPut(any(InstanceIdentifier.class), any(CompositeNode.class))).thenReturn(dummyFuture);
         
         String uri = createUri("/config/", "ietf-interfaces:interfaces/interface/eth0");
-        Response response = target(uri).request(MEDIA_TYPE).put(entity);
-        assertEquals(200, response.getStatus());
-        response = target(uri).request(MEDIA_TYPE).post(entity);
+        Response response = target(uri).request(MEDIA_TYPE_DRAFT02).put(entity);
         assertEquals(204, response.getStatus());
+        response = target(uri).request(MEDIA_TYPE_DRAFT02).post(entity);
+        assertEquals(200, response.getStatus());
         
         uri = createUri("/operational/", "ietf-interfaces:interfaces/interface/eth0");
-        response = target(uri).request(MEDIA_TYPE).put(entity);
-        assertEquals(200, response.getStatus());
-        response = target(uri).request(MEDIA_TYPE).post(entity);
+        response = target(uri).request(MEDIA_TYPE_DRAFT02).put(entity);
         assertEquals(204, response.getStatus());
+        response = target(uri).request(MEDIA_TYPE_DRAFT02).post(entity);
+        assertEquals(200, response.getStatus());
         
         uri = createUri("/datastore/", "ietf-interfaces:interfaces/interface/eth0");
         response = target(uri).request(MEDIA_TYPE).put(entity);
-        assertEquals(200, response.getStatus());
-        response = target(uri).request(MEDIA_TYPE).post(entity);
         assertEquals(204, response.getStatus());
+        response = target(uri).request(MEDIA_TYPE).post(entity);
+        assertEquals(200, response.getStatus());
     }
     
     @Test
     public void testRpcResultOtherToStatusCodes() throws UnsupportedEncodingException {
         InputStream xmlStream = RestconfImplTest.class.getResourceAsStream("/parts/ietf-interfaces_interfaces.xml");
         String xml = TestUtils.getDocumentInPrintableForm(TestUtils.loadDocumentFrom(xmlStream));
-        Entity<String> entity = Entity.entity(xml, MEDIA_TYPE);
+        Entity<String> entity = Entity.entity(xml, MEDIA_TYPE_DRAFT02);
         RpcResult<TransactionStatus> rpcResult = DummyRpcResult.builder().result(TransactionStatus.FAILED).build();
         Future<RpcResult<TransactionStatus>> dummyFuture = DummyFuture.builder().rpcResult(rpcResult).build();
         when(brokerFacade.commitOperationalDataPut(any(InstanceIdentifier.class), any(CompositeNode.class))).thenReturn(dummyFuture);
         when(brokerFacade.commitConfigurationDataPut(any(InstanceIdentifier.class), any(CompositeNode.class))).thenReturn(dummyFuture);
         
         String uri = createUri("/config/", "ietf-interfaces:interfaces/interface/eth0");
-        Response response = target(uri).request(MEDIA_TYPE).put(entity);
+        Response response = target(uri).request(MEDIA_TYPE_DRAFT02).put(entity);
         assertEquals(500, response.getStatus());
-        response = target(uri).request(MEDIA_TYPE).post(entity);
+        response = target(uri).request(MEDIA_TYPE_DRAFT02).post(entity);
         assertEquals(500, response.getStatus());
         
         uri = createUri("/operational/", "ietf-interfaces:interfaces/interface/eth0");
-        response = target(uri).request(MEDIA_TYPE).put(entity);
+        response = target(uri).request(MEDIA_TYPE_DRAFT02).put(entity);
         assertEquals(500, response.getStatus());
-        response = target(uri).request(MEDIA_TYPE).post(entity);
+        response = target(uri).request(MEDIA_TYPE_DRAFT02).post(entity);
         assertEquals(500, response.getStatus());
         
         uri = createUri("/datastore/", "ietf-interfaces:interfaces/interface/eth0");
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/augment-container.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/augment-container.yang
new file mode 100644 (file)
index 0000000..7efe4f7
--- /dev/null
@@ -0,0 +1,22 @@
+module augment-container {
+  namespace "ns:augment:container";  
+  prefix "augcont";
+
+  
+  import yang {prefix yng; revision-date 2013-11-26;}  
+
+
+  revision "2013-11-26" {    
+  }
+  
+       augment "/yng:cont" {
+               container cont1 {
+                       leaf lf11 {
+                               type string;
+                       }
+               }
+       }
+       
+
+         
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/augment-leaf.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/augment-leaf.yang
new file mode 100644 (file)
index 0000000..248d3bb
--- /dev/null
@@ -0,0 +1,18 @@
+module augment-leaf {
+  namespace "ns:augment:leaf";  
+  prefix "auglf";
+
+  
+  import yang {prefix yng; revision-date 2013-11-26;}  
+
+
+  revision "2013-11-26" {    
+  }
+  
+       augment "/yng:cont" {
+               leaf lf2 {
+                       type string;
+               }
+       }
+       
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/augment-leaflist.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/augment-leaflist.yang
new file mode 100644 (file)
index 0000000..1f4b937
--- /dev/null
@@ -0,0 +1,20 @@
+module augment-leaflist {
+  namespace "ns:augment:leaflist";  
+  prefix "auglflst";
+
+  
+  import yang {prefix yng; revision-date 2013-11-26;}  
+
+
+  revision "2013-11-26" {    
+  }
+  
+       augment "/yng:cont" {
+               leaf-list lflst1 {
+                       type string;
+               }
+       }
+       
+
+         
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/augment-list.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/augment-list.yang
new file mode 100644 (file)
index 0000000..a35a87e
--- /dev/null
@@ -0,0 +1,22 @@
+module augment-list {
+  namespace "ns:augment:list";  
+  prefix "auglst";
+
+  
+  import yang {prefix yng; revision-date 2013-11-26;}  
+
+
+  revision "2013-11-26" {    
+  }
+  
+       augment "/yng:cont" {
+               list lst1 {
+                       leaf lf11 {
+                               type string;
+                       }
+               }
+       }
+       
+
+         
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/xml/data.xml b/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/xml/data.xml
new file mode 100644 (file)
index 0000000..08cdb34
--- /dev/null
@@ -0,0 +1,16 @@
+<cont>
+       <lf1>lf1</lf1>
+       <lf2>lf2</lf2>
+       <cont1>
+               <lf11>lf11</lf11>
+       </cont1>
+       <lst1>
+               <lf11>lf1_1</lf11>
+       </lst1>
+       <lst1>
+               <lf11>lf1_2</lf11>
+       </lst1>
+       <lflst1>lflst1_1</lflst1>
+       <lflst1>lflst1_2</lflst1>
+       <lflst1>lflst1_3</lflst1>
+</cont>
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/yang.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/yang.yang
new file mode 100644 (file)
index 0000000..aeb9737
--- /dev/null
@@ -0,0 +1,17 @@
+module yang {
+  namespace "ns:yang";  
+
+  prefix "yng";
+  revision 2013-11-26 {    
+  }
+  
+       container cont {
+               leaf lf1 {
+                       type string;
+               }
+               
+       }
+       
+
+         
+}
\ No newline at end of file
index 7cbd2314b60265e04626ba4d2409a4f2912be559..521de7e394ee69fd3d5dfdda4bf8f546a1b513c0 100644 (file)
@@ -28,6 +28,7 @@ public class StatisticsManagerActivator extends AbstractBindingAwareProvider {
     @Override
     public void onSessionInitiated(ProviderContext session) {
         
+        pSession = session;
         DataProviderService dps = session.<DataProviderService>getSALService(DataProviderService.class);
         StatisticsManagerActivator.statsProvider.setDataService(dps);
         NotificationProviderService nps = session.<NotificationProviderService>getSALService(NotificationProviderService.class);
index 5218d051fa2cdb40ec9fa47f58114abf5c334dc6..d1ab3515035dfb0b5597c263c5f23ac29656d659 100644 (file)
@@ -100,8 +100,6 @@ public class StatisticsProvider implements AutoCloseable {
             public void run() {
                 while(true){
                     try {
-                        spLogger.info("Statistics requester thread started with timer interval : {}",5000);
-                        
                         statsRequestSender();
                         
                         Thread.sleep(5000);
@@ -111,6 +109,11 @@ public class StatisticsProvider implements AutoCloseable {
                 }
             }
         });
+        
+        spLogger.debug("Statistics requester thread started with timer interval : {}",5000);
+        
+        statisticsRequesterThread.start();
+        
         spLogger.info("Statistics Provider started.");
     }
     
@@ -124,6 +127,9 @@ public class StatisticsProvider implements AutoCloseable {
         
         //Need to call API to receive all the nodes connected to controller.
         List<Node> targetNodes = getAllConnectedNodes();
+        
+        if(targetNodes == null)
+            return;
 
         for (Node targetNode : targetNodes){
             spLogger.info("Send request for stats collection to node : {})",targetNode.getId());
@@ -212,6 +218,9 @@ public class StatisticsProvider implements AutoCloseable {
     private List<Node> getAllConnectedNodes(){
         
         Nodes nodes = (Nodes) dps.readOperationalData(nodesIdentifier);
+        if(nodes == null)
+            return null;
+        
         spLogger.info("Number of connected nodes : {}",nodes.getNode().size());
         return nodes.getNode();
     }
index 23ba8aaea41e5866fc1934290bfd17f6154aadd9..41ae52b3bf0ff5da3cfb3adcffb6ccfbeb4ac491 100644 (file)
@@ -21,7 +21,6 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
 import org.opendaylight.controller.sal.connect.netconf.InventoryUtils;
-import org.opendaylight.controller.sal.connect.netconf.NetconfDeviceManager;
 import org.opendaylight.controller.sal.connect.netconf.NetconfInventoryUtils;
 import org.opendaylight.controller.sal.core.api.data.DataBrokerService;
 import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance;
@@ -61,9 +60,6 @@ public class ServiceProviderController {
     @Inject
     DataBrokerService dataBroker;
 
-    @Inject
-    NetconfDeviceManager netconfManager;
-
     @Test
     public void properInitialized() throws Exception {
 
@@ -72,8 +68,6 @@ public class ServiceProviderController {
         InstanceIdentifier path = InstanceIdentifier.builder(InventoryUtils.INVENTORY_PATH)
                 .nodeWithKey(InventoryUtils.INVENTORY_NODE, InventoryUtils.INVENTORY_ID, "foo").toInstance();
 
-        netconfManager.netconfNodeAdded(path, new InetSocketAddress("127.0.0.1", 8383));
-
         
         InstanceIdentifier mountPointPath = path;