Merge "Bug 2597: Batch modification operations in TransactionProxy"
authorMoiz Raja <moraja@cisco.com>
Wed, 25 Feb 2015 00:52:17 +0000 (00:52 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Wed, 25 Feb 2015 00:52:17 +0000 (00:52 +0000)
98 files changed:
features/restconf/src/main/resources/features.xml
opendaylight/adsal/features/nsf/src/main/resources/features.xml
opendaylight/archetypes/opendaylight-startup/src/main/resources/archetype-resources/features/pom.xml
opendaylight/archetypes/opendaylight-startup/src/main/resources/archetype-resources/features/src/main/features/features.xml
opendaylight/archetypes/opendaylight-startup/src/main/resources/archetype-resources/impl/src/main/java/__packageInPathFormat__/impl/__classPrefix__Provider.java [moved from opendaylight/archetypes/opendaylight-startup/src/main/resources/archetype-resources/impl/src/main/java/__packageInPathFormat__/__classPrefix__Provider.java with 97% similarity]
opendaylight/archetypes/opendaylight-startup/src/main/resources/archetype-resources/impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/__artifactId__/impl/rev141210/__classPrefix__Module.java
opendaylight/archetypes/opendaylight-startup/src/main/resources/archetype-resources/impl/src/test/java/__packageInPathFormat__/impl/__classPrefix__ProviderTest.java [moved from opendaylight/archetypes/opendaylight-startup/src/main/resources/archetype-resources/impl/src/test/java/__packageInPathFormat__/__classPrefix__ProviderTest.java with 97% similarity]
opendaylight/archetypes/opendaylight-startup/src/main/resources/archetype-resources/impl/src/test/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/__artifactId__/impl/rev141210/__classPrefix__ModuleTest.java
opendaylight/archetypes/opendaylight-startup/src/main/resources/archetype-resources/karaf/pom.xml
opendaylight/archetypes/opendaylight-startup/src/main/resources/archetype-resources/pom.xml
opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/ConfigRegistry.java
opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/LookupRegistry.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionControllerImpl.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionLookupRegistry.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ServiceReferenceRegistryImpl.java
opendaylight/config/config-util/src/main/java/org/opendaylight/controller/config/util/BeanReader.java [new file with mode: 0644]
opendaylight/config/config-util/src/main/java/org/opendaylight/controller/config/util/ConfigRegistryClient.java
opendaylight/config/config-util/src/main/java/org/opendaylight/controller/config/util/ConfigRegistryJMXClient.java
opendaylight/config/config-util/src/main/java/org/opendaylight/controller/config/util/ConfigTransactionClient.java
opendaylight/config/config-util/src/main/java/org/opendaylight/controller/config/util/ConfigTransactionJMXClient.java
opendaylight/config/config-util/src/test/java/org/opendaylight/controller/config/util/TestingConfigTransactionController.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/ConcurrentDOMDataBroker.java
opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/md/sal/dom/api/DOMDataTreeIdentifier.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/AbstractDOMForwardedTransactionFactory.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/CommitCoordinationTask.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/DOMDataBrokerTransactionChainImpl.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/PingPongTransactionChain.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/SerializedDOMDataBroker.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/ShardRegistration.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/ShardedDOMDataTree.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/ShardedDOMDataTreeProducer.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/ShardedDOMDataWriteTransaction.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/ShardingTableEntry.java [new file with mode: 0644]
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/listener/NetconfDeviceCommunicator.java
opendaylight/md-sal/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/listener/NetconfDeviceCommunicatorTest.java
opendaylight/md-sal/sal-rest-connector/pom.xml
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/md/sal/rest/common/RestconfValidationUtils.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/md/sal/rest/schema/SchemaExportContentYangBodyWriter.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/md/sal/rest/schema/SchemaExportContentYinBodyWriter.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/md/sal/rest/schema/SchemaExportContext.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/md/sal/rest/schema/SchemaRetrievalService.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/md/sal/rest/schema/SchemaRetrievalServiceImpl.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/gson/JsonParser.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/JsonToCompositeNodeReader.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/RestconfApplication.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/RestconfCompositeWrapper.java [new file with mode: 0644]
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/rest/impl/XmlToCompositeNodeReader.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/CompositeNodeWrapper.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/EmptyNodeWrapper.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/NodeWrapper.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/SimpleNodeWrapper.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/StructuredData.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfig.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/Datastore.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/DiscardChanges.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfig.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/get/Get.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/getconfig/GetConfig.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/getconfig/RunningDatastoreQueryStrategy.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationProvider.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/transactions/TransactionProvider.java
opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java
opendaylight/networkconfiguration/neutron/northbound/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/INeutronRequest.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronFirewallAware.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronFirewallCRUD.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronFirewallPolicyAware.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronFirewallPolicyCRUD.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronFirewallRuleAware.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronFirewallRuleCRUD.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronFloatingIPAware.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronFloatingIPCRUD.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronLoadBalancerAware.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronLoadBalancerCRUD.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronLoadBalancerHealthMonitorAware.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronLoadBalancerHealthMonitorCRUD.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronLoadBalancerListenerAware.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronLoadBalancerListenerCRUD.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronLoadBalancerPoolAware.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronLoadBalancerPoolCRUD.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronLoadBalancerPoolMemberAware.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronLoadBalancerPoolMemberCRUD.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronNetworkAware.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronNetworkCRUD.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronObject.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronPortAware.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronPortCRUD.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronRouterAware.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronRouterCRUD.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronSecurityGroupAware.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronSecurityGroupCRUD.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronSecurityRuleAware.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronSecurityRuleCRUD.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronSubnetAware.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronSubnetCRUD.java

index 123b00767ef6a178fc4895970ce9a9071998af45..8060206b53753c435d39d666b5832f34040be280 100644 (file)
@@ -97,6 +97,7 @@
         <bundle>mvn:org.opendaylight.controller/sal-rest-connector/${project.version}</bundle>
         <bundle>mvn:com.google.code.gson/gson/${gson.version}</bundle>
         <bundle>mvn:org.opendaylight.yangtools/yang-data-codec-gson/${yangtools.version}</bundle>
+        <bundle>mvn:org.opendaylight.yangtools/yang-model-export/${yangtools.version}</bundle>
         <bundle>mvn:com.sun.jersey/jersey-core/${jersey.version}</bundle>
         <bundle>mvn:com.sun.jersey/jersey-server/${jersey.version}</bundle>
         <bundle>mvn:com.sun.jersey/jersey-servlet/${jersey.version}</bundle>
index e8f7bc1e5c8b9522c16d8851ae26393bc4af2225..692faa746e1fdfcc766032697584cefe4ac3808e 100644 (file)
         -->
     </feature>
 
+    <feature name="odl-nsf-service" description="OpenDaylight :: NSF :: Network Service Functions in Controller" version="${project.version}">
+        <feature version="${sal.version}">odl-adsal-all</feature>
+        <feature version="${project.version}">odl-nsf-controller-managers</feature>
+        <feature version="${project.version}">odl-adsal-controller-northbound</feature>
+    </feature>
+
     <feature name="odl-nsf-managers" description="OpenDaylight :: AD-SAL :: Network Service Functions" version="${project.version}">
         <feature version="${commons.opendaylight.version}">odl-base-all</feature>
         <feature version="${sal.version}">odl-adsal-all</feature>
         <bundle>mvn:org.opendaylight.controller/routing.dijkstra_implementation/${routing.dijkstra_implementation.version}</bundle>
     </feature>
 
+    <feature name="odl-nsf-controller-managers" description="OpenDaylight :: AD-SAL :: Network Service Functions in Controller" version="${project.version}">
+        <feature version="${commons.opendaylight.version}">odl-base-all</feature>
+        <feature version="${sal.version}">odl-adsal-all</feature>
+        <bundle>mvn:org.opendaylight.controller/usermanager/${usermanager.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller/usermanager.implementation/${usermanager.version}</bundle>
+
+        <bundle>mvn:org.opendaylight.controller/appauth/${appauth.version}</bundle>
+
+        <bundle>mvn:org.opendaylight.controller/connectionmanager/${connectionmanager.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller/connectionmanager.implementation/${connectionmanager.version}</bundle>
+
+        <bundle>mvn:org.opendaylight.controller/containermanager/${containermanager.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller/containermanager.implementation/${containermanager.version}</bundle>
+
+        <bundle>mvn:org.opendaylight.controller/statisticsmanager/${statisticsmanager.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller/statisticsmanager.implementation/${statisticsmanager.implementation.version}</bundle>
+
+        <bundle>mvn:org.opendaylight.controller/switchmanager/${switchmanager.api.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller/switchmanager.implementation/${switchmanager.implementation.version}</bundle>
+
+        <bundle>mvn:org.opendaylight.controller/forwardingrulesmanager/${forwardingrulesmanager.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller/forwardingrulesmanager.implementation/${forwardingrulesmanager.implementation.version}</bundle>
+
+        <bundle>mvn:org.opendaylight.controller/topologymanager/${topologymanager.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller/topologymanager.shell/${topologymanager.shell.version}</bundle>
+
+        <bundle>mvn:org.opendaylight.controller/hosttracker/${hosttracker.api.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller/hosttracker.implementation/${hosttracker.implementation.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller/hosttracker.shell/${hosttracker.shell.version}</bundle>
+
+        <bundle>mvn:org.opendaylight.controller/forwarding.staticrouting/${forwarding.staticrouting}</bundle>
+
+        <bundle>mvn:org.opendaylight.controller.thirdparty/net.sf.jung2/2.0.1</bundle>
+        <bundle>mvn:org.opendaylight.controller/routing.dijkstra_implementation/${routing.dijkstra_implementation.version}</bundle>
+    </feature>
+
     <feature name="odl-adsal-northbound" description="OpenDaylight :: AD-SAL :: Northbound APIs" version="${project.version}">
         <feature version="${commons.opendaylight.version}">odl-base-all</feature>
         <feature version="${project.version}">odl-nsf-managers</feature>
         <bundle>mvn:org.opendaylight.controller/topology.northbound/${topology.northbound.version}</bundle>
         <bundle>mvn:org.opendaylight.controller/usermanager.northbound/${usermanager.northbound.version}</bundle>
     </feature>
+
+    <feature name="odl-adsal-controller-northbound" description="OpenDaylight :: AD-SAL :: Northbound APIs in Controller" version="${project.version}">
+        <feature version="${commons.opendaylight.version}">odl-base-all</feature>
+        <feature version="${project.version}">odl-nsf-managers</feature>
+        <bundle>mvn:org.ow2.asm/asm-all/${asm.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller/bundlescanner/${bundlescanner.api.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller/bundlescanner.implementation/${bundlescanner.implementation.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller/commons.northbound/${northbound.commons.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller/connectionmanager.northbound/${connectionmanager.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller/flowprogrammer.northbound/${flowprogrammer.northbound.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller/hosttracker.northbound/${hosttracker.northbound.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller/networkconfig.bridgedomain.northbound/${networkconfig.bridgedomain.northbound.version}</bundle>
+        <bundle>mvn:org.eclipse.persistence/org.eclipse.persistence.antlr/${eclipse.persistence.version}</bundle>
+        <bundle>mvn:org.eclipse.persistence/org.eclipse.persistence.core/${eclipse.persistence.version}</bundle>
+        <bundle>mvn:org.eclipse.persistence/org.eclipse.persistence.moxy/${eclipse.persistence.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller/forwarding.staticrouting.northbound/${forwarding.staticrouting.northbound.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller/statistics.northbound/${statistics.northbound.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller/subnets.northbound/${subnets.northbound.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller/switchmanager.northbound/${switchmanager.northbound.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller/topology.northbound/${topology.northbound.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller/usermanager.northbound/${usermanager.northbound.version}</bundle>
+    </feature>
 </features>
index 49b43f442edba2810196bf470a146df77ba83a71..c5adb28db745ce6c676f21ccf3f10c4edd43f933 100644 (file)
@@ -26,6 +26,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
   <properties>
     <mdsal.version>1.2.0-SNAPSHOT</mdsal.version>
     <yangtools.version>0.7.0-SNAPSHOT</yangtools.version>
+    <configfile.directory>etc/opendaylight/karaf</configfile.directory>
   </properties>
   <dependencyManagement>
     <dependencies>
index bbeb2de90ea5dc8dfc86ca44fecbc4d7330fefde..1facf4c8aac0aa727c90c165706aa3438ec274f8 100644 (file)
@@ -16,22 +16,22 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
   <repository>mvn:org.opendaylight.yangtools/features-yangtools/${symbol_dollar}{yangtools.version}/xml/features</repository>
   <repository>mvn:org.opendaylight.controller/features-mdsal/${symbol_dollar}{mdsal.version}/xml/features</repository>
   <repository>mvn:org.opendaylight.controller/features-restconf/${symbol_dollar}{mdsal.version}/xml/features</repository>
-  <feature name='odl-${artifactId}-api' version='${symbol_dollar}{project.version}' description='OpenDaylight :: ${artifactId} :: api '>
+  <feature name='odl-${artifactId}-api' version='${symbol_dollar}{project.version}' description='OpenDaylight :: ${artifactId} :: api'>
     <feature version='${symbol_dollar}{yangtools.version}'>odl-yangtools-models</feature>
     <bundle>mvn:${groupId}/${artifactId}-api/${symbol_dollar}{project.version}</bundle>
   </feature>
-  <feature name='odl-${artifactId}-impl' version='${symbol_dollar}{project.version}' description='OpenDaylight :: ${artifactId} :: impl '>
+  <feature name='odl-${artifactId}' version='${symbol_dollar}{project.version}' description='OpenDaylight :: ${artifactId}'>
     <feature version='${symbol_dollar}{mdsal.version}'>odl-mdsal-broker</feature>
     <feature version='${symbol_dollar}{project.version}'>odl-${artifactId}-api</feature>
     <bundle>mvn:${groupId}/${artifactId}-impl/${symbol_dollar}{project.version}</bundle>
-    <configfile finalname="${artifactId}-impl-default-config.xml">mvn:${groupId}/${artifactId}-impl/${symbol_dollar}{project.version}/xml/config</configfile>
+    <configfile finalname="${configfile.directory}/${artifactId}.xml">mvn:${groupId}/${artifactId}-impl/${symbol_dollar}{project.version}/xml/config</configfile>
   </feature>
-  <feature name='odl-${artifactId}-impl-rest' version='${symbol_dollar}{project.version}' description='OpenDaylight :: ${artifactId} :: impl :: REST '>
-    <feature version="${symbol_dollar}{project.version}">odl-${artifactId}-impl</feature>
+  <feature name='odl-${artifactId}-rest' version='${symbol_dollar}{project.version}' description='OpenDaylight :: ${artifactId} :: REST'>
+    <feature version="${symbol_dollar}{project.version}">odl-${artifactId}</feature>
     <feature version="${symbol_dollar}{mdsal.version}">odl-restconf</feature>
   </feature>
-  <feature name='odl-${artifactId}-impl-ui' version='${symbol_dollar}{project.version}' description='OpenDaylight :: ${artifactId} :: impl :: UI'>
-    <feature version="${symbol_dollar}{project.version}">odl-${artifactId}-impl-rest</feature>
+  <feature name='odl-${artifactId}-ui' version='${symbol_dollar}{project.version}' description='OpenDaylight :: ${artifactId} :: UI'>
+    <feature version="${symbol_dollar}{project.version}">odl-${artifactId}-rest</feature>
     <feature version="${symbol_dollar}{mdsal.version}">odl-mdsal-apidocs</feature>
     <feature version="${symbol_dollar}{mdsal.version}">odl-mdsal-xsql</feature>
   </feature>
@@ -8,7 +8,7 @@
  * 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 ${package};
+package ${package}.impl;
 
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
 import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
index 3290e85469f150088d3d3cccb0d571dd3240172c..3cf83415d72b689482432dca381f0e737b7b728e 100644 (file)
@@ -10,7 +10,7 @@
  */
 package org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.${artifactId}.impl.rev141210;
 
-import ${package}.${classPrefix}Provider;
+import ${package}.impl.${classPrefix}Provider;
 
 public class ${classPrefix}Module extends org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.${artifactId}.impl.rev141210.Abstract${classPrefix}Module {
     public ${classPrefix}Module(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
index 87b955c6b95c73233a4a475445b23f8dd74cbccb..486e3d39ba4ea58e610607517d61a9599272d707 100644 (file)
@@ -24,7 +24,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
     <maven>3.1.1</maven>
   </prerequisites>
   <properties>
-    <karaf.localFeature>odl-${artifactId}-impl-ui</karaf.localFeature>
+    <karaf.localFeature>odl-${artifactId}-ui</karaf.localFeature>
   </properties>
   <dependencyManagement>
     <dependencies>
@@ -54,4 +54,23 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
       <scope>runtime</scope>
     </dependency>
   </dependencies>
+  <!-- DO NOT install or deploy the karaf artifact -->
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-deploy-plugin</artifactId>
+        <configuration>
+          <skip>true</skip>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-install-plugin</artifactId>
+        <configuration>
+          <skip>true</skip>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
 </project>
index 067d4db4e90cd26fd7295af0a28122c9cbea5958..616704ada025601d9c0b069e6de3448bcea78bdf 100644 (file)
@@ -41,4 +41,11 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
       </plugin>
     </plugins>
   </build>
+
+  <scm>
+    <connection>scm:git:ssh://git.opendaylight.org:29418/${artifactId}.git</connection>
+    <developerConnection>scm:git:ssh://git.opendaylight.org:29418/${artifactId}.git</developerConnection>
+    <tag>HEAD</tag>
+    <url>https://wiki.opendaylight.org/view/${artifactId}:Main</url>
+  </scm>
 </project>
index 5c9ed8767c38986587052ea5d588e3b079338979..3d72114dafbcd56d97f0d718d594c2b861dea99a 100644 (file)
@@ -66,23 +66,4 @@ public interface ConfigRegistry extends LookupRegistry, ServiceReferenceReadable
     Set<String> getAvailableModuleNames();
 
 
-
-    /**
-     * Find all runtime beans
-     *
-     * @return objectNames
-     */
-    Set<ObjectName> lookupRuntimeBeans();
-
-    /**
-     * Find all runtime of specified module
-     *
-     * @param moduleName
-     *            of bean
-     * @param instanceName
-     *            of bean
-     * @return objectNames
-     */
-    Set<ObjectName> lookupRuntimeBeans(String moduleName, String instanceName);
-
 }
index b90fc9c034753f467cd41a927c8afa3dbdf493a3..5d615c20845099d260cf5f2d0dddf5e6aad3d7bf 100644 (file)
@@ -71,4 +71,21 @@ public interface LookupRegistry {
      */
     Set<String> getAvailableModuleFactoryQNames();
 
+    /**
+     * Find all runtime beans
+     *
+     * @return objectNames
+     */
+    Set<ObjectName> lookupRuntimeBeans();
+
+    /**
+     * Find all runtime of specified module
+     *
+     * @param moduleName
+     *            of bean
+     * @param instanceName
+     *            of bean
+     * @return objectNames
+     */
+    Set<ObjectName> lookupRuntimeBeans(String moduleName, String instanceName);
 }
index 37c2e2d777d83004b43e9dbd32cb3e9793c61f36..186a7218bae75a8cf7c724b817f95b8f9d41be90 100644 (file)
@@ -482,6 +482,25 @@ class ConfigTransactionControllerImpl implements
     public void checkConfigBeanExists(ObjectName objectName) throws InstanceNotFoundException {
         txLookupRegistry.checkConfigBeanExists(objectName);
     }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Set<ObjectName> lookupRuntimeBeans() {
+        return txLookupRegistry.lookupRuntimeBeans();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Set<ObjectName> lookupRuntimeBeans(String moduleName,
+                                              String instanceName) {
+        return txLookupRegistry.lookupRuntimeBeans(moduleName, instanceName);
+    }
+
     // --
 
     /**
index f9a3801171a0064a2c43b28f297e66adfabf7498..a0138b2d9d8c270c2da2cdf1978874409c8e20c1 100644 (file)
@@ -116,6 +116,26 @@ class ConfigTransactionLookupRegistry  implements LookupRegistry, Closeable {
         return ModuleQNameUtil.getQNames(allCurrentFactories);
     }
 
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Set<ObjectName> lookupRuntimeBeans() {
+        return lookupRuntimeBeans("*", "*");
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Set<ObjectName> lookupRuntimeBeans(String moduleName,
+                                              String instanceName) {
+        String finalModuleName = moduleName == null ? "*" : moduleName;
+        String finalInstanceName = instanceName == null ? "*" : instanceName;
+        ObjectName namePattern = ObjectNameUtil.createRuntimeBeanPattern(
+                finalModuleName, finalInstanceName);
+        return transactionJMXRegistrator.queryNames(namePattern, null);
+    }
 
     @Override
     public String toString() {
index 27f0d5c1f287b60ab49eb679b8657a1f5b56c746..dd6c2b94222b67b6b0d04310993e83b435bdd436 100644 (file)
@@ -97,6 +97,16 @@ public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceRe
                 throw new UnsupportedOperationException();
             }
 
+            @Override
+            public Set<ObjectName> lookupRuntimeBeans() {
+                throw new UnsupportedOperationException();
+            }
+
+            @Override
+            public Set<ObjectName> lookupRuntimeBeans(final String moduleName, final String instanceName) {
+                throw new UnsupportedOperationException();
+            }
+
             @Override
             public String toString() {
                 return "initial";
diff --git a/opendaylight/config/config-util/src/main/java/org/opendaylight/controller/config/util/BeanReader.java b/opendaylight/config/config-util/src/main/java/org/opendaylight/controller/config/util/BeanReader.java
new file mode 100644 (file)
index 0000000..de9baa6
--- /dev/null
@@ -0,0 +1,10 @@
+package org.opendaylight.controller.config.util;
+
+import javax.management.ObjectName;
+
+/**
+ * Created by mmarsale on 20.2.2015.
+ */
+public interface BeanReader {
+    Object getAttributeCurrentValue(ObjectName on, String attributeName);
+}
index 99d46cb638c3255d59532f4018176720b51bd85b..d384ae55c00bda72566ca2742304d7419f787a1d 100644 (file)
@@ -10,7 +10,7 @@ package org.opendaylight.controller.config.util;
 import javax.management.ObjectName;
 import org.opendaylight.controller.config.api.jmx.ConfigRegistryMXBean;
 
-public interface ConfigRegistryClient extends ConfigRegistryMXBean {
+public interface ConfigRegistryClient extends ConfigRegistryMXBean, BeanReader {
 
     ConfigTransactionClient createTransaction();
 
@@ -23,6 +23,4 @@ public interface ConfigRegistryClient extends ConfigRegistryMXBean {
     Object invokeMethod(ObjectName on, String name, Object[] params,
             String[] signature);
 
-    Object getAttributeCurrentValue(ObjectName on, String attributeName);
-
 }
index 099d010642ee510052a43ade62b77e2e20f2a884..a39111afee11168fe2250e84388e56d84f52b8be 100644 (file)
@@ -211,7 +211,7 @@ public class ConfigRegistryJMXClient implements ConfigRegistryClient {
         } catch (AttributeNotFoundException | InstanceNotFoundException
                 | MBeanException | ReflectionException e) {
             throw new RuntimeException("Unable to get attribute "
-                    + attributeName + " for " + on, e);
+                    + attributeName + " for " + on + ". Available beans: " + lookupConfigBeans(), e);
         }
     }
 
index 359035d51dd57aebc9762ba27d5e272eeb80ceea..c7c072d39d8233e84d6f93ebd585f759114a833b 100644 (file)
@@ -16,7 +16,7 @@ import org.opendaylight.controller.config.api.jmx.CommitStatus;
 import org.opendaylight.controller.config.api.jmx.ConfigTransactionControllerMXBean;
 
 public interface ConfigTransactionClient extends
-        ConfigTransactionControllerMXBean {
+        ConfigTransactionControllerMXBean, BeanReader {
 
     CommitStatus commit() throws ConflictingVersionException,
             ValidationException;
@@ -47,7 +47,7 @@ public interface ConfigTransactionClient extends
      * @param on - ObjectName of the Object from which the attribute should be read
      * @param jmxName - name of the attribute to be read
      *
-     * @return Attribute of Object on with attribute name jmxName
+     * @return Object of Object on with attribute name jmxName
      */
     Attribute getAttribute(ObjectName on, String jmxName);
 }
index a0af19796ebedfa5bedc809a5ce18f3b23d5858e..26ca1391ad4bf32eea9708e2db47f21cc33bdcfa 100644 (file)
@@ -240,6 +240,26 @@ public class ConfigTransactionJMXClient implements ConfigTransactionClient {
         configTransactionControllerMXBeanProxy.checkServiceReferenceExists(objectName);
     }
 
+    @Override
+    public Attribute getAttribute(ObjectName on, String attrName) {
+        if (ObjectNameUtil.getTransactionName(on) == null) {
+            throw new IllegalArgumentException("Not in transaction instance "
+                    + on + ", no transaction name present");
+        }
+
+        try {
+            return new Attribute(attrName, configMBeanServer.getAttribute(on,attrName));
+        } catch (JMException e) {
+            throw new IllegalStateException("Unable to get attribute "
+                    + attrName + " for " + on, e);
+        }
+    }
+
+    @Override
+    public Object getAttributeCurrentValue(ObjectName on, String attrName) {
+        return getAttribute(on, attrName).getValue();
+    }
+
     @Override
     public void validateBean(ObjectName configBeanON)
             throws ValidationException {
@@ -273,22 +293,17 @@ public class ConfigTransactionJMXClient implements ConfigTransactionClient {
     }
 
     @Override
-    public Attribute getAttribute(ObjectName on, String attrName) {
-        if (ObjectNameUtil.getTransactionName(on) == null) {
-            throw new IllegalArgumentException("Not in transaction instance "
-                    + on + ", no transaction name present");
-        }
+    public Set<String> getAvailableModuleFactoryQNames() {
+        return configTransactionControllerMXBeanProxy.getAvailableModuleFactoryQNames();
+    }
 
-        try {
-            return new Attribute(attrName, configMBeanServer.getAttribute(on,attrName));
-        } catch (JMException e) {
-            throw new IllegalStateException("Unable to get attribute "
-                    + attrName + " for " + on, e);
-        }
+    @Override
+    public Set<ObjectName> lookupRuntimeBeans() {
+        return configTransactionControllerMXBeanProxy.lookupRuntimeBeans();
     }
 
     @Override
-    public Set<String> getAvailableModuleFactoryQNames() {
-        return configTransactionControllerMXBeanProxy.getAvailableModuleFactoryQNames();
+    public Set<ObjectName> lookupRuntimeBeans(final String moduleName, final String instanceName) {
+        return configTransactionControllerMXBeanProxy.lookupRuntimeBeans(moduleName, instanceName);
     }
 }
index e1138addc74bd9a6d2072b80d93fe98263a46ffc..e69019405dec6e1be983c153eeab7efbe126d2da 100644 (file)
@@ -8,6 +8,7 @@
 package org.opendaylight.controller.config.util;
 
 import com.google.common.collect.Sets;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Set;
@@ -184,6 +185,16 @@ public class TestingConfigTransactionController implements
         return Sets.newHashSet("availableModuleFactoryQNames");
     }
 
+    @Override
+    public Set<ObjectName> lookupRuntimeBeans() {
+        return Collections.emptySet();
+    }
+
+    @Override
+    public Set<ObjectName> lookupRuntimeBeans(final String moduleName, final String instanceName) {
+        return Collections.emptySet();
+    }
+
     @Override
     public ObjectName getServiceReference(String serviceInterfaceQName, String refName) throws InstanceNotFoundException {
         return conf3;
index 13334c927236cdbeba31bf82ee10fb4f7d0cc952..886c4730678208fdbf129be10463eddf252f5c0f 100644 (file)
@@ -8,13 +8,13 @@
 package org.opendaylight.controller.cluster.datastore;
 
 import com.google.common.base.Preconditions;
-import com.google.common.collect.Iterables;
 import com.google.common.util.concurrent.AbstractFuture;
 import com.google.common.util.concurrent.AbstractListeningExecutorService;
 import com.google.common.util.concurrent.CheckedFuture;
 import com.google.common.util.concurrent.FutureCallback;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
+import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.Executor;
@@ -70,17 +70,16 @@ public class ConcurrentDOMDataBroker extends AbstractDOMDataBroker {
 
     @Override
     public CheckedFuture<Void, TransactionCommitFailedException> submit(DOMDataWriteTransaction transaction,
-            Iterable<DOMStoreThreePhaseCommitCohort> cohorts) {
+            Collection<DOMStoreThreePhaseCommitCohort> cohorts) {
 
         Preconditions.checkArgument(transaction != null, "Transaction must not be null.");
         Preconditions.checkArgument(cohorts != null, "Cohorts must not be null.");
         LOG.debug("Tx: {} is submitted for execution.", transaction.getIdentifier());
 
-        final int cohortSize = Iterables.size(cohorts);
         final AsyncNotifyingSettableFuture clientSubmitFuture =
                 new AsyncNotifyingSettableFuture(clientFutureCallbackExecutor);
 
-        doCanCommit(clientSubmitFuture, transaction, cohorts, cohortSize);
+        doCanCommit(clientSubmitFuture, transaction, cohorts);
 
         return MappingCheckedFuture.create(clientSubmitFuture,
                 TransactionCommitFailedExceptionMapper.COMMIT_ERROR_MAPPER);
@@ -88,31 +87,31 @@ public class ConcurrentDOMDataBroker extends AbstractDOMDataBroker {
 
     private void doCanCommit(final AsyncNotifyingSettableFuture clientSubmitFuture,
             final DOMDataWriteTransaction transaction,
-            final Iterable<DOMStoreThreePhaseCommitCohort> cohorts, final int cohortSize) {
+            final Collection<DOMStoreThreePhaseCommitCohort> cohorts) {
 
         final long startTime = System.nanoTime();
 
         // Not using Futures.allAsList here to avoid its internal overhead.
-        final AtomicInteger remaining = new AtomicInteger(cohortSize);
+        final AtomicInteger remaining = new AtomicInteger(cohorts.size());
         FutureCallback<Boolean> futureCallback = new FutureCallback<Boolean>() {
             @Override
             public void onSuccess(Boolean result) {
                 if (result == null || !result) {
-                    handleException(clientSubmitFuture, transaction, cohorts, cohortSize,
+                    handleException(clientSubmitFuture, transaction, cohorts,
                             CAN_COMMIT, TransactionCommitFailedExceptionMapper.CAN_COMMIT_ERROR_MAPPER,
                             new TransactionCommitFailedException(
                                             "Can Commit failed, no detailed cause available."));
                 } else {
                     if(remaining.decrementAndGet() == 0) {
                         // All cohorts completed successfully - we can move on to the preCommit phase
-                        doPreCommit(startTime, clientSubmitFuture, transaction, cohorts, cohortSize);
+                        doPreCommit(startTime, clientSubmitFuture, transaction, cohorts);
                     }
                 }
             }
 
             @Override
             public void onFailure(Throwable t) {
-                handleException(clientSubmitFuture, transaction, cohorts, cohortSize, CAN_COMMIT,
+                handleException(clientSubmitFuture, transaction, cohorts, CAN_COMMIT,
                         TransactionCommitFailedExceptionMapper.CAN_COMMIT_ERROR_MAPPER, t);
             }
         };
@@ -125,22 +124,22 @@ public class ConcurrentDOMDataBroker extends AbstractDOMDataBroker {
 
     private void doPreCommit(final long startTime, final AsyncNotifyingSettableFuture clientSubmitFuture,
             final DOMDataWriteTransaction transaction,
-            final Iterable<DOMStoreThreePhaseCommitCohort> cohorts, final int cohortSize) {
+            final Collection<DOMStoreThreePhaseCommitCohort> cohorts) {
 
         // Not using Futures.allAsList here to avoid its internal overhead.
-        final AtomicInteger remaining = new AtomicInteger(cohortSize);
+        final AtomicInteger remaining = new AtomicInteger(cohorts.size());
         FutureCallback<Void> futureCallback = new FutureCallback<Void>() {
             @Override
             public void onSuccess(Void notUsed) {
                 if(remaining.decrementAndGet() == 0) {
                     // All cohorts completed successfully - we can move on to the commit phase
-                    doCommit(startTime, clientSubmitFuture, transaction, cohorts, cohortSize);
+                    doCommit(startTime, clientSubmitFuture, transaction, cohorts);
                 }
             }
 
             @Override
             public void onFailure(Throwable t) {
-                handleException(clientSubmitFuture, transaction, cohorts, cohortSize, PRE_COMMIT,
+                handleException(clientSubmitFuture, transaction, cohorts, PRE_COMMIT,
                         TransactionCommitFailedExceptionMapper.PRE_COMMIT_MAPPER, t);
             }
         };
@@ -153,10 +152,10 @@ public class ConcurrentDOMDataBroker extends AbstractDOMDataBroker {
 
     private void doCommit(final long startTime, final AsyncNotifyingSettableFuture clientSubmitFuture,
             final DOMDataWriteTransaction transaction,
-            final Iterable<DOMStoreThreePhaseCommitCohort> cohorts, final int cohortSize) {
+            final Collection<DOMStoreThreePhaseCommitCohort> cohorts) {
 
         // Not using Futures.allAsList here to avoid its internal overhead.
-        final AtomicInteger remaining = new AtomicInteger(cohortSize);
+        final AtomicInteger remaining = new AtomicInteger(cohorts.size());
         FutureCallback<Void> futureCallback = new FutureCallback<Void>() {
             @Override
             public void onSuccess(Void notUsed) {
@@ -170,7 +169,7 @@ public class ConcurrentDOMDataBroker extends AbstractDOMDataBroker {
 
             @Override
             public void onFailure(Throwable t) {
-                handleException(clientSubmitFuture, transaction, cohorts, cohortSize, COMMIT,
+                handleException(clientSubmitFuture, transaction, cohorts, COMMIT,
                         TransactionCommitFailedExceptionMapper.COMMIT_ERROR_MAPPER, t);
             }
         };
@@ -183,7 +182,7 @@ public class ConcurrentDOMDataBroker extends AbstractDOMDataBroker {
 
     private void handleException(final AsyncNotifyingSettableFuture clientSubmitFuture,
             final DOMDataWriteTransaction transaction,
-            final Iterable<DOMStoreThreePhaseCommitCohort> cohorts, int cohortSize,
+            final Collection<DOMStoreThreePhaseCommitCohort> cohorts,
             final String phase, final TransactionCommitFailedExceptionMapper exMapper,
             final Throwable t) {
 
@@ -205,7 +204,7 @@ public class ConcurrentDOMDataBroker extends AbstractDOMDataBroker {
         // Transaction failed - tell all cohorts to abort.
 
         @SuppressWarnings("unchecked")
-        ListenableFuture<Void>[] canCommitFutures = new ListenableFuture[cohortSize];
+        ListenableFuture<Void>[] canCommitFutures = new ListenableFuture[cohorts.size()];
         int i = 0;
         for(DOMStoreThreePhaseCommitCohort cohort: cohorts) {
             canCommitFutures[i++] = cohort.abort();
index 7370ebee7fe1ae3c0ac3b60ddd4337ffad53e66f..f404c0637f4cfe5ac49fb4fa5001ad1c71aa563d 100644 (file)
@@ -8,17 +8,19 @@ package org.opendaylight.controller.md.sal.dom.api;
 
 import com.google.common.base.Preconditions;
 import java.io.Serializable;
+import java.util.Iterator;
 import javax.annotation.Nonnull;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.yangtools.concepts.Immutable;
 import org.opendaylight.yangtools.concepts.Path;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 
 /**
  * A unique identifier for a particular subtree. It is composed of the logical
  * data store type and the instance identifier of the root node.
  */
-public final class DOMDataTreeIdentifier implements Immutable, Path<DOMDataTreeIdentifier>, Serializable {
+public final class DOMDataTreeIdentifier implements Immutable, Path<DOMDataTreeIdentifier>, Serializable, Comparable<DOMDataTreeIdentifier> {
     private static final long serialVersionUID = 1L;
     private final YangInstanceIdentifier rootIdentifier;
     private final LogicalDatastoreType datastoreType;
@@ -74,4 +76,30 @@ public final class DOMDataTreeIdentifier implements Immutable, Path<DOMDataTreeI
         }
         return rootIdentifier.equals(other.rootIdentifier);
     }
+
+    @Override
+    public int compareTo(final DOMDataTreeIdentifier o) {
+        int i = datastoreType.compareTo(o.datastoreType);
+        if (i != 0) {
+            return i;
+        }
+
+        final Iterator<PathArgument> mi = rootIdentifier.getPathArguments().iterator();
+        final Iterator<PathArgument> oi = o.rootIdentifier.getPathArguments().iterator();
+
+        while (mi.hasNext()) {
+            if (!oi.hasNext()) {
+                return 1;
+            }
+
+            final PathArgument ma = mi.next();
+            final PathArgument oa = oi.next();
+            i = ma.compareTo(oa);
+            if (i != 0) {
+                return i;
+            }
+        }
+
+        return oi.hasNext() ? -1 : 0;
+    }
 }
index 08888c13cffec8b43da6efa8fb9703bcc9beb37c..8ee928e87835460097b712271ecf5744a4144276 100644 (file)
@@ -9,6 +9,7 @@ package org.opendaylight.controller.md.sal.dom.broker.impl;
 
 import com.google.common.base.Preconditions;
 import com.google.common.util.concurrent.CheckedFuture;
+import java.util.Collection;
 import java.util.EnumMap;
 import java.util.Map;
 import java.util.Map.Entry;
@@ -77,7 +78,7 @@ abstract class AbstractDOMForwardedTransactionFactory<T extends DOMStoreTransact
      *         the Future fails with a {@link TransactionCommitFailedException}.
      */
     protected abstract CheckedFuture<Void,TransactionCommitFailedException> submit(final DOMDataWriteTransaction transaction,
-            final Iterable<DOMStoreThreePhaseCommitCohort> cohorts);
+            final Collection<DOMStoreThreePhaseCommitCohort> cohorts);
 
     /**
      * Creates a new composite read-only transaction
index e0ac702dad59c8d0119460e13b9a87a9535a8cc1..b85350f95d25afde4b346842c3b457f8a23626c0 100644 (file)
@@ -8,9 +8,9 @@ package org.opendaylight.controller.md.sal.dom.broker.impl;
 
 import com.google.common.base.Preconditions;
 import com.google.common.base.Throwables;
-import com.google.common.collect.Iterables;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
+import java.util.Collection;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutionException;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
@@ -32,18 +32,16 @@ final class CommitCoordinationTask implements Callable<Void> {
     };
 
     private static final Logger LOG = LoggerFactory.getLogger(CommitCoordinationTask.class);
-    private final Iterable<DOMStoreThreePhaseCommitCohort> cohorts;
+    private final Collection<DOMStoreThreePhaseCommitCohort> cohorts;
     private final DurationStatisticsTracker commitStatTracker;
     private final DOMDataWriteTransaction tx;
-    private final int cohortSize;
 
     public CommitCoordinationTask(final DOMDataWriteTransaction transaction,
-            final Iterable<DOMStoreThreePhaseCommitCohort> cohorts,
+            final Collection<DOMStoreThreePhaseCommitCohort> cohorts,
             final DurationStatisticsTracker commitStatTracker) {
         this.tx = Preconditions.checkNotNull(transaction, "transaction must not be null");
         this.cohorts = Preconditions.checkNotNull(cohorts, "cohorts must not be null");
         this.commitStatTracker = commitStatTracker;
-        this.cohortSize = Iterables.size(cohorts);
     }
 
     @Override
@@ -115,7 +113,7 @@ final class CommitCoordinationTask implements Callable<Void> {
      *
      */
     private ListenableFuture<?>[] canCommitAll() {
-        final ListenableFuture<?>[] ops = new ListenableFuture<?>[cohortSize];
+        final ListenableFuture<?>[] ops = new ListenableFuture<?>[cohorts.size()];
         int i = 0;
         for (DOMStoreThreePhaseCommitCohort cohort : cohorts) {
             ops[i++] = cohort.canCommit();
@@ -162,7 +160,7 @@ final class CommitCoordinationTask implements Callable<Void> {
      *
      */
     private ListenableFuture<?>[] preCommitAll() {
-        final ListenableFuture<?>[] ops = new ListenableFuture<?>[cohortSize];
+        final ListenableFuture<?>[] ops = new ListenableFuture<?>[cohorts.size()];
         int i = 0;
         for (DOMStoreThreePhaseCommitCohort cohort : cohorts) {
             ops[i++] = cohort.preCommit();
@@ -205,7 +203,7 @@ final class CommitCoordinationTask implements Callable<Void> {
      * @return List of all cohorts futures from can commit phase.
      */
     private ListenableFuture<?>[] commitAll() {
-        final ListenableFuture<?>[] ops = new ListenableFuture<?>[cohortSize];
+        final ListenableFuture<?>[] ops = new ListenableFuture<?>[cohorts.size()];
         int i = 0;
         for (DOMStoreThreePhaseCommitCohort cohort : cohorts) {
             ops[i++] = cohort.commit();
@@ -256,7 +254,7 @@ final class CommitCoordinationTask implements Callable<Void> {
      */
     private ListenableFuture<Void> abortAsyncAll() {
 
-        final ListenableFuture<?>[] ops = new ListenableFuture<?>[cohortSize];
+        final ListenableFuture<?>[] ops = new ListenableFuture<?>[cohorts.size()];
         int i = 0;
         for (DOMStoreThreePhaseCommitCohort cohort : cohorts) {
             ops[i++] = cohort.abort();
index 77387c761cd6b26efea4c05471eb9632c695c578..201eb81a94155b49a0b32d00807b53c6ebebdb11 100644 (file)
@@ -10,6 +10,7 @@ import com.google.common.base.Preconditions;
 import com.google.common.util.concurrent.CheckedFuture;
 import com.google.common.util.concurrent.FutureCallback;
 import com.google.common.util.concurrent.Futures;
+import java.util.Collection;
 import java.util.Map;
 import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
 import java.util.concurrent.atomic.AtomicLong;
@@ -87,7 +88,7 @@ final class DOMDataBrokerTransactionChainImpl extends AbstractDOMForwardedTransa
 
     @Override
     public CheckedFuture<Void, TransactionCommitFailedException> submit(
-            final DOMDataWriteTransaction transaction, final Iterable<DOMStoreThreePhaseCommitCohort> cohorts) {
+            final DOMDataWriteTransaction transaction, final Collection<DOMStoreThreePhaseCommitCohort> cohorts) {
         checkNotFailed();
         checkNotClosed();
 
index 961b6c7b9312948ad862fa5236f7ab66ed834534..9895ff9ad5e87af9901b7ffe03b4a2e82726b307 100644 (file)
@@ -158,13 +158,16 @@ public final class PingPongTransactionChain implements DOMTransactionChain {
 
     /*
      * This forces allocateTransaction() on a slow path, which has to happen after
-     * this method has completed executing.
+     * this method has completed executing. Also inflightTx may be updated outside
+     * the lock, hence we need to re-check.
      */
     @GuardedBy("this")
     private void processIfReady() {
-        final PingPongTransaction tx = READY_UPDATER.getAndSet(this, null);
-        if (tx != null) {
-            processTransaction(tx);
+        if (inflightTx == null) {
+            final PingPongTransaction tx = READY_UPDATER.getAndSet(this, null);
+            if (tx != null) {
+                processTransaction(tx);
+            }
         }
     }
 
@@ -251,14 +254,27 @@ public final class PingPongTransactionChain implements DOMTransactionChain {
     }
 
     @Override
-    public void close() {
+    public synchronized void close() {
         final PingPongTransaction notLocked = lockedTx;
         Preconditions.checkState(notLocked == null, "Attempted to close chain with outstanding transaction %s", notLocked);
 
-        synchronized (this) {
-            processIfReady();
-            delegate.close();
+        // Force allocations on slow path. We will complete the rest
+        final PingPongTransaction tx = READY_UPDATER.getAndSet(this, null);
+
+        // Make sure no transaction is outstanding. Otherwise sleep a bit and retry
+        while (inflightTx != null) {
+            LOG.debug("Busy-waiting for in-flight transaction {} to complete", inflightTx);
+            Thread.yield();
+            continue;
         }
+
+        // If we have an outstanding transaction, send it down
+        if (tx != null) {
+            processTransaction(tx);
+        }
+
+        // All done, close the delegate. All new allocations should fail.
+        delegate.close();
     }
 
     @Override
index 268b1b85840fcecbc4b0de55fc6e8c903d5243e2..ad23e3a72bc9242878e3b13faba6727ed474fa65 100644 (file)
@@ -11,6 +11,7 @@ import com.google.common.util.concurrent.CheckedFuture;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
 import com.google.common.util.concurrent.ListeningExecutorService;
+import java.util.Collection;
 import java.util.Map;
 import java.util.concurrent.RejectedExecutionException;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
@@ -57,7 +58,7 @@ public class SerializedDOMDataBroker extends AbstractDOMDataBroker {
 
     @Override
     protected CheckedFuture<Void,TransactionCommitFailedException> submit(final DOMDataWriteTransaction transaction,
-            final Iterable<DOMStoreThreePhaseCommitCohort> cohorts) {
+            final Collection<DOMStoreThreePhaseCommitCohort> cohorts) {
         Preconditions.checkArgument(transaction != null, "Transaction must not be null.");
         Preconditions.checkArgument(cohorts != null, "Cohorts must not be null.");
         LOG.debug("Tx: {} is submitted for execution.", transaction.getIdentifier());
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/ShardRegistration.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/ShardRegistration.java
new file mode 100644 (file)
index 0000000..9a71089
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.dom.broker.impl;
+
+import com.google.common.base.Preconditions;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeIdentifier;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeShard;
+import org.opendaylight.yangtools.concepts.AbstractListenerRegistration;
+
+final class ShardRegistration<T extends DOMDataTreeShard> extends AbstractListenerRegistration<T> {
+    private final DOMDataTreeIdentifier prefix;
+    private final ShardedDOMDataTree tree;
+
+    protected ShardRegistration(final ShardedDOMDataTree tree, final DOMDataTreeIdentifier prefix, final T shard) {
+        super(shard);
+        this.tree = Preconditions.checkNotNull(tree);
+        this.prefix = Preconditions.checkNotNull(prefix);
+    }
+
+    DOMDataTreeIdentifier getPrefix() {
+        return prefix;
+    }
+
+    @Override
+    protected void removeRegistration() {
+        tree.removeShard(this);
+    }
+}
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/ShardedDOMDataTree.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/ShardedDOMDataTree.java
new file mode 100644 (file)
index 0000000..11eae5d
--- /dev/null
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.dom.broker.impl;
+
+import com.google.common.base.Preconditions;
+import java.util.Collection;
+import java.util.EnumMap;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.TreeMap;
+import javax.annotation.concurrent.GuardedBy;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeIdentifier;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeListener;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeProducer;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeService;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeShard;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeShardingConflictException;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeShardingService;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public final class ShardedDOMDataTree implements DOMDataTreeService, DOMDataTreeShardingService {
+    private static final Logger LOG = LoggerFactory.getLogger(ShardedDOMDataTree.class);
+    private final Map<LogicalDatastoreType, ShardingTableEntry> shardingTables = new EnumMap<>(LogicalDatastoreType.class);
+    @GuardedBy("this")
+    private final Map<DOMDataTreeIdentifier, DOMDataTreeProducer> idToProducer = new TreeMap<>();
+
+    @GuardedBy("this")
+    private ShardingTableEntry lookupShard(final DOMDataTreeIdentifier prefix) {
+        final ShardingTableEntry t = shardingTables.get(prefix.getDatastoreType());
+        if (t == null) {
+            return null;
+        }
+
+        return t.lookup(prefix.getRootIdentifier());
+    }
+
+    @GuardedBy("this")
+    private void storeShard(final DOMDataTreeIdentifier prefix, final ShardRegistration<?> reg) {
+        ShardingTableEntry t = shardingTables.get(prefix.getDatastoreType());
+        if (t == null) {
+            t = new ShardingTableEntry();
+            shardingTables.put(prefix.getDatastoreType(), t);
+        }
+
+        t.store(prefix.getRootIdentifier(), reg);
+    }
+
+    void removeShard(final ShardRegistration<?> reg) {
+        final DOMDataTreeIdentifier prefix = reg.getPrefix();
+        final ShardRegistration<?> parentReg;
+
+        synchronized (this) {
+            final ShardingTableEntry t = shardingTables.get(prefix.getDatastoreType());
+            if (t == null) {
+                LOG.warn("Shard registration {} points to non-existent table", reg);
+                return;
+            }
+
+            t.remove(prefix.getRootIdentifier());
+            parentReg = lookupShard(prefix).getRegistration();
+
+            /*
+             * FIXME: adjust all producers. This is tricky, as we need different locking strategy,
+             *        simply because we risk AB/BA deadlock with a producer being split off from
+             *        a producer.
+             *
+             */
+        }
+
+        if (parentReg != null) {
+            parentReg.getInstance().onChildDetached(prefix, reg.getInstance());
+        }
+    }
+
+    @Override
+    public <T extends DOMDataTreeShard> ListenerRegistration<T> registerDataTreeShard(final DOMDataTreeIdentifier prefix, final T shard) throws DOMDataTreeShardingConflictException {
+        final ShardRegistration<T> reg;
+        final ShardRegistration<?> parentReg;
+
+        synchronized (this) {
+            /*
+             * Lookup the parent shard (e.g. the one which currently matches the prefix),
+             * and if it exists, check if its registration prefix does not collide with
+             * this registration.
+             */
+            final ShardingTableEntry parent = lookupShard(prefix);
+            parentReg = parent.getRegistration();
+            if (parentReg != null && prefix.equals(parentReg.getPrefix())) {
+                throw new DOMDataTreeShardingConflictException(String.format("Prefix %s is already occupied by shard {}", prefix, parentReg.getInstance()));
+            }
+
+            // FIXME: wrap the shard in a proper adaptor based on implemented interface
+
+            reg = new ShardRegistration<T>(this, prefix, shard);
+
+            storeShard(prefix, reg);
+
+            // FIXME: update any producers/registrations
+        }
+
+        // Notify the parent shard
+        if (parentReg != null) {
+            parentReg.getInstance().onChildAttached(prefix, shard);
+        }
+
+        return reg;
+    }
+
+    @GuardedBy("this")
+    private DOMDataTreeProducer findProducer(final DOMDataTreeIdentifier subtree) {
+        for (Entry<DOMDataTreeIdentifier, DOMDataTreeProducer> e : idToProducer.entrySet()) {
+            if (e.getKey().contains(subtree)) {
+                return e.getValue();
+            }
+        }
+
+        return null;
+    }
+
+    synchronized void destroyProducer(final ShardedDOMDataTreeProducer producer) {
+        for (DOMDataTreeIdentifier s : producer.getSubtrees()) {
+            DOMDataTreeProducer r = idToProducer.remove(s);
+            if (!producer.equals(r)) {
+                LOG.error("Removed producer %s on subtree %s while removing %s", r, s, producer);
+            }
+        }
+    }
+
+    @GuardedBy("this")
+    private DOMDataTreeProducer createProducer(final Map<DOMDataTreeIdentifier, DOMDataTreeShard> shardMap) {
+        // Record the producer's attachment points
+        final DOMDataTreeProducer ret = ShardedDOMDataTreeProducer.create(this, shardMap);
+        for (DOMDataTreeIdentifier s : shardMap.keySet()) {
+            idToProducer.put(s, ret);
+        }
+
+        return ret;
+    }
+
+    @Override
+    public synchronized DOMDataTreeProducer createProducer(final Collection<DOMDataTreeIdentifier> subtrees) {
+        Preconditions.checkArgument(!subtrees.isEmpty(), "Subtrees may not be empty");
+
+        final Map<DOMDataTreeIdentifier, DOMDataTreeShard> shardMap = new HashMap<>();
+        for (DOMDataTreeIdentifier s : subtrees) {
+            // Attempting to create a disconnected producer -- all subtrees have to be unclaimed
+            final DOMDataTreeProducer producer = findProducer(s);
+            Preconditions.checkArgument(producer == null, "Subtree %s is attached to producer %s", s, producer);
+
+            shardMap.put(s, lookupShard(s).getRegistration().getInstance());
+        }
+
+        return createProducer(shardMap);
+    }
+
+    synchronized DOMDataTreeProducer createProducer(final ShardedDOMDataTreeProducer parent, final Collection<DOMDataTreeIdentifier> subtrees) {
+        Preconditions.checkNotNull(parent);
+
+        final Map<DOMDataTreeIdentifier, DOMDataTreeShard> shardMap = new HashMap<>();
+        for (DOMDataTreeIdentifier s : subtrees) {
+            shardMap.put(s, lookupShard(s).getRegistration().getInstance());
+        }
+
+        return createProducer(shardMap);
+    }
+
+    @Override
+    public synchronized <T extends DOMDataTreeListener> ListenerRegistration<T> registerListener(final T listener, final Collection<DOMDataTreeIdentifier> subtrees, final boolean allowRxMerges, final Collection<DOMDataTreeProducer> producers) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+}
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/ShardedDOMDataTreeProducer.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/ShardedDOMDataTreeProducer.java
new file mode 100644 (file)
index 0000000..9712b25
--- /dev/null
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.dom.broker.impl;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.BiMap;
+import com.google.common.collect.ImmutableBiMap;
+import com.google.common.collect.ImmutableBiMap.Builder;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Queue;
+import java.util.Set;
+import javax.annotation.concurrent.GuardedBy;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeIdentifier;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeProducer;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeProducerBusyException;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeProducerException;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeShard;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
+import org.opendaylight.controller.sal.core.spi.data.DOMStore;
+import org.opendaylight.controller.sal.core.spi.data.DOMStoreTransactionChain;
+import org.opendaylight.controller.sal.core.spi.data.DOMStoreWriteTransaction;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+final class ShardedDOMDataTreeProducer implements DOMDataTreeProducer {
+    private static final Logger LOG = LoggerFactory.getLogger(ShardedDOMDataTreeProducer.class);
+    private final BiMap<DOMDataTreeShard, DOMStoreTransactionChain> shardToChain;
+    private final Map<DOMDataTreeIdentifier, DOMDataTreeShard> idToShard;
+    private final ShardedDOMDataTree dataTree;
+
+    @GuardedBy("this")
+    private Map<DOMDataTreeIdentifier, DOMDataTreeProducer> children = Collections.emptyMap();
+    @GuardedBy("this")
+    private DOMDataWriteTransaction openTx;
+    @GuardedBy("this")
+    private boolean closed;
+
+    ShardedDOMDataTreeProducer(final ShardedDOMDataTree dataTree, final Map<DOMDataTreeIdentifier, DOMDataTreeShard> shardMap, final Set<DOMDataTreeShard> shards) {
+        this.dataTree = Preconditions.checkNotNull(dataTree);
+
+        // Create shard -> chain map
+        final Builder<DOMDataTreeShard, DOMStoreTransactionChain> cb = ImmutableBiMap.builder();
+        final Queue<Exception> es = new LinkedList<>();
+
+        for (DOMDataTreeShard s : shards) {
+            if (s instanceof DOMStore) {
+                try {
+                    final DOMStoreTransactionChain c = ((DOMStore)s).createTransactionChain();
+                    LOG.trace("Using DOMStore chain {} to access shard {}", c, s);
+                    cb.put(s, c);
+                } catch (Exception e) {
+                    LOG.error("Failed to instantiate chain for shard {}", s, e);
+                    es.add(e);
+                }
+            } else {
+                LOG.error("Unhandled shard instance type {}", s.getClass());
+            }
+        }
+        this.shardToChain = cb.build();
+
+        // An error was encountered, close chains and report the error
+        if (shardToChain.size() != shards.size()) {
+            for (DOMStoreTransactionChain c : shardToChain.values()) {
+                try {
+                    c.close();
+                } catch (Exception e) {
+                    LOG.warn("Exception raised while closing chain %s", c, e);
+                }
+            }
+
+            final IllegalStateException e = new IllegalStateException("Failed to completely allocate contexts", es.poll());
+            while (!es.isEmpty()) {
+                e.addSuppressed(es.poll());
+            }
+
+            throw e;
+        }
+
+        idToShard = ImmutableMap.copyOf(shardMap);
+    }
+
+    @Override
+    public synchronized DOMDataWriteTransaction createTransaction(final boolean isolated) {
+        Preconditions.checkState(!closed, "Producer is already closed");
+        Preconditions.checkState(openTx == null, "Transaction %s is still open", openTx);
+
+        // Allocate backing transactions
+        final Map<DOMDataTreeShard, DOMStoreWriteTransaction> shardToTx = new HashMap<>();
+        for (Entry<DOMDataTreeShard, DOMStoreTransactionChain> e : shardToChain.entrySet()) {
+            shardToTx.put(e.getKey(), e.getValue().newWriteOnlyTransaction());
+        }
+
+        // Create the ID->transaction map
+        final ImmutableMap.Builder<DOMDataTreeIdentifier, DOMStoreWriteTransaction> b = ImmutableMap.builder();
+        for (Entry<DOMDataTreeIdentifier, DOMDataTreeShard> e : idToShard.entrySet()) {
+            b.put(e.getKey(), shardToTx.get(e.getValue()));
+        }
+
+        final ShardedDOMDataWriteTransaction ret = new ShardedDOMDataWriteTransaction(this, b.build());
+        openTx = ret;
+        return ret;
+    }
+
+    @GuardedBy("this")
+    private boolean haveSubtree(final DOMDataTreeIdentifier subtree) {
+        for (DOMDataTreeIdentifier i : idToShard.keySet()) {
+            if (i.contains(subtree)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    @GuardedBy("this")
+    private DOMDataTreeProducer lookupChild(final DOMDataTreeIdentifier s) {
+        for (Entry<DOMDataTreeIdentifier, DOMDataTreeProducer> e : children.entrySet()) {
+            if (e.getKey().contains(s)) {
+                return e.getValue();
+            }
+        }
+
+        return null;
+    }
+
+    @Override
+    public synchronized DOMDataTreeProducer createProducer(final Collection<DOMDataTreeIdentifier> subtrees) {
+        Preconditions.checkState(!closed, "Producer is already closed");
+        Preconditions.checkState(openTx == null, "Transaction %s is still open", openTx);
+
+        for (DOMDataTreeIdentifier s : subtrees) {
+            // Check if the subtree was visible at any time
+            if (!haveSubtree(s)) {
+                throw new IllegalArgumentException(String.format("Subtree %s was never available in producer %s", s, this));
+            }
+
+            // Check if the subtree has not been delegated to a child
+            final DOMDataTreeProducer child = lookupChild(s);
+            Preconditions.checkArgument(child == null, "Subtree %s is delegated to child producer %s", s, child);
+
+            // Check if part of the requested subtree is not delegated to a child.
+            for (DOMDataTreeIdentifier c : children.keySet()) {
+                if (s.contains(c)) {
+                    throw new IllegalArgumentException(String.format("Subtree %s cannot be delegated as it is superset of already-delegated %s", s, c));
+                }
+            }
+        }
+
+        final DOMDataTreeProducer ret = dataTree.createProducer(this, subtrees);
+        final ImmutableMap.Builder<DOMDataTreeIdentifier, DOMDataTreeProducer> cb = ImmutableMap.builder();
+        cb.putAll(children);
+        for (DOMDataTreeIdentifier s : subtrees) {
+            cb.put(s, ret);
+        }
+
+        children = cb.build();
+        return ret;
+    }
+
+    @Override
+    public synchronized void close() throws DOMDataTreeProducerException {
+        if (!closed) {
+            if (openTx != null) {
+                throw new DOMDataTreeProducerBusyException(String.format("Transaction %s is still open", openTx));
+            }
+
+            closed = true;
+            dataTree.destroyProducer(this);
+        }
+    }
+
+    static DOMDataTreeProducer create(final ShardedDOMDataTree dataTree, final Map<DOMDataTreeIdentifier, DOMDataTreeShard> shardMap) {
+        /*
+         * FIXME: we do not allow multiple multiple shards in a producer because we do not implement the
+         *        synchronization primitives yet
+         */
+        final Set<DOMDataTreeShard> shards = ImmutableSet.copyOf(shardMap.values());
+        if (shards.size() > 1) {
+            throw new UnsupportedOperationException("Cross-shard producers are not supported yet");
+        }
+
+        return new ShardedDOMDataTreeProducer(dataTree, shardMap, shards);
+    }
+
+    Set<DOMDataTreeIdentifier> getSubtrees() {
+        return idToShard.keySet();
+    }
+
+    synchronized void cancelTransaction(final ShardedDOMDataWriteTransaction transaction) {
+        if (!openTx.equals(transaction)) {
+            LOG.warn("Transaction {} is not open in producer {}", transaction, this);
+            return;
+        }
+
+        LOG.debug("Transaction {} cancelled", transaction);
+        openTx = null;
+    }
+}
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/ShardedDOMDataWriteTransaction.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/ShardedDOMDataWriteTransaction.java
new file mode 100644 (file)
index 0000000..33f15e3
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.dom.broker.impl;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicLong;
+import javax.annotation.concurrent.GuardedBy;
+import javax.annotation.concurrent.NotThreadSafe;
+import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.controller.md.sal.common.impl.service.AbstractDataTransaction;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeIdentifier;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
+import org.opendaylight.controller.sal.core.spi.data.DOMStoreThreePhaseCommitCohort;
+import org.opendaylight.controller.sal.core.spi.data.DOMStoreWriteTransaction;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@NotThreadSafe
+final class ShardedDOMDataWriteTransaction implements DOMDataWriteTransaction {
+    private static final Logger LOG = LoggerFactory.getLogger(ShardedDOMDataWriteTransaction.class);
+    private static final AtomicLong COUNTER = new AtomicLong();
+    private final Map<DOMDataTreeIdentifier, DOMStoreWriteTransaction> idToTransaction;
+    private final ShardedDOMDataTreeProducer producer;
+    private final String identifier;
+    @GuardedBy("this")
+    private boolean closed =  false;
+
+    ShardedDOMDataWriteTransaction(final ShardedDOMDataTreeProducer producer, final Map<DOMDataTreeIdentifier, DOMStoreWriteTransaction> idToTransaction) {
+        this.producer = Preconditions.checkNotNull(producer);
+        this.idToTransaction = Preconditions.checkNotNull(idToTransaction);
+        this.identifier = "SHARDED-DOM-" + COUNTER.getAndIncrement();
+    }
+
+    // FIXME: use atomic operations
+    @GuardedBy("this")
+    private DOMStoreWriteTransaction lookup(final LogicalDatastoreType store, final YangInstanceIdentifier path) {
+        final DOMDataTreeIdentifier id = new DOMDataTreeIdentifier(store, path);
+
+        for (Entry<DOMDataTreeIdentifier, DOMStoreWriteTransaction> e : idToTransaction.entrySet()) {
+            if (e.getKey().contains(id)) {
+                return e.getValue();
+            }
+        }
+
+        throw new IllegalArgumentException(String.format("Path %s is not acessible from transaction %s", id, this));
+    }
+
+    @Override
+    public String getIdentifier() {
+        return identifier;
+    }
+
+    @Override
+    public synchronized boolean cancel() {
+        if (closed) {
+            return false;
+        }
+
+        LOG.debug("Cancelling transaction {}", identifier);
+        for (DOMStoreWriteTransaction tx : ImmutableSet.copyOf(idToTransaction.values())) {
+            tx.close();
+        }
+
+        closed = true;
+        producer.cancelTransaction(this);
+        return true;
+    }
+
+    @Override
+    public synchronized CheckedFuture<Void, TransactionCommitFailedException> submit() {
+        Preconditions.checkState(!closed, "Transaction %s is already closed", identifier);
+
+        final Set<DOMStoreWriteTransaction> txns = ImmutableSet.copyOf(idToTransaction.values());
+        final List<DOMStoreThreePhaseCommitCohort> cohorts = new ArrayList<>(txns.size());
+        for (DOMStoreWriteTransaction tx : txns) {
+            cohorts.add(tx.ready());
+        }
+
+        try {
+            return Futures.immediateCheckedFuture(new CommitCoordinationTask(this, cohorts, null).call());
+        } catch (TransactionCommitFailedException e) {
+            return Futures.immediateFailedCheckedFuture(e);
+        }
+    }
+
+    @Override
+    @Deprecated
+    public ListenableFuture<RpcResult<TransactionStatus>> commit() {
+        return AbstractDataTransaction.convertToLegacyCommitFuture(submit());
+    }
+
+    @Override
+    public synchronized void delete(final LogicalDatastoreType store, final YangInstanceIdentifier path) {
+        lookup(store, path).delete(path);
+    }
+
+    @Override
+    public synchronized void put(final LogicalDatastoreType store, final YangInstanceIdentifier path, final NormalizedNode<?, ?> data) {
+        lookup(store, path).write(path, data);
+    }
+
+    @Override
+    public synchronized void merge(final LogicalDatastoreType store, final YangInstanceIdentifier path, final NormalizedNode<?, ?> data) {
+        lookup(store, path).merge(path, data);
+    }
+}
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/ShardingTableEntry.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/ShardingTableEntry.java
new file mode 100644 (file)
index 0000000..fcd0ebd
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.dom.broker.impl;
+
+import com.google.common.base.Preconditions;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Map;
+import org.opendaylight.yangtools.concepts.Identifiable;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+final class ShardingTableEntry implements Identifiable<PathArgument> {
+    private static final Logger LOG = LoggerFactory.getLogger(ShardingTableEntry.class);
+    private final Map<PathArgument, ShardingTableEntry> children = Collections.emptyMap();
+    private final PathArgument identifier;
+    private ShardRegistration<?> registration;
+
+    ShardingTableEntry() {
+        identifier = null;
+    }
+
+    ShardingTableEntry(final PathArgument identifier) {
+        this.identifier = Preconditions.checkNotNull(identifier);
+    }
+
+    @Override
+    public PathArgument getIdentifier() {
+        return identifier;
+    }
+
+    public ShardRegistration<?> getRegistration() {
+        return registration;
+    }
+
+    ShardingTableEntry lookup(final YangInstanceIdentifier id) {
+        final Iterator<PathArgument> it = id.getPathArguments().iterator();
+        ShardingTableEntry entry = this;
+
+        while (it.hasNext()) {
+            final PathArgument a = it.next();
+            final ShardingTableEntry child = entry.children.get(a);
+            if (child == null) {
+                LOG.debug("Lookup of {} stopped at {}", id, a);
+                break;
+            }
+
+            entry = child;
+        }
+
+        return entry;
+    }
+
+    void store(final YangInstanceIdentifier id, final ShardRegistration<?> reg) {
+        final Iterator<PathArgument> it = id.getPathArguments().iterator();
+        ShardingTableEntry entry = this;
+
+        while (it.hasNext()) {
+            final PathArgument a = it.next();
+            ShardingTableEntry child = entry.children.get(a);
+            if (child == null) {
+                child = new ShardingTableEntry(a);
+                entry.children.put(a, child);
+            }
+        }
+
+        Preconditions.checkState(entry.registration == null);
+        entry.registration = reg;
+    }
+
+    private boolean remove(final Iterator<PathArgument> it) {
+        if (it.hasNext()) {
+            final PathArgument arg = it.next();
+            final ShardingTableEntry child = children.get(arg);
+            if (child != null) {
+                if (child.remove(it)) {
+                    children.remove(arg);
+                }
+            } else {
+                LOG.warn("Cannot remove non-existent child {}", arg);
+            }
+        }
+
+        return registration == null && children.isEmpty();
+    }
+
+    void remove(final YangInstanceIdentifier id) {
+        this.remove(id.getPathArguments().iterator());
+    }
+}
index 8553820b40095755d4ee82361d184cbf5590fc9e..c62f56ac1ebd29b2c9eabf065a3512ec24ba60b2 100644 (file)
@@ -248,6 +248,10 @@ public class NetconfDeviceCommunicator implements NetconfClientSessionListener,
 
                 request.future.set( RpcResultBuilder.<NetconfMessage>failed()
                         .withRpcError( NetconfMessageTransformUtil.toRpcError( e ) ).build() );
+
+                //recursively processing message to eventually find matching request
+                processMessage(message);
+
                 return;
             }
 
index 68fe87fb6036b0cab08cb277682416df49415f26..0ff5e2d3d50014dcaf5ddc6184e9fda4a1ecb295 100644 (file)
@@ -296,6 +296,27 @@ public class NetconfDeviceCommunicatorTest {
         return new NetconfMessage( doc );
     }
 
+    //Test scenario verifying whether missing message is handled
+    @Test
+    public void testOnMissingResponseMessage() throws Exception {
+
+        setupSession();
+
+        String messageID1 = UUID.randomUUID().toString();
+        ListenableFuture<RpcResult<NetconfMessage>> resultFuture1 = sendRequest( messageID1 );
+
+        String messageID2 = UUID.randomUUID().toString();
+        ListenableFuture<RpcResult<NetconfMessage>> resultFuture2 = sendRequest( messageID2 );
+
+        String messageID3 = UUID.randomUUID().toString();
+        ListenableFuture<RpcResult<NetconfMessage>> resultFuture3 = sendRequest( messageID3 );
+
+        //response messages 1,2 are omitted
+        communicator.onMessage( mockSession, createSuccessResponseMessage( messageID3 ) );
+
+        verifyResponseMessage( resultFuture3.get(), messageID3 );
+    }
+
     @Test
     public void testOnSuccessfulResponseMessage() throws Exception {
         setupSession();
index 4a9684717574e8d55741abb62741cdfaf875b305..7daad1631aac9153b4021b5a52c8ecd51cefab50 100644 (file)
       <groupId>org.opendaylight.yangtools</groupId>
       <artifactId>yang-data-codec-gson</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.yangtools</groupId>
+      <artifactId>yang-model-export</artifactId>
+      <!-- FIXME: remove explicit version, once model export package is part of yangtools-artefacts -->
+      <version>0.7.0-SNAPSHOT</version>
+    </dependency>
 
     <dependency>
       <groupId>ch.qos.logback</groupId>
             <Private-Package>org.opendaylight.controller.sal.rest.*,
               org.opendaylight.controller.sal.restconf.rpc.*,
               org.opendaylight.controller.sal.restconf.impl,
+              org.opendaylight.controller.md.sal.rest.common.*,
               org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.rest.connector.rev140724.*,
             </Private-Package>
             <Import-Package>*,
diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/md/sal/rest/common/RestconfValidationUtils.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/md/sal/rest/common/RestconfValidationUtils.java
new file mode 100644 (file)
index 0000000..0d53c9c
--- /dev/null
@@ -0,0 +1,66 @@
+/**
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.md.sal.rest.common;
+
+import org.opendaylight.controller.sal.restconf.impl.RestconfDocumentedException;
+import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorTag;
+import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorType;
+
+/**
+ * sal-rest-connector
+ * org.opendaylight.controller.md.sal.rest.common
+ *
+ * Utility class is centralizing all needed validation functionality for a Restconf osgi module.
+ * All methods have to throw {@link RestconfDocumentedException} only, which is a representation
+ * for all error situation followed by restconf-netconf specification.
+ * @see {@link https://tools.ietf.org/html/draft-bierman-netconf-restconf-02}
+ *
+ * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
+ *
+ * Created: Feb 24, 2015
+ */
+public class RestconfValidationUtils {
+
+    private RestconfValidationUtils () {
+        throw new UnsupportedOperationException("Utility class");
+    }
+
+    /**
+     * Method returns {@link RestconfDocumentedException} for a false condition.
+     *
+     * @param condition - condition for rise {@link RestconfDocumentedException}
+     * @param type      - input {@link ErrorType} for create {@link RestconfDocumentedException}
+     * @param tag       - input {@link ErrorTag} for create {@link RestconfDocumentedException}
+     * @param message   - input error message for create {@link RestconfDocumentedException}
+     */
+    public static void checkDocumentedError(final boolean condition, final ErrorType type,
+            final ErrorTag tag, final String message) {
+        if(!condition) {
+            throw new RestconfDocumentedException(message, type, tag);
+        }
+    }
+
+    /**
+     * Method returns {@link RestconfDocumentedException} if value is NULL or same input value.
+     * {@link ErrorType} is relevant for server application layer
+     * {@link ErrorTag} is 404 data-missing
+     * @see {@link https://tools.ietf.org/html/draft-bierman-netconf-restconf-02}
+     *
+     * @param value         - some value from {@link org.opendaylight.yangtools.yang.model.api.Module}
+     * @param moduleName    - name of {@link org.opendaylight.yangtools.yang.model.api.Module}
+     * @return              - T value (same input value)
+     */
+    public static <T> T checkNotNullDocumented(final T value, final String moduleName) {
+        if(value == null) {
+            final String errMsg = "Module " + moduleName + "was not found.";
+            throw new RestconfDocumentedException(errMsg, ErrorType.APPLICATION, ErrorTag.DATA_MISSING);
+        }
+        return value;
+    }
+}
diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/md/sal/rest/schema/SchemaExportContentYangBodyWriter.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/md/sal/rest/schema/SchemaExportContentYangBodyWriter.java
new file mode 100644 (file)
index 0000000..20300e2
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2014 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.md.sal.rest.schema;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import javax.ws.rs.Produces;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.ext.MessageBodyWriter;
+import javax.ws.rs.ext.Provider;
+
+@Provider
+@Produces(SchemaRetrievalService.YANG_MEDIA_TYPE)
+public class SchemaExportContentYangBodyWriter implements MessageBodyWriter<SchemaExportContext> {
+
+    @Override
+    public boolean isWriteable(final Class<?> type, final Type genericType, final Annotation[] annotations,
+            final MediaType mediaType) {
+        return type.equals(SchemaExportContext.class);
+    }
+
+    @Override
+    public long getSize(final SchemaExportContext t, final Class<?> type, final Type genericType,
+            final Annotation[] annotations, final MediaType mediaType) {
+        return -1;
+    }
+
+    @Override
+    public void writeTo(final SchemaExportContext t, final Class<?> type, final Type genericType,
+            final Annotation[] annotations, final MediaType mediaType,
+            final MultivaluedMap<String, Object> httpHeaders, final OutputStream entityStream) throws IOException,
+            WebApplicationException {
+        final PrintWriter writer = new PrintWriter(entityStream);
+        writer.write(t.getModule().getSource());
+
+    }
+}
diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/md/sal/rest/schema/SchemaExportContentYinBodyWriter.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/md/sal/rest/schema/SchemaExportContentYinBodyWriter.java
new file mode 100644 (file)
index 0000000..9773c0a
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2014 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.md.sal.rest.schema;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import javax.ws.rs.Produces;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.ext.MessageBodyWriter;
+import javax.ws.rs.ext.Provider;
+import javax.xml.stream.XMLStreamException;
+import org.opendaylight.yangtools.yang.model.export.YinExportUtils;
+
+@Provider
+@Produces(SchemaRetrievalService.YIN_MEDIA_TYPE)
+public class SchemaExportContentYinBodyWriter implements MessageBodyWriter<SchemaExportContext> {
+
+    @Override
+    public boolean isWriteable(final Class<?> type, final Type genericType, final Annotation[] annotations,
+            final MediaType mediaType) {
+        return type.equals(SchemaExportContext.class);
+    }
+
+    @Override
+    public long getSize(final SchemaExportContext t, final Class<?> type, final Type genericType,
+            final Annotation[] annotations, final MediaType mediaType) {
+        return -1;
+    }
+
+    @Override
+    public void writeTo(final SchemaExportContext t, final Class<?> type, final Type genericType,
+            final Annotation[] annotations, final MediaType mediaType,
+            final MultivaluedMap<String, Object> httpHeaders, final OutputStream entityStream) throws IOException,
+            WebApplicationException {
+        try {
+            YinExportUtils.writeModuleToOutputStream(t.getSchemaContext(), t.getModule(), entityStream);
+        } catch (final XMLStreamException e) {
+            throw new IllegalStateException(e);
+        }
+
+    }
+}
diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/md/sal/rest/schema/SchemaExportContext.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/md/sal/rest/schema/SchemaExportContext.java
new file mode 100644 (file)
index 0000000..4d3c95f
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2014 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.md.sal.rest.schema;
+
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+public class SchemaExportContext {
+
+    private final SchemaContext schemaContext;
+    private final Module module;
+
+    public SchemaExportContext(final SchemaContext ctx, final Module module) {
+        schemaContext = ctx;
+        this.module = module;
+    }
+
+    public SchemaContext getSchemaContext() {
+        return schemaContext;
+    }
+
+    public Module getModule() {
+        return module;
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/md/sal/rest/schema/SchemaRetrievalService.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/md/sal/rest/schema/SchemaRetrievalService.java
new file mode 100644 (file)
index 0000000..b268247
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2014 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.md.sal.rest.schema;
+
+import com.google.common.annotations.Beta;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+
+@Beta
+public interface SchemaRetrievalService {
+
+    public static final String YANG_MEDIA_TYPE = "application/yang";
+    public static final String YIN_MEDIA_TYPE = "application/yin+xml";
+
+    @GET
+    @Produces({YIN_MEDIA_TYPE,YANG_MEDIA_TYPE})
+    @Path("/modules/module/{identifier:.+}/schema")
+    SchemaExportContext getSchema(@PathParam("identifier") String mountAndModuleId);
+}
diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/md/sal/rest/schema/SchemaRetrievalServiceImpl.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/md/sal/rest/schema/SchemaRetrievalServiceImpl.java
new file mode 100644 (file)
index 0000000..b7308c1
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2014 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.md.sal.rest.schema;
+
+import com.google.common.base.Splitter;
+import com.google.common.collect.Iterables;
+import java.text.ParseException;
+import java.util.Date;
+import java.util.Iterator;
+import org.opendaylight.controller.md.sal.rest.common.RestconfValidationUtils;
+import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
+import org.opendaylight.controller.sal.restconf.impl.InstanceIdentifierContext;
+import org.opendaylight.controller.sal.restconf.impl.RestconfDocumentedException;
+import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorTag;
+import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorType;
+import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+public class SchemaRetrievalServiceImpl implements SchemaRetrievalService {
+
+    private final ControllerContext salContext;
+
+    private static final Splitter SLASH_SPLITTER = Splitter.on("/");
+    private static final Splitter AT_SPLITTER = Splitter.on("@");
+    private static final String MOUNT_ARG = ControllerContext.MOUNT;
+
+    public SchemaRetrievalServiceImpl(final ControllerContext controllerContext) {
+        salContext = controllerContext;
+    }
+
+
+    @Override
+    public SchemaExportContext getSchema(final String mountAndModule) {
+        final SchemaContext schemaContext;
+        final Iterable<String> pathComponents = SLASH_SPLITTER.split(mountAndModule);
+        final Iterator<String> componentIter = pathComponents.iterator();
+        if(!Iterables.contains(pathComponents, MOUNT_ARG)) {
+            schemaContext = salContext.getGlobalSchema();
+        } else {
+            final StringBuilder pathBuilder = new StringBuilder();
+            while(componentIter.hasNext()) {
+                final String current = componentIter.next();
+                // It is argument, not last element.
+                if(pathBuilder.length() != 0) {
+                        pathBuilder.append("/");
+                }
+                pathBuilder.append(current);
+                if(MOUNT_ARG.equals(current)) {
+                    // We stop right at mountpoint, last two arguments should
+                    // be module name and revision
+                    break;
+                }
+            }
+            schemaContext = getMountSchemaContext(pathBuilder.toString());
+
+        }
+
+        RestconfValidationUtils.checkDocumentedError(componentIter.hasNext(),
+                ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE, "Module name must be supplied.");
+        final String moduleName = componentIter.next();
+        RestconfValidationUtils.checkDocumentedError(componentIter.hasNext(),
+                ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE, "Revision date must be supplied.");
+        final String revisionString = componentIter.next();
+        return getExportUsingNameAndRevision(schemaContext, moduleName, revisionString);
+    }
+
+    private SchemaExportContext getExportUsingNameAndRevision(final SchemaContext schemaContext, final String moduleName,
+            final String revisionStr) {
+        try {
+            final Date revision = SimpleDateFormatUtil.getRevisionFormat().parse(revisionStr);
+            final Module module = schemaContext.findModuleByName(moduleName, revision);
+            return new SchemaExportContext(schemaContext, RestconfValidationUtils.checkNotNullDocumented(module, moduleName));
+        } catch (final ParseException e) {
+            throw new RestconfDocumentedException("Supplied revision is not in expected date format YYYY-mm-dd", e);
+        }
+    }
+
+    private SchemaContext getMountSchemaContext(final String identifier) {
+        final InstanceIdentifierContext mountContext = salContext.toMountPointIdentifier(identifier);
+        return mountContext.getSchemaContext();
+    }
+
+
+
+}
+
index a784be2adca3128cfc74134a3dcd9267528f5538..699aed66d7bcd3b62398831946a98b509420fb82 100644 (file)
@@ -22,31 +22,34 @@ import java.io.EOFException;
 import java.io.IOException;
 
 /**
+ * @deprecated class will be removed in Lithium release
+ *
  * This class parses JSON elements from a gson JsonReader. It disallows multiple elements of the same name unlike the
  * default gson JsonParser."
  */
+@Deprecated
 public class JsonParser {
-    public JsonElement parse(JsonReader reader) throws JsonIOException, JsonSyntaxException {
+    public JsonElement parse(final JsonReader reader) throws JsonIOException, JsonSyntaxException {
         // code copied from gson's JsonParser and Stream classes
 
-        boolean lenient = reader.isLenient();
+        final boolean lenient = reader.isLenient();
         reader.setLenient(true);
         boolean isEmpty = true;
         try {
             reader.peek();
             isEmpty = false;
             return read(reader);
-        } catch (EOFException e) {
+        } catch (final EOFException e) {
             if (isEmpty) {
                 return JsonNull.INSTANCE;
             }
             // The stream ended prematurely so it is likely a syntax error.
             throw new JsonSyntaxException(e);
-        } catch (MalformedJsonException e) {
+        } catch (final MalformedJsonException e) {
             throw new JsonSyntaxException(e);
-        } catch (IOException e) {
+        } catch (final IOException e) {
             throw new JsonIOException(e);
-        } catch (NumberFormatException e) {
+        } catch (final NumberFormatException e) {
             throw new JsonSyntaxException(e);
         } catch (StackOverflowError | OutOfMemoryError e) {
             throw new JsonParseException("Failed parsing JSON source: " + reader + " to Json", e);
@@ -55,12 +58,12 @@ public class JsonParser {
         }
     }
 
-    public JsonElement read(JsonReader in) throws IOException {
+    public JsonElement read(final JsonReader in) throws IOException {
         switch (in.peek()) {
         case STRING:
             return new JsonPrimitive(in.nextString());
         case NUMBER:
-            String number = in.nextString();
+            final String number = in.nextString();
             return new JsonPrimitive(new LazilyParsedNumber(number));
         case BOOLEAN:
             return new JsonPrimitive(in.nextBoolean());
@@ -68,7 +71,7 @@ public class JsonParser {
             in.nextNull();
             return JsonNull.INSTANCE;
         case BEGIN_ARRAY:
-            JsonArray array = new JsonArray();
+            final JsonArray array = new JsonArray();
             in.beginArray();
             while (in.hasNext()) {
                 array.add(read(in));
@@ -76,7 +79,7 @@ public class JsonParser {
             in.endArray();
             return array;
         case BEGIN_OBJECT:
-            JsonObject object = new JsonObject();
+            final JsonObject object = new JsonObject();
             in.beginObject();
             while (in.hasNext()) {
                 final String childName = in.nextName();
index caff848180e84400c5a810bfd1939da1e295a22c..6863b964d47f42bccbd3a7f084e17aad03b5dc68 100644 (file)
@@ -26,6 +26,9 @@ import org.opendaylight.yangtools.yang.data.api.Node;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+/**
+ * @deprecated class will be removed in Lithium release
+ */
 @Provider
 @Consumes({ Draft02.MediaTypes.DATA + RestconfService.JSON, Draft02.MediaTypes.OPERATION + RestconfService.JSON,
         MediaType.APPLICATION_JSON })
@@ -47,7 +50,7 @@ public enum JsonToCompositeNodeProvider implements MessageBodyReader<Node<?>> {
             WebApplicationException {
         try {
             return JsonToCompositeNodeReader.read(entityStream);
-        } catch (Exception e) {
+        } catch (final Exception e) {
             LOG.debug("Error parsing json input", e);
 
             throw new RestconfDocumentedException("Error parsing input: " + e.getMessage(), ErrorType.PROTOCOL,
index 552e2bbd190d154280e1a8ce7a3bc22d89de908b..2834fa15c1fee42df91917b0b3a39193abb51639 100644 (file)
@@ -28,6 +28,10 @@ import org.opendaylight.controller.sal.restconf.impl.SimpleNodeWrapper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+/**
+ * @deprecated class will be removed in Lithium release
+ */
+@Deprecated
 class JsonToCompositeNodeReader {
     private static final Logger LOG = LoggerFactory.getLogger(JsonToCompositeNodeReader.class);
     private static final Splitter COLON_SPLITTER = Splitter.on(':');
@@ -37,9 +41,9 @@ class JsonToCompositeNodeReader {
     }
 
     public static CompositeNodeWrapper read(final InputStream entityStream) throws UnsupportedFormatException {
-        JsonParser parser = new JsonParser();
+        final JsonParser parser = new JsonParser();
 
-        JsonElement rootElement = parser.parse(new JsonReader(new InputStreamReader(entityStream)));
+        final JsonElement rootElement = parser.parse(new JsonReader(new InputStreamReader(entityStream)));
         if (rootElement.isJsonNull()) {
             // no content, so return null to indicate no input
             return null;
@@ -49,14 +53,14 @@ class JsonToCompositeNodeReader {
             throw new UnsupportedFormatException("Root element of Json has to be Object");
         }
 
-        Set<Entry<String, JsonElement>> entrySetsOfRootJsonObject = rootElement.getAsJsonObject().entrySet();
+        final Set<Entry<String, JsonElement>> entrySetsOfRootJsonObject = rootElement.getAsJsonObject().entrySet();
         if (entrySetsOfRootJsonObject.size() != 1) {
             throw new UnsupportedFormatException("Json Object should contain one element");
         }
 
-        Entry<String, JsonElement> childEntry = entrySetsOfRootJsonObject.iterator().next();
-        String firstElementName = childEntry.getKey();
-        JsonElement firstElementType = childEntry.getValue();
+        final Entry<String, JsonElement> childEntry = entrySetsOfRootJsonObject.iterator().next();
+        final String firstElementName = childEntry.getKey();
+        final JsonElement firstElementType = childEntry.getValue();
         if (firstElementType.isJsonObject()) {
             // container in yang
             return createStructureWithRoot(firstElementName, firstElementType.getAsJsonObject());
@@ -64,7 +68,7 @@ class JsonToCompositeNodeReader {
         if (firstElementType.isJsonArray()) {
             // list in yang
             if (firstElementType.getAsJsonArray().size() == 1) {
-                JsonElement firstElementInArray = firstElementType.getAsJsonArray().get(0);
+                final JsonElement firstElementInArray = firstElementType.getAsJsonArray().get(0);
                 if (firstElementInArray.isJsonObject()) {
                     return createStructureWithRoot(firstElementName, firstElementInArray.getAsJsonObject());
                 }
@@ -77,9 +81,9 @@ class JsonToCompositeNodeReader {
     }
 
     private static CompositeNodeWrapper createStructureWithRoot(final String rootObjectName, final JsonObject rootObject) {
-        CompositeNodeWrapper firstNode = new CompositeNodeWrapper(getNamespaceFor(rootObjectName),
+        final CompositeNodeWrapper firstNode = new CompositeNodeWrapper(getNamespaceFor(rootObjectName),
                 getLocalNameFor(rootObjectName));
-        for (Entry<String, JsonElement> childOfFirstNode : rootObject.entrySet()) {
+        for (final Entry<String, JsonElement> childOfFirstNode : rootObject.entrySet()) {
             addChildToParent(childOfFirstNode.getKey(), childOfFirstNode.getValue(), firstNode);
         }
         return firstNode;
@@ -88,10 +92,10 @@ class JsonToCompositeNodeReader {
     private static void addChildToParent(final String childName, final JsonElement childType,
             final CompositeNodeWrapper parent) {
         if (childType.isJsonObject()) {
-            CompositeNodeWrapper child = new CompositeNodeWrapper(getNamespaceFor(childName),
+            final CompositeNodeWrapper child = new CompositeNodeWrapper(getNamespaceFor(childName),
                     getLocalNameFor(childName));
             parent.addValue(child);
-            for (Entry<String, JsonElement> childOfChild : childType.getAsJsonObject().entrySet()) {
+            for (final Entry<String, JsonElement> childOfChild : childType.getAsJsonObject().entrySet()) {
                 addChildToParent(childOfChild.getKey(), childOfChild.getValue(), child);
             }
         } else if (childType.isJsonArray()) {
@@ -99,13 +103,13 @@ class JsonToCompositeNodeReader {
                 parent.addValue(new EmptyNodeWrapper(getNamespaceFor(childName), getLocalNameFor(childName)));
 
             } else {
-                for (JsonElement childOfChildType : childType.getAsJsonArray()) {
+                for (final JsonElement childOfChildType : childType.getAsJsonArray()) {
                     addChildToParent(childName, childOfChildType, parent);
                 }
             }
         } else if (childType.isJsonPrimitive()) {
-            JsonPrimitive childPrimitive = childType.getAsJsonPrimitive();
-            String value = childPrimitive.getAsString().trim();
+            final JsonPrimitive childPrimitive = childType.getAsJsonPrimitive();
+            final String value = childPrimitive.getAsString().trim();
             parent.addValue(new SimpleNodeWrapper(getNamespaceFor(childName), getLocalNameFor(childName),
                     resolveValueOfElement(value)));
         } else {
@@ -133,7 +137,7 @@ class JsonToCompositeNodeReader {
             if (Iterators.size(it) == 1) {
                 try {
                     return URI.create(maybeURI);
-                } catch (IllegalArgumentException e) {
+                } catch (final IllegalArgumentException e) {
                     LOG.debug("Value {} couldn't be interpreted as URI.", maybeURI);
                 }
             }
@@ -153,14 +157,14 @@ class JsonToCompositeNodeReader {
     private static Object resolveValueOfElement(final String value) {
         // it could be instance-identifier Built-In Type
         if (!value.isEmpty() && value.charAt(0) == '/') {
-            IdentityValuesDTO resolvedValue = RestUtil.asInstanceIdentifier(value, new PrefixMapingFromJson());
+            final IdentityValuesDTO resolvedValue = RestUtil.asInstanceIdentifier(value, new PrefixMapingFromJson());
             if (resolvedValue != null) {
                 return resolvedValue;
             }
         }
 
         // it could be identityref Built-In Type therefore it is necessary to look at value as module_name:local_name
-        URI namespace = getNamespaceFor(value);
+        final URI namespace = getNamespaceFor(value);
         if (namespace != null) {
             return new IdentityValuesDTO(namespace.toString(), getLocalNameFor(value), null, value);
         }
index c9496af4c86d4838b6ee570e26b2b84ac8c34e26..9ab8fa84010753ee039b4a55c0a4104ebb0415a2 100644 (file)
@@ -11,6 +11,9 @@ import com.google.common.collect.ImmutableSet;
 import java.util.HashSet;
 import java.util.Set;
 import javax.ws.rs.core.Application;
+import org.opendaylight.controller.md.sal.rest.schema.SchemaExportContentYangBodyWriter;
+import org.opendaylight.controller.md.sal.rest.schema.SchemaExportContentYinBodyWriter;
+import org.opendaylight.controller.md.sal.rest.schema.SchemaRetrievalServiceImpl;
 import org.opendaylight.controller.sal.restconf.impl.BrokerFacade;
 import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
 import org.opendaylight.controller.sal.restconf.impl.RestconfImpl;
@@ -26,20 +29,24 @@ public class RestconfApplication extends Application {
                 .add(JsonNormalizedNodeBodyReader.class)
                 .add(NormalizedNodeJsonBodyWriter.class)
                 .add(NormalizedNodeXmlBodyWriter.class)
+                .add(SchemaExportContentYinBodyWriter.class)
+                .add(SchemaExportContentYangBodyWriter.class)
                 .build();
     }
 
     @Override
     public Set<Object> getSingletons() {
-        Set<Object> singletons = new HashSet<>();
-        ControllerContext controllerContext = ControllerContext.getInstance();
-        BrokerFacade brokerFacade = BrokerFacade.getInstance();
-        RestconfImpl restconfImpl = RestconfImpl.getInstance();
+        final Set<Object> singletons = new HashSet<>();
+        final ControllerContext controllerContext = ControllerContext.getInstance();
+        final BrokerFacade brokerFacade = BrokerFacade.getInstance();
+        final RestconfImpl restconfImpl = RestconfImpl.getInstance();
+        final SchemaRetrievalServiceImpl schemaRetrieval = new SchemaRetrievalServiceImpl(controllerContext);
         restconfImpl.setBroker(brokerFacade);
         restconfImpl.setControllerContext(controllerContext);
         singletons.add(controllerContext);
         singletons.add(brokerFacade);
-        singletons.add(StatisticsRestconfServiceWrapper.getInstance());
+        singletons.add(schemaRetrieval);
+        singletons.add(new RestconfCompositeWrapper(StatisticsRestconfServiceWrapper.getInstance(), schemaRetrieval));
         singletons.add(StructuredDataToXmlProvider.INSTANCE);
         singletons.add(StructuredDataToJsonProvider.INSTANCE);
         singletons.add(JsonToCompositeNodeProvider.INSTANCE);
diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/RestconfCompositeWrapper.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/RestconfCompositeWrapper.java
new file mode 100644 (file)
index 0000000..d362006
--- /dev/null
@@ -0,0 +1,108 @@
+package org.opendaylight.controller.sal.rest.impl;
+
+import com.google.common.base.Preconditions;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+import org.opendaylight.controller.md.sal.rest.schema.SchemaExportContext;
+import org.opendaylight.controller.md.sal.rest.schema.SchemaRetrievalService;
+import org.opendaylight.controller.sal.rest.api.RestconfService;
+import org.opendaylight.controller.sal.restconf.impl.NormalizedNodeContext;
+import org.opendaylight.controller.sal.restconf.impl.StructuredData;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.Node;
+
+public class RestconfCompositeWrapper implements RestconfService, SchemaRetrievalService {
+
+    private final RestconfService restconf;
+    private final SchemaRetrievalService schema;
+
+    public RestconfCompositeWrapper(final RestconfService restconf, final SchemaRetrievalService schema) {
+        this.restconf = Preconditions.checkNotNull(restconf);
+        this.schema = Preconditions.checkNotNull(schema);
+    }
+
+    @Override
+    public Object getRoot() {
+        return restconf.getRoot();
+    }
+
+    @Override
+    public StructuredData getModules(final UriInfo uriInfo) {
+        return restconf.getModules(uriInfo);
+    }
+
+    @Override
+    public StructuredData getModules(final String identifier, final UriInfo uriInfo) {
+        return restconf.getModules(identifier, uriInfo);
+    }
+
+    @Override
+    public StructuredData getModule(final String identifier, final UriInfo uriInfo) {
+        return restconf.getModule(identifier, uriInfo);
+    }
+
+    @Override
+    public StructuredData getOperations(final UriInfo uriInfo) {
+        return restconf.getOperations(uriInfo);
+    }
+
+    @Override
+    public StructuredData getOperations(final String identifier, final UriInfo uriInfo) {
+        return restconf.getOperations(identifier, uriInfo);
+    }
+
+    @Override
+    public StructuredData invokeRpc(final String identifier, final CompositeNode payload, final UriInfo uriInfo) {
+        return restconf.invokeRpc(identifier, payload, uriInfo);
+    }
+
+    @Override
+    public StructuredData invokeRpc(final String identifier, final String noPayload, final UriInfo uriInfo) {
+        return restconf.invokeRpc(identifier, noPayload, uriInfo);
+    }
+
+    @Override
+    public NormalizedNodeContext readConfigurationData(final String identifier, final UriInfo uriInfo) {
+        return restconf.readConfigurationData(identifier, uriInfo);
+    }
+
+    @Override
+    public NormalizedNodeContext readOperationalData(final String identifier, final UriInfo uriInfo) {
+        return restconf.readOperationalData(identifier, uriInfo);
+    }
+
+    @Override
+    public Response updateConfigurationData(final String identifier, final Node<?> payload) {
+        return restconf.updateConfigurationData(identifier, payload);
+    }
+
+    @Override
+    public Response createConfigurationData(final String identifier, final Node<?> payload) {
+        return restconf.createConfigurationData(identifier, payload);
+    }
+
+    @Override
+    public Response createConfigurationData(final Node<?> payload) {
+        return restconf.createConfigurationData(payload);
+    }
+
+    @Override
+    public Response deleteConfigurationData(final String identifier) {
+        return restconf.deleteConfigurationData(identifier);
+    }
+
+    @Override
+    public Response subscribeToStream(final String identifier, final UriInfo uriInfo) {
+        return restconf.subscribeToStream(identifier, uriInfo);
+    }
+
+    @Override
+    public StructuredData getAvailableStreams(final UriInfo uriInfo) {
+        return restconf.getAvailableStreams(uriInfo);
+    }
+
+    @Override
+    public SchemaExportContext getSchema(final String mountId) {
+        return schema.getSchema(mountId);
+    }
+}
index 063d2f51afffdd0c7094d7363d95795182b5cd8e..13dbf266898e3260d7b6af7d0d056a98d9b20770 100644 (file)
@@ -28,6 +28,9 @@ import org.opendaylight.controller.sal.restconf.impl.StructuredData;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
 
+/**
+ * @deprecated class will be removed in Lithium release
+ */
 @Provider
 @Produces({ Draft02.MediaTypes.API + RestconfService.JSON, Draft02.MediaTypes.DATA + RestconfService.JSON,
     Draft02.MediaTypes.OPERATION + RestconfService.JSON, MediaType.APPLICATION_JSON })
@@ -48,19 +51,19 @@ public enum StructuredDataToJsonProvider implements MessageBodyWriter<Structured
     public void writeTo(final StructuredData t, final Class<?> type, final Type genericType, final Annotation[] annotations,
             final MediaType mediaType, final MultivaluedMap<String, Object> httpHeaders, final OutputStream entityStream)
                     throws IOException, WebApplicationException {
-        CompositeNode data = t.getData();
+        final CompositeNode data = t.getData();
         if (data == null) {
             throw new RestconfDocumentedException(Response.Status.NOT_FOUND);
         }
 
-        JsonWriter writer = new JsonWriter(new OutputStreamWriter(entityStream, Charsets.UTF_8));
+        final JsonWriter writer = new JsonWriter(new OutputStreamWriter(entityStream, Charsets.UTF_8));
 
         if (t.isPrettyPrintMode()) {
             writer.setIndent("    ");
         } else {
             writer.setIndent("");
         }
-        JsonMapper jsonMapper = new JsonMapper(t.getMountPoint());
+        final JsonMapper jsonMapper = new JsonMapper(t.getMountPoint());
         jsonMapper.write(writer, data, (DataNodeContainer) t.getSchema());
         writer.flush();
     }
index 703a2a463476bcfd4704c34419cc17c73a6af3fc..fcb7b1de913fd95faab60c60f0ca28e869056e88 100644 (file)
@@ -37,6 +37,9 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
 
+/**
+ * @deprecated class will be removed in Lithium release
+ */
 @Provider
 @Produces({ Draft02.MediaTypes.API + RestconfService.XML, Draft02.MediaTypes.DATA + RestconfService.XML,
         Draft02.MediaTypes.OPERATION + RestconfService.XML, MediaType.APPLICATION_XML, MediaType.TEXT_XML })
@@ -51,7 +54,7 @@ public enum StructuredDataToXmlProvider implements MessageBodyWriter<StructuredD
             final Transformer ret;
             try {
                 ret = FACTORY.newTransformer();
-            } catch (TransformerConfigurationException e) {
+            } catch (final TransformerConfigurationException e) {
                 LOG.error("Failed to instantiate XML transformer", e);
                 throw new IllegalStateException("XML encoding currently unavailable", e);
             }
@@ -83,7 +86,7 @@ public enum StructuredDataToXmlProvider implements MessageBodyWriter<StructuredD
             final Annotation[] annotations, final MediaType mediaType,
             final MultivaluedMap<String, Object> httpHeaders, final OutputStream entityStream) throws IOException,
             WebApplicationException {
-        CompositeNode data = t.getData();
+        final CompositeNode data = t.getData();
         if (data == null) {
             throw new RestconfDocumentedException(Response.Status.NOT_FOUND);
         }
@@ -96,7 +99,7 @@ public enum StructuredDataToXmlProvider implements MessageBodyWriter<StructuredD
             } else {
                 trans.setOutputProperty(OutputKeys.INDENT, "no");
             }
-        } catch (RuntimeException e) {
+        } catch (final RuntimeException e) {
             throw new RestconfDocumentedException(e.getMessage(), ErrorType.TRANSPORT, ErrorTag.OPERATION_FAILED);
         }
 
@@ -104,7 +107,7 @@ public enum StructuredDataToXmlProvider implements MessageBodyWriter<StructuredD
         final Document domTree = new XmlMapper().write(data, (DataNodeContainer) t.getSchema());
         try {
             trans.transform(new DOMSource(domTree), new StreamResult(entityStream));
-        } catch (TransformerException e) {
+        } catch (final TransformerException e) {
             LOG.error("Error during translation of Document to OutputStream", e);
             throw new RestconfDocumentedException(e.getMessage(), ErrorType.TRANSPORT, ErrorTag.OPERATION_FAILED);
         }
index d56a32e36ee084c7180b37e7d444f77fedded580..2ae8462e035ad2cbaff15ec6ee304dcc8fc1a671 100644 (file)
@@ -27,6 +27,9 @@ import org.opendaylight.yangtools.yang.data.api.Node;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+/**
+ * @deprecated class will be removed in Lithium release
+ */
 @Provider
 @Consumes({ Draft02.MediaTypes.DATA + RestconfService.XML, Draft02.MediaTypes.OPERATION + RestconfService.XML,
         MediaType.APPLICATION_XML, MediaType.TEXT_XML })
@@ -42,9 +45,9 @@ public enum XmlToCompositeNodeProvider implements MessageBodyReader<Node<?>> {
 
     @Override
     public Node<?> readFrom(final Class<Node<?>> type, final Type genericType, final Annotation[] annotations,
-            MediaType mediaType, MultivaluedMap<String, String> httpHeaders, InputStream entityStream)
+            final MediaType mediaType, final MultivaluedMap<String, String> httpHeaders, final InputStream entityStream)
             throws IOException, WebApplicationException {
-        XmlToCompositeNodeReader xmlReader = new XmlToCompositeNodeReader();
+        final XmlToCompositeNodeReader xmlReader = new XmlToCompositeNodeReader();
         try {
             return xmlReader.read(entityStream);
         } catch (XMLStreamException | UnsupportedFormatException e) {
index d71a12ff744c2b06b804a7d4a53487ec66739451..c9a09552adf331b85a123131733507abfcb629a5 100644 (file)
@@ -8,7 +8,6 @@
 package org.opendaylight.controller.sal.rest.impl;
 
 import static com.google.common.base.Preconditions.checkArgument;
-
 import java.io.BufferedInputStream;
 import java.io.IOException;
 import java.io.InputStream;
@@ -28,6 +27,9 @@ import org.opendaylight.controller.sal.restconf.impl.NodeWrapper;
 import org.opendaylight.controller.sal.restconf.impl.SimpleNodeWrapper;
 import org.opendaylight.yangtools.yang.data.api.Node;
 
+/**
+ * @deprecated class will be removed in Lithium release
+ */
 @Deprecated
 public class XmlToCompositeNodeReader {
 
@@ -50,7 +52,7 @@ public class XmlToCompositeNodeReader {
 
         eventReader = xmlInputFactory.createXMLEventReader(entityStream);
         if (eventReader.hasNext()) {
-            XMLEvent element = eventReader.peek();
+            final XMLEvent element = eventReader.peek();
             if (element.isStartDocument()) {
                 eventReader.nextEvent();
             }
@@ -126,7 +128,7 @@ public class XmlToCompositeNodeReader {
     private boolean isSimpleNodeEvent(final XMLEvent event) throws XMLStreamException {
         checkArgument(event != null, "XML Event cannot be NULL!");
         if (event.isStartElement()) {
-            XMLEvent innerEvent = skipCommentsAndWhitespace();
+            final XMLEvent innerEvent = skipCommentsAndWhitespace();
             if (innerEvent != null && (innerEvent.isCharacters() || innerEvent.isEndElement())) {
                 return true;
             }
@@ -137,7 +139,7 @@ public class XmlToCompositeNodeReader {
     private boolean isCompositeNodeEvent(final XMLEvent event) throws XMLStreamException {
         checkArgument(event != null, "XML Event cannot be NULL!");
         if (event.isStartElement()) {
-            XMLEvent innerEvent = skipCommentsAndWhitespace();
+            final XMLEvent innerEvent = skipCommentsAndWhitespace();
             if (innerEvent != null) {
                 if (innerEvent.isStartElement()) {
                     return true;
@@ -149,14 +151,14 @@ public class XmlToCompositeNodeReader {
 
     private XMLEvent skipCommentsAndWhitespace() throws XMLStreamException {
         while (eventReader.hasNext()) {
-            XMLEvent event = eventReader.peek();
+            final XMLEvent event = eventReader.peek();
             if (event.getEventType() == XMLStreamConstants.COMMENT) {
                 eventReader.nextEvent();
                 continue;
             }
 
             if (event.isCharacters()) {
-                Characters chars = event.asCharacters();
+                final Characters chars = event.asCharacters();
                 if (chars.isWhiteSpace()) {
                     eventReader.nextEvent();
                     continue;
@@ -175,7 +177,7 @@ public class XmlToCompositeNodeReader {
     private NodeWrapper<? extends Node<?>> resolveSimpleNodeFromStartElement(final StartElement startElement)
             throws XMLStreamException {
         checkArgument(startElement != null, "Start Element cannot be NULL!");
-        String data = getValueOf(startElement);
+        final String data = getValueOf(startElement);
         if (data == null) {
             return new EmptyNodeWrapper(getNamespaceFor(startElement), getLocalNameFor(startElement));
         }
@@ -224,23 +226,23 @@ public class XmlToCompositeNodeReader {
     }
 
     private URI getNamespaceFor(final StartElement startElement) {
-        String namespaceURI = startElement.getName().getNamespaceURI();
+        final String namespaceURI = startElement.getName().getNamespaceURI();
         return namespaceURI.isEmpty() ? null : URI.create(namespaceURI);
     }
 
     private Object resolveValueOfElement(final String value, final StartElement startElement) {
         // it could be instance-identifier Built-In Type
         if (value.startsWith("/")) {
-            IdentityValuesDTO iiValue = RestUtil.asInstanceIdentifier(value, new RestUtil.PrefixMapingFromXml(
+            final IdentityValuesDTO iiValue = RestUtil.asInstanceIdentifier(value, new RestUtil.PrefixMapingFromXml(
                     startElement));
             if (iiValue != null) {
                 return iiValue;
             }
         }
         // it could be identityref Built-In Type
-        String[] namespaceAndValue = value.split(":");
+        final String[] namespaceAndValue = value.split(":");
         if (namespaceAndValue.length == 2) {
-            String namespace = startElement.getNamespaceContext().getNamespaceURI(namespaceAndValue[0]);
+            final String namespace = startElement.getNamespaceContext().getNamespaceURI(namespaceAndValue[0]);
             if (namespace != null && !namespace.isEmpty()) {
                 return new IdentityValuesDTO(namespace, namespaceAndValue[1], namespaceAndValue[0], value);
             }
index 206dbdeab60a20dff4d13f9fbd3c96c68ac45b4d..c3edfccb9885392e187e1a6b692312893d6057cb 100644 (file)
@@ -23,6 +23,10 @@ import org.opendaylight.yangtools.yang.data.api.Node;
 import org.opendaylight.yangtools.yang.data.api.SimpleNode;
 import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
 
+/**
+ * @deprecated class will be removed in Lithium release
+ */
+@Deprecated
 public final class CompositeNodeWrapper implements NodeWrapper<CompositeNode>, CompositeNode {
 
     private MutableCompositeNode compositeNode;
@@ -102,8 +106,8 @@ public final class CompositeNodeWrapper implements NodeWrapper<CompositeNode>, C
                 name = new QName(namespace, localName);
             }
 
-            List<Node<?>> nodeValues = new ArrayList<>(values.size());
-            for (NodeWrapper<?> nodeWrapper : values) {
+            final List<Node<?>> nodeValues = new ArrayList<>(values.size());
+            for (final NodeWrapper<?> nodeWrapper : values) {
                 nodeValues.add(nodeWrapper.unwrap());
             }
             compositeNode = NodeFactory.createMutableCompositeNode(name, null, nodeValues, null, null);
index a3d44d3572106232e10edaad73e91d1b4d46039a..5a310e8af276811980617dd416b9b7cbe15c86d8 100644 (file)
@@ -15,6 +15,10 @@ import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.opendaylight.yangtools.yang.data.api.Node;
 import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
 
+/**
+ * @deprecated class will be removed in Lithium release
+ */
+@Deprecated
 public final class EmptyNodeWrapper implements NodeWrapper<Node<?>>, Node<Void> {
 
     private Node<?> unwrapped;
index 9637a36268860e13e8ac296004089aed6c8ce825..09c7835ef6cf0a7b5cf637c9f3430ad566037aba 100644 (file)
@@ -11,6 +11,10 @@ import java.net.URI;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.Node;
 
+/**
+ * @deprecated class will be removed in Lithium release
+ */
+@Deprecated
 public interface NodeWrapper<T extends Node<?>> {
 
     void setQname(QName name);
index 854e9635cf3cde883d97bbcc28f29c99bbda5c9c..2f50fd2ef5add3f2f3702b386d94c174b7ac4964 100644 (file)
@@ -16,6 +16,10 @@ import org.opendaylight.yangtools.yang.data.api.MutableSimpleNode;
 import org.opendaylight.yangtools.yang.data.api.SimpleNode;
 import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
 
+/**
+ * @deprecated class will be removed in Lithium release
+ */
+@Deprecated
 public final class SimpleNodeWrapper implements NodeWrapper<SimpleNode<?>>, SimpleNode<Object> {
 
     private SimpleNode<Object> simpleNode;
index 29354349671943d2c3e67e16188c06ae9dd3bc55..be4ac992da76072db056d70db590327edb6c39ae 100644 (file)
@@ -11,6 +11,10 @@ import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 
+/**
+ * @deprecated class will be removed in Lithium release
+ */
+@Deprecated
 public class StructuredData {
 
     private final CompositeNode data;
@@ -27,7 +31,7 @@ public class StructuredData {
         this.data = data;
         this.schema = schema;
         this.mountPoint = mountPoint;
-        this.prettyPrintMode = preattyPrintMode;
+        prettyPrintMode = preattyPrintMode;
     }
 
     public CompositeNode getData() {
index 4ae4de18f30f80580f237951e1cb1568180b5bb3..ba7b2f20e44058d7b9af4663003d36e4654400ea 100644 (file)
@@ -17,7 +17,7 @@ import java.util.Map;
 import java.util.Map.Entry;
 import javax.management.ObjectName;
 import javax.management.openmbean.OpenType;
-import org.opendaylight.controller.config.util.ConfigRegistryClient;
+import org.opendaylight.controller.config.util.BeanReader;
 import org.opendaylight.controller.config.yangjmxgenerator.RuntimeBeanEntry;
 import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIfc;
 import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
@@ -46,9 +46,9 @@ public final class InstanceConfig {
     private final Map<String, AttributeIfc> yangToAttrConfig;
     private final String nullableDummyContainerName;
     private final Map<String, AttributeIfc> jmxToAttrConfig;
-    private final ConfigRegistryClient configRegistryClient;
+    private final BeanReader configRegistryClient;
 
-    public InstanceConfig(ConfigRegistryClient configRegistryClient, Map<String, AttributeIfc> yangNamesToAttributes,
+    public InstanceConfig(BeanReader configRegistryClient, Map<String, AttributeIfc> yangNamesToAttributes,
                           String nullableDummyContainerName) {
 
         this.yangToAttrConfig = yangNamesToAttributes;
index d736595719e8ac59247b65db130c5e490142e6ae..9c55953bbc853b01403eedb11eca38c828076762 100644 (file)
@@ -26,7 +26,7 @@ public enum Datastore {
             TransactionProvider transactionProvider) {
         switch (source) {
         case running:
-            return new RunningDatastoreQueryStrategy();
+            return new RunningDatastoreQueryStrategy(transactionProvider);
         case candidate:
             return new CandidateDatastoreQueryStrategy(transactionProvider);
         default:
index dd2ceaec193bf3b55df22bd6d129c9f69f0e508f..1f70a1e52df63b62118e8c97af6b4107c9f068b8 100644 (file)
@@ -54,13 +54,15 @@ public class DiscardChanges extends AbstractConfigNetconfOperation {
     protected Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws NetconfDocumentedException {
         fromXml(xml);
         try {
-            this.transactionProvider.abortTransaction();
-        } catch (final IllegalStateException e) {
+            if (transactionProvider.getTransaction().isPresent()) {
+                this.transactionProvider.abortTransaction();
+            }
+        } catch (final RuntimeException e) {
             LOG.warn("Abort failed: ", e);
             final Map<String, String> errorInfo = new HashMap<>();
             errorInfo
                     .put(ErrorTag.operation_failed.name(),
-                            "Operation failed. Use 'get-config' or 'edit-config' before triggering 'discard-changes' operation");
+                            "Abort failed.");
             throw new NetconfDocumentedException(e.getMessage(), e, ErrorType.application, ErrorTag.operation_failed,
                     ErrorSeverity.error, errorInfo);
         }
index ca6a8c46b95083652e064a23593ff00da8616813..bc84734190937a8882583b165a72fc521dbb535f 100644 (file)
@@ -20,6 +20,7 @@ import java.util.Set;
 import javax.management.InstanceNotFoundException;
 import javax.management.ObjectName;
 import org.opendaylight.controller.config.api.ValidationException;
+import org.opendaylight.controller.config.util.BeanReader;
 import org.opendaylight.controller.config.util.ConfigRegistryClient;
 import org.opendaylight.controller.config.util.ConfigTransactionClient;
 import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
@@ -262,7 +263,7 @@ public class EditConfig extends AbstractConfigNetconfOperation {
 
     public static Map<String/* Namespace from yang file */,
             Map<String /* Name of module entry from yang file */, ModuleConfig>> transformMbeToModuleConfigs
-    (final ConfigRegistryClient configRegistryClient, Map<String/* Namespace from yang file */,
+    (final BeanReader configRegistryClient, Map<String/* Namespace from yang file */,
                     Map<String /* Name of module entry from yang file */, ModuleMXBeanEntry>> mBeanEntries) {
 
         Map<String, Map<String, ModuleConfig>> namespaceToModuleNameToModuleConfig = Maps.newHashMap();
@@ -295,7 +296,6 @@ public class EditConfig extends AbstractConfigNetconfOperation {
 
     @Override
     protected Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws NetconfDocumentedException {
-
         EditConfigXmlParser.EditConfigExecution editConfigExecution;
         Config cfg = getConfigMapping(getConfigRegistryClient(), yangStoreSnapshot);
         editConfigExecution = editConfigXmlParser.fromXml(xml, cfg);
index 27d53cdc32c400718da6c2da3a71057a76db063c..fe7f2773cd3e0c37c04e6b93d3a83e67e676767e 100644 (file)
@@ -14,6 +14,7 @@ import java.util.Map;
 import java.util.Set;
 import javax.management.ObjectName;
 import org.opendaylight.controller.config.util.ConfigRegistryClient;
+import org.opendaylight.controller.config.util.ConfigTransactionClient;
 import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
 import org.opendaylight.controller.config.yangjmxgenerator.RuntimeBeanEntry;
 import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
@@ -27,6 +28,7 @@ import org.opendaylight.controller.netconf.confignetconfconnector.operations.Abs
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.Datastore;
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfig;
 import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreContext;
+import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider;
 import org.opendaylight.controller.netconf.util.exception.MissingNameSpaceException;
 import org.opendaylight.controller.netconf.util.exception.UnexpectedElementException;
 import org.opendaylight.controller.netconf.util.exception.UnexpectedNamespaceException;
@@ -38,12 +40,14 @@ import org.w3c.dom.Element;
 
 public class Get extends AbstractConfigNetconfOperation {
 
+    private final TransactionProvider transactionProvider;
     private final YangStoreContext yangStoreSnapshot;
     private static final Logger LOG = LoggerFactory.getLogger(Get.class);
 
-    public Get(YangStoreContext yangStoreSnapshot, ConfigRegistryClient configRegistryClient,
+    public Get(final TransactionProvider transactionProvider, YangStoreContext yangStoreSnapshot, ConfigRegistryClient configRegistryClient,
                String netconfSessionIdForReporting) {
         super(configRegistryClient, netconfSessionIdForReporting);
+        this.transactionProvider = transactionProvider;
         this.yangStoreSnapshot = yangStoreSnapshot;
     }
 
@@ -115,23 +119,30 @@ public class Get extends AbstractConfigNetconfOperation {
     protected Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws NetconfDocumentedException {
         checkXml(xml);
 
-        final Set<ObjectName> runtimeBeans = getConfigRegistryClient().lookupRuntimeBeans();
+        final ObjectName testTransaction = transactionProvider.getOrCreateReadTransaction();
+        final ConfigTransactionClient registryClient = getConfigRegistryClient().getConfigTransactionClient(testTransaction);
 
-        //Transaction provider required only for candidate datastore
-        final Set<ObjectName> configBeans = Datastore.getInstanceQueryStrategy(Datastore.running, null)
-                .queryInstances(getConfigRegistryClient());
+        try {
+            // Runtime beans are not parts of transactions and have to be queried against the central registry
+            final Set<ObjectName> runtimeBeans = getConfigRegistryClient().lookupRuntimeBeans();
 
-        final Map<String, Map<String, ModuleRuntime>> moduleRuntimes = createModuleRuntimes(getConfigRegistryClient(),
-                yangStoreSnapshot.getModuleMXBeanEntryMap());
-        final Map<String, Map<String, ModuleConfig>> moduleConfigs = EditConfig.transformMbeToModuleConfigs(
-                getConfigRegistryClient(), yangStoreSnapshot.getModuleMXBeanEntryMap());
+            final Set<ObjectName> configBeans = Datastore.getInstanceQueryStrategy(Datastore.running, transactionProvider)
+                    .queryInstances(getConfigRegistryClient());
 
-        final Runtime runtime = new Runtime(moduleRuntimes, moduleConfigs);
+            final Map<String, Map<String, ModuleRuntime>> moduleRuntimes = createModuleRuntimes(getConfigRegistryClient(),
+                    yangStoreSnapshot.getModuleMXBeanEntryMap());
+            final Map<String, Map<String, ModuleConfig>> moduleConfigs = EditConfig.transformMbeToModuleConfigs(
+                    registryClient, yangStoreSnapshot.getModuleMXBeanEntryMap());
 
-        final Element element = runtime.toXml(runtimeBeans, configBeans, document);
+            final Runtime runtime = new Runtime(moduleRuntimes, moduleConfigs);
 
-        LOG.trace("{} operation successful", XmlNetconfConstants.GET);
+            final Element element = runtime.toXml(runtimeBeans, configBeans, document);
 
-        return element;
+            LOG.trace("{} operation successful", XmlNetconfConstants.GET);
+
+            return element;
+        } finally {
+            transactionProvider.closeReadTransaction();
+        }
     }
 }
index 350ace5eb1a44ac88bd60ac3fc338babcc4d22ae..2c4bde0ee8ffdaa3a57824fa23c89228a1f6345b 100644 (file)
@@ -72,23 +72,36 @@ public class GetConfig extends AbstractConfigNetconfOperation {
 
     private Element getResponseInternal(final Document document, final ConfigRegistryClient configRegistryClient,
             final Datastore source) {
-        Element dataElement = XmlUtil.createElement(document, XmlNetconfConstants.DATA_KEY, Optional.<String>absent());
-        final Set<ObjectName> instances = Datastore.getInstanceQueryStrategy(source, this.transactionProvider)
-                .queryInstances(configRegistryClient);
 
-        final Config configMapping = new Config(EditConfig.transformMbeToModuleConfigs(configRegistryClient,
-                yangStoreSnapshot.getModuleMXBeanEntryMap()));
-
-
-        ObjectName on = transactionProvider.getOrCreateTransaction();
-        ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(on);
-
-        ServiceRegistryWrapper serviceTracker = new ServiceRegistryWrapper(ta);
-        dataElement = configMapping.toXml(instances, this.maybeNamespace, document, dataElement, serviceTracker);
-
-        LOG.trace("{} operation successful", GET_CONFIG);
-
-        return dataElement;
+        final ConfigTransactionClient registryClient;
+        // Read current state from a transaction, if running is source, then start new transaction just for reading
+        // in case of candidate, get current transaction representing candidate
+        if(source == Datastore.running) {
+            final ObjectName readTx = transactionProvider.getOrCreateReadTransaction();
+            registryClient = getConfigRegistryClient().getConfigTransactionClient(readTx);
+        } else {
+            registryClient  = getConfigRegistryClient().getConfigTransactionClient(transactionProvider.getOrCreateTransaction());
+        }
+
+        try {
+            Element dataElement = XmlUtil.createElement(document, XmlNetconfConstants.DATA_KEY, Optional.<String>absent());
+            final Set<ObjectName> instances = Datastore.getInstanceQueryStrategy(source, this.transactionProvider)
+                    .queryInstances(configRegistryClient);
+
+            final Config configMapping = new Config(EditConfig.transformMbeToModuleConfigs(registryClient,
+                    yangStoreSnapshot.getModuleMXBeanEntryMap()));
+
+            ServiceRegistryWrapper serviceTracker = new ServiceRegistryWrapper(registryClient);
+            dataElement = configMapping.toXml(instances, this.maybeNamespace, document, dataElement, serviceTracker);
+
+            LOG.trace("{} operation successful", GET_CONFIG);
+
+            return dataElement;
+        } finally {
+            if(source == Datastore.running) {
+                transactionProvider.closeReadTransaction();
+            }
+        }
     }
 
     @Override
index ae9cb2eb379063fd5cb2d255d85e2e54ead45500..74b5f60a101c88467a9b180cf6bc0d3d4910c67e 100644 (file)
@@ -11,12 +11,22 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.ge
 import java.util.Set;
 import javax.management.ObjectName;
 import org.opendaylight.controller.config.util.ConfigRegistryClient;
+import org.opendaylight.controller.config.util.ConfigTransactionClient;
+import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider;
 
 public class RunningDatastoreQueryStrategy implements DatastoreQueryStrategy {
 
+    private final TransactionProvider transactionProvider;
+
+    public RunningDatastoreQueryStrategy(TransactionProvider transactionProvider) {
+        this.transactionProvider = transactionProvider;
+    }
+
     @Override
     public Set<ObjectName> queryInstances(ConfigRegistryClient configRegistryClient) {
-        return configRegistryClient.lookupConfigBeans();
+        ObjectName on = transactionProvider.getOrCreateReadTransaction();
+        ConfigTransactionClient proxy = configRegistryClient.getConfigTransactionClient(on);
+        return proxy.lookupConfigBeans();
     }
 
 }
index 612bd859983ec99d3432a2a32894ecd8ab6b5eee..e3fdc056d9d77d482adfe53aa513618ba720566e 100644 (file)
@@ -52,7 +52,7 @@ final class NetconfOperationProvider {
         ops.add(new Commit(transactionProvider, configRegistryClient, netconfSessionIdForReporting));
         ops.add(new Lock(netconfSessionIdForReporting));
         ops.add(new UnLock(netconfSessionIdForReporting));
-        ops.add(new Get(yangStoreSnapshot, configRegistryClient, netconfSessionIdForReporting));
+        ops.add(new Get(transactionProvider, yangStoreSnapshot, configRegistryClient, netconfSessionIdForReporting));
         ops.add(new DiscardChanges(transactionProvider, configRegistryClient, netconfSessionIdForReporting));
         ops.add(new Validate(transactionProvider, configRegistryClient, netconfSessionIdForReporting));
         ops.add(new RuntimeRpc(yangStoreSnapshot, configRegistryClient, netconfSessionIdForReporting));
index b2ee63a987836102fa31ae8c97e8dac899a33198..7655cb300db5a9f28238802e59db3cf3f6a54cff 100644 (file)
@@ -31,7 +31,8 @@ public class TransactionProvider implements AutoCloseable {
     private final ConfigRegistryClient configRegistryClient;
 
     private final String netconfSessionIdForReporting;
-    private ObjectName transaction;
+    private ObjectName candidateTx;
+    private ObjectName readTx;
     private final List<ObjectName> allOpenedTransactions = new ArrayList<>();
     private static final String  NO_TRANSACTION_FOUND_FOR_SESSION = "No transaction found for session ";
 
@@ -56,18 +57,34 @@ public class TransactionProvider implements AutoCloseable {
 
     public synchronized Optional<ObjectName> getTransaction() {
 
-        if (transaction == null){
+        if (candidateTx == null){
             return Optional.absent();
         }
 
         // Transaction was already closed somehow
-        if (!isStillOpenTransaction(transaction)) {
-            LOG.warn("Fixing illegal state: transaction {} was closed in {}", transaction,
+        if (!isStillOpenTransaction(candidateTx)) {
+            LOG.warn("Fixing illegal state: transaction {} was closed in {}", candidateTx,
                     netconfSessionIdForReporting);
-            transaction = null;
+            candidateTx = null;
             return Optional.absent();
         }
-        return Optional.of(transaction);
+        return Optional.of(candidateTx);
+    }
+
+    public synchronized Optional<ObjectName> getReadTransaction() {
+
+        if (readTx == null){
+            return Optional.absent();
+        }
+
+        // Transaction was already closed somehow
+        if (!isStillOpenTransaction(readTx)) {
+            LOG.warn("Fixing illegal state: transaction {} was closed in {}", readTx,
+                    netconfSessionIdForReporting);
+            readTx = null;
+            return Optional.absent();
+        }
+        return Optional.of(readTx);
     }
 
     private boolean isStillOpenTransaction(ObjectName transaction) {
@@ -80,9 +97,20 @@ public class TransactionProvider implements AutoCloseable {
         if (ta.isPresent()) {
             return ta.get();
         }
-        transaction = configRegistryClient.beginConfig();
-        allOpenedTransactions.add(transaction);
-        return transaction;
+        candidateTx = configRegistryClient.beginConfig();
+        allOpenedTransactions.add(candidateTx);
+        return candidateTx;
+    }
+
+    public synchronized ObjectName getOrCreateReadTransaction() {
+        Optional<ObjectName> ta = getReadTransaction();
+
+        if (ta.isPresent()) {
+            return ta.get();
+        }
+        readTx = configRegistryClient.beginConfig();
+        allOpenedTransactions.add(readTx);
+        return readTx;
     }
 
     /**
@@ -109,8 +137,8 @@ public class TransactionProvider implements AutoCloseable {
         try {
             CommitStatus status = configRegistryClient.commitConfig(taON);
             // clean up
-            allOpenedTransactions.remove(transaction);
-            transaction = null;
+            allOpenedTransactions.remove(candidateTx);
+            candidateTx = null;
             return status;
         } catch (ValidationException validationException) {
             // no clean up: user can reconfigure and recover this transaction
@@ -131,8 +159,19 @@ public class TransactionProvider implements AutoCloseable {
 
         ConfigTransactionClient transactionClient = configRegistryClient.getConfigTransactionClient(taON.get());
         transactionClient.abortConfig();
-        allOpenedTransactions.remove(transaction);
-        transaction = null;
+        allOpenedTransactions.remove(candidateTx);
+        candidateTx = null;
+    }
+
+    public synchronized void closeReadTransaction() {
+        LOG.debug("Closing read transaction");
+        Optional<ObjectName> taON = getReadTransaction();
+        Preconditions.checkState(taON.isPresent(), NO_TRANSACTION_FOUND_FOR_SESSION + netconfSessionIdForReporting);
+
+        ConfigTransactionClient transactionClient = configRegistryClient.getConfigTransactionClient(taON.get());
+        transactionClient.abortConfig();
+        allOpenedTransactions.remove(readTx);
+        readTx = null;
     }
 
     public synchronized void abortTestTransaction(ObjectName testTx) {
index b1222997fb8d944eeb6f4e4b489262e082698ecc..d6b5e62b27b59eb60e023c64603e56474145592d 100644 (file)
@@ -569,14 +569,14 @@ public class NetconfMappingTest extends AbstractConfigTest {
         commit();
     }
 
-    @Test(expected = NetconfDocumentedException.class)
+    @Test
     public void testEx2() throws Exception {
-        discard();
+        assertContainsElement(discard(), readXmlToElement("<ok xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"/>"));
     }
 
-    private void discard() throws ParserConfigurationException, SAXException, IOException, NetconfDocumentedException {
+    private Document discard() throws ParserConfigurationException, SAXException, IOException, NetconfDocumentedException {
         DiscardChanges discardOp = new DiscardChanges(transactionProvider, configRegistryClient, NETCONF_SESSION_ID);
-        executeOp(discardOp, "netconfMessages/discardChanges.xml");
+        return executeOp(discardOp, "netconfMessages/discardChanges.xml");
     }
 
     private void checkBinaryLeafEdited(final Document response) throws NodeTestException, SAXException, IOException {
@@ -716,7 +716,7 @@ public class NetconfMappingTest extends AbstractConfigTest {
     }
 
     private Document get() throws NetconfDocumentedException, ParserConfigurationException, SAXException, IOException {
-        Get getOp = new Get(yangStoreSnapshot, configRegistryClient, NETCONF_SESSION_ID);
+        Get getOp = new Get(transactionProvider, yangStoreSnapshot, configRegistryClient, NETCONF_SESSION_ID);
         return executeOp(getOp, "netconfMessages/get.xml");
     }
 
index 8e0ff5c859f101003f69ea4a4ed6b58daa6e3072..8325d84e3553cf660b17e00e352463faaff4bdf1 100644 (file)
@@ -14,6 +14,12 @@ import org.opendaylight.controller.networkconfig.neutron.INeutronObject;
 
 import java.util.List;
 
+/**
+ * This interface defines the methods for Neutron Requests
+ *
+ * @deprecated Replaced by {@link org.opendaylight.neutron.northbound.api.INeutronRequest}
+ */
+@Deprecated
 public interface INeutronRequest<T extends INeutronObject> {
     public T getSingleton();
     public boolean isSingleton();
index 9b4f579025e55340a8317d6cda20a0368c014e25..e0a59091f1c5c968d1c3c65233fb32bc3fc9c656 100644 (file)
@@ -11,8 +11,10 @@ package org.opendaylight.controller.networkconfig.neutron;
 /**
  * This interface defines the methods a service that wishes to be aware of Firewall Rules needs to implement
  *
+ * @deprecated Replaced by {@link org.opendaylight.neutron.neutron.spi.INeutronFirewallAware}
  */
 
+@Deprecated
 public interface INeutronFirewallAware {
 
     /**
index c986bffd6b6a72574e42374888e44dc9b87061ff..5e7fbb2090ca8bab3ba4ca8d018803053bb88eb0 100644 (file)
@@ -13,8 +13,10 @@ import java.util.List;
 /**
  * This interface defines the methods for CRUD of NB OpenStack Firewall objects
  *
+ * @deprecated Replaced by {@link org.opendaylight.neutron.neutron.spi.INeutronFirewallCRUD}
  */
 
+@Deprecated
 public interface INeutronFirewallCRUD {
     /**
      * Applications call this interface method to determine if a particular
index 203d513923c406c5fef5cca5e6eb2034312ffb1a..ba467834d4dccc78d0e287f32462231993ef5892 100644 (file)
@@ -11,8 +11,10 @@ package org.opendaylight.controller.networkconfig.neutron;
 /**
  * This interface defines the methods a service that wishes to be aware of Firewall Policys needs to implement
  *
+ * @deprecated Replaced by {@link org.opendaylight.neutron.neutron.spi.INeutronFirewallPolicyAware}
  */
 
+@Deprecated
 public interface INeutronFirewallPolicyAware {
 
     /**
index 6049656a6e309069f997adb755d7304faeb1a840..f280ff2266f63813a9ed09effd1aa1d2806aa3bf 100644 (file)
@@ -13,8 +13,10 @@ import java.util.List;
 /**
  * This interface defines the methods for CRUD of NB OpenStack Firewall Policy objects
  *
+ * @deprecated Replaced by {@link org.opendaylight.neutron.neutron.spi.INeutronFirewallPolicyCRUD}
  */
 
+@Deprecated
 public interface INeutronFirewallPolicyCRUD {
     /**
      * Applications call this interface method to determine if a particular
index a663058328f8fef01bc9ee74b436e4d03b837018..5863cdd0dc37f06e4928c8341a3abf2c509cde93 100644 (file)
@@ -11,8 +11,10 @@ package org.opendaylight.controller.networkconfig.neutron;
 /**
  * This interface defines the methods a service that wishes to be aware of Firewall Rules needs to implement
  *
+ * @deprecated Replaced by {@link org.opendaylight.neutron.neutron.spi.INeutronFirewallRuleAware}
  */
 
+@Deprecated
 public interface INeutronFirewallRuleAware {
 
     /**
index 990896bdb7249591cf90e4f2509e9be36cfa572f..b0c8c613c135c615a955062fcecfa1248a7596d7 100644 (file)
@@ -13,8 +13,10 @@ import java.util.List;
 /**
  * This interface defines the methods for CRUD of NB OpenStack Firewall Rule objects
  *
+ * @deprecated Replaced by {@link org.opendaylight.neutron.neutron.spi.INeutronFirewallRuleCRUD}
  */
 
+@Deprecated
 public interface INeutronFirewallRuleCRUD {
     /**
      * Applications call this interface method to determine if a particular
index 43175d3236455e1d3f9f4a5df23b3e3e290e9ac0..0a6c76ccb82c3b09835367e9411ffc9cde6e374c 100644 (file)
@@ -11,8 +11,10 @@ package org.opendaylight.controller.networkconfig.neutron;
 /**
  * This interface defines the methods a service that wishes to be aware of Neutron FloatingIPs needs to implement
  *
+ * @deprecated Replaced by {@link org.opendaylight.neutron.neutron.spi.INeutronFloatingIPAware}
  */
 
+@Deprecated
 public interface INeutronFloatingIPAware {
 
     /**
index e416ee7d2f31efb450fc4c6795a687c95eb25591..561e1dae730ba529a42cdb71e8f3512a8d83a3a4 100644 (file)
@@ -13,8 +13,10 @@ import java.util.List;
 /**
  * This interface defines the methods for CRUD of NB FloatingIP objects
  *
+ * @deprecated Replaced by {@link org.opendaylight.neutron.neutron.spi.INeutronFloatingIPCRUD}
  */
 
+@Deprecated
 public interface INeutronFloatingIPCRUD {
     /**
      * Applications call this interface method to determine if a particular
index e4aa5f382b2a152741169c0ebb6ea861240a5b9c..7202b01617ca553ec1814a6855a8a2cace1d6b1d 100644 (file)
@@ -11,8 +11,10 @@ package org.opendaylight.controller.networkconfig.neutron;
 /**
  * This interface defines the methods a service that wishes to be aware of LoadBalancer Rules needs to implement
  *
+ * @deprecated Replaced by {@link org.opendaylight.neutron.neutron.spi.INeutronLoadBalancerAware}
  */
 
+@Deprecated
 public interface INeutronLoadBalancerAware {
 
     /**
index a2ce41eab2b825b4d630ef49d2651e84d28dd5bc..394622fe6c5a6e43c66f4c9cb6f0ccfa3daf3869 100644 (file)
@@ -13,8 +13,10 @@ import java.util.List;
 /**
  * This interface defines the methods for CRUD of NB OpenStack LoadBalancer objects
  *
+ * @deprecated Replaced by {@link org.opendaylight.neutron.neutron.spi.INeutronLoadBalancerCRUD}
  */
 
+@Deprecated
 public interface INeutronLoadBalancerCRUD {
     /**
      * Applications call this interface method to determine if a particular
index 7194da32b4a4f4974b2b068a34a1cedc8df15744..2259435c9eb90f7064408e0db7373de0f5ac8288 100644 (file)
@@ -11,8 +11,10 @@ package org.opendaylight.controller.networkconfig.neutron;
 /**
  * This interface defines the methods a service that wishes to be aware of LoadBalancerHealthMonitor Rules needs to implement
  *
+ * @deprecated Replaced by {@link org.opendaylight.neutron.neutron.spi.INeutronLoadBalancerHealthMonitorAware}
  */
 
+@Deprecated
 public interface INeutronLoadBalancerHealthMonitorAware {
 
     /**
index 78380001dfa9e98faf6cbca5e38caf9031b3a726..f7b11a53aad24c84373a0567a0b882c872dde8f8 100644 (file)
@@ -13,8 +13,10 @@ import java.util.List;
 /**
  * This interface defines the methods for CRUD of NB OpenStack LoadBalancerHealthMonitor objects
  *
+ * @deprecated Replaced by {@link org.opendaylight.neutron.neutron.spi.INeutronLoadBalancerHealthMonitorCRUD}
  */
 
+@Deprecated
 public interface INeutronLoadBalancerHealthMonitorCRUD {
     /**
      * Applications call this interface method to determine if a particular
index 417419f93642d527626596a0418dfcab1ced1515..2043878905a6292218eee7738bf443073abf84cf 100644 (file)
@@ -11,8 +11,10 @@ package org.opendaylight.controller.networkconfig.neutron;
 /**
  * This interface defines the methods a service that wishes to be aware of LoadBalancerListener Rules needs to implement
  *
+ * @deprecated Replaced by {@link org.opendaylight.neutron.neutron.spi.INeutronLoadBalancerListenerAware}
  */
 
+@Deprecated
 public interface INeutronLoadBalancerListenerAware {
 
     /**
index c160f8ed8b6554da6431d96b1868863041eee08c..7336c76cd375098475c09deb3a5271e00e092dc9 100644 (file)
@@ -13,8 +13,10 @@ import java.util.List;
 /**
  * This interface defines the methods for CRUD of NB OpenStack LoadBalancerListener objects
  *
+ * @deprecated Replaced by {@link org.opendaylight.neutron.neutron.spi.INeutronLoadBalancerListenerCRUD}
  */
 
+@Deprecated
 public interface INeutronLoadBalancerListenerCRUD {
     /**
      * Applications call this interface method to determine if a particular
index 16c7d3716973b3d9e4b18d9ed60469e2469b24e5..851df355bb139e9bbd9f49c7d5df9d45f1ca8b22 100644 (file)
@@ -11,8 +11,10 @@ package org.opendaylight.controller.networkconfig.neutron;
 /**
  * This interface defines the methods a service that wishes to be aware of LoadBalancerPool Rules needs to implement
  *
+ * @deprecated Replaced by {@link org.opendaylight.neutron.neutron.spi.INeutronLoadBalancerPoolAware}
  */
 
+@Deprecated
 public interface INeutronLoadBalancerPoolAware {
 
     /**
index 9614448d065a56c3d4ce0ab965720ec94c18dbe9..7fabcd92423fa5a4b252b4202ed98cdc0dbd1190 100644 (file)
@@ -13,8 +13,10 @@ import java.util.List;
 /**
  * This interface defines the methods for CRUD of NB OpenStack LoadBalancerPool objects
  *
+ * @deprecated Replaced by {@link org.opendaylight.neutron.neutron.spi.INeutronLoadBalancerPoolCRUD}
  */
 
+@Deprecated
 public interface INeutronLoadBalancerPoolCRUD {
     /**
      * Applications call this interface method to determine if a particular
index 69a57748ddabc88212411cf6b4ecf3d088a80381..88a16cae4d5e9ae02da1cc8b025690eb17f7afb4 100644 (file)
@@ -7,6 +7,13 @@
  */
 package org.opendaylight.controller.networkconfig.neutron;
 
+/**
+ * This interface defines the methods for CRUD of NB OpenStack INeutronLoadBalancerPoolMemberAware objects
+ *
+ * @deprecated Replaced by {@link org.opendaylight.neutron.neutron.spi.INeutronLoadBalancerPoolMemberAware}
+ */
+
+@Deprecated
 public interface INeutronLoadBalancerPoolMemberAware {
 
 
index c1f5c7003ce87750d1cff33649e367eedbf94e4f..99b32169e18f25c6dc19ccfd61979f892f330e05 100644 (file)
@@ -10,6 +10,13 @@ package org.opendaylight.controller.networkconfig.neutron;
 
 import java.util.List;
 
+/**
+ * This interface defines the methods for CRUD of NB OpenStack INeutronLoadBalancerPoolMemberCRUD objects
+ *
+ * @deprecated Replaced by {@link org.opendaylight.neutron.neutron.spi.INeutronLoadBalancerPoolMemberCRUD}
+ */
+
+@Deprecated
 public interface INeutronLoadBalancerPoolMemberCRUD {
 
     /**
index 88d3c1dc6e84726842361add116002fd035ebb24..f5936a63a528c07e5e1427c4d2ff84f72bea9a3c 100644 (file)
@@ -11,8 +11,10 @@ package org.opendaylight.controller.networkconfig.neutron;
 /**
  * This interface defines the methods a service that wishes to be aware of Neutron Networks needs to implement
  *
+ * @deprecated Replaced by {@link org.opendaylight.neutron.neutron.spi.INeutronNetworkAware}
  */
 
+@Deprecated
 public interface INeutronNetworkAware {
 
     /**
index bf900a618f1057c5fbc8babc12635cbec7045d37..7f86536fd96850ef3a74d150ef155dfced1e6b4b 100644 (file)
@@ -13,8 +13,10 @@ import java.util.List;
 /**
  * This interface defines the methods for CRUD of NB network objects
  *
+ * @deprecated Replaced by {@link org.opendaylight.neutron.neutron.spi.INeutronNetworkCRUD}
  */
 
+@Deprecated
 public interface INeutronNetworkCRUD {
     /**
      * Applications call this interface method to determine if a particular
index bebac37c41732bf2bb102d698a2e13202f72302d..e39c07eadc2d67249a7a36e8080127ffcbe603d7 100644 (file)
@@ -12,7 +12,10 @@ package org.opendaylight.controller.networkconfig.neutron;
 
 /**
  * This class contains behaviour common to Neutron configuration objects
+ *
+ * @deprecated Replaced by {@link org.opendaylight.neutron.neutron.spi.INeutronObject}
  */
+@Deprecated
 public interface INeutronObject {
     public String getID();
     public void setID(String id);
index 3f40ba3879a84a2b8aa517f0baad66e2cf0c1672..3a14c308a2ba2cac1a1832c549c802dd1970945d 100644 (file)
@@ -11,8 +11,10 @@ package org.opendaylight.controller.networkconfig.neutron;
 /**
  * This interface defines the methods a service that wishes to be aware of Neutron Ports needs to implement
  *
+ * @deprecated Replaced by {@link org.opendaylight.neutron.neutron.spi.INeutronPortAware}
  */
 
+@Deprecated
 public interface INeutronPortAware {
 
     /**
index ce30c6806eea294c57bc637e3fb532377c3b21b4..58b007b65d2c784401f4419fa481deddb31786ee 100644 (file)
@@ -13,8 +13,10 @@ import java.util.List;
 /**
  * This interface defines the methods for CRUD of NB Port objects
  *
+ * @deprecated Replaced by {@link org.opendaylight.neutron.neutron.spi.INeutronPortCRUD}
  */
 
+@Deprecated
 public interface INeutronPortCRUD {
     /**
      * Applications call this interface method to determine if a particular
index 3c9e83d490c0e0d561077f42ad3903b1c11e93b9..f4c44343621cf52935f1258b7692fa473400f30a 100644 (file)
@@ -11,8 +11,10 @@ package org.opendaylight.controller.networkconfig.neutron;
 /**
  * This interface defines the methods a service that wishes to be aware of Neutron Routers needs to implement
  *
+ * @deprecated Replaced by {@link org.opendaylight.neutron.neutron.spi.INeutronRouterAware}
  */
 
+@Deprecated
 public interface INeutronRouterAware {
 
     /**
index b1a943fce1946e287271da2984206c84b3942bab..37b2c940e0fdf04cbb14eb3eb266d1738c21ce1d 100644 (file)
@@ -13,8 +13,10 @@ import java.util.List;
 /**
  * This interface defines the methods for CRUD of NB Router objects
  *
+ * @deprecated Replaced by {@link org.opendaylight.neutron.neutron.spi.INeutronRouterCRUD}
  */
 
+@Deprecated
 public interface INeutronRouterCRUD {
     /**
      * Applications call this interface method to determine if a particular
index 0fdf77f968708111a5dd3dd99a442843c762351e..b518924e195820494841a613f44e908b503f2c2a 100644 (file)
@@ -11,8 +11,11 @@ package org.opendaylight.controller.networkconfig.neutron;
 
 /**
  * This interface defines the methods a service that wishes to be aware of Neutron Security Groups needs to implement
+ *
+ * @deprecated Replaced by {@link org.opendaylight.neutron.neutron.spi.INeutronSecurityGroupAware}
  */
 
+@Deprecated
 public interface INeutronSecurityGroupAware {
 
     /**
index a408ef92a7be75bcfff59195a6f3c6632ac13292..6b20182eae46f6bc5b10214f8dac1f858bd86ae2 100644 (file)
@@ -13,8 +13,11 @@ import java.util.List;
 
 /**
  * This interface defines the methods for CRUD of NB OpenStack Security Group objects
+ *
+ * @deprecated Replaced by {@link org.opendaylight.neutron.neutron.spi.INeutronSecurityGroupCRUD}
  */
 
+@Deprecated
 public interface INeutronSecurityGroupCRUD {
     /**
      * Applications call this interface method to determine if a particular
index ff2a1c4978f6891998c098905439ec932daf76f0..3be9cc92b696c53ab706f450949e1d277f9753b1 100644 (file)
@@ -11,8 +11,11 @@ package org.opendaylight.controller.networkconfig.neutron;
 
 /**
  * This interface defines the methods required to be aware of Neutron Security Rules
+ *
+ * @deprecated Replaced by {@link org.opendaylight.neutron.neutron.spi.INeutronSecurityRuleAware}
  */
 
+@Deprecated
 public interface INeutronSecurityRuleAware {
 
     /**
index 73b41c71a4745b204028a04f3a54ea9850ad79b7..a5223b7e8d9167a28de13f111620149067cce9bf 100644 (file)
@@ -13,8 +13,11 @@ import java.util.List;
 
 /**
  * This interface defines the methods for CRUD of NB OpenStack Security Rule objects
+ *
+ * @deprecated Replaced by {@link org.opendaylight.neutron.neutron.spi.INeutronSecurityRuleCRUD}
  */
 
+@Deprecated
 public interface INeutronSecurityRuleCRUD {
     /**
      * Applications call this interface method to determine if a particular
index fa0707698d6a88208693bfb9233fd523b512c6de..57d382b127afbb76f2e7d5d0bbaf84ac61ad08c0 100644 (file)
@@ -11,8 +11,10 @@ package org.opendaylight.controller.networkconfig.neutron;
 /**
  * This interface defines the methods a service that wishes to be aware of Neutron Subnets needs to implement
  *
+ * @deprecated Replaced by {@link org.opendaylight.neutron.neutron.spi.INeutronSubnetAware}
  */
 
+@Deprecated
 public interface INeutronSubnetAware {
 
     /**
index 6f9a6ffb7b54850dce84b900ca08cadd57c00ce4..842068284810e07766c128b18da8371e37a77a9b 100644 (file)
@@ -13,8 +13,10 @@ import java.util.List;
 /**
  * This interface defines the methods for CRUD of NB Subnet objects
  *
+ * @deprecated Replaced by {@link org.opendaylight.neutron.neutron.spi.INeutronSubnetCRUD}
  */
 
+@Deprecated
 public interface INeutronSubnetCRUD {
     /**
      * Applications call this interface method to determine if a particular