Merge "CHange log level from warn to debug in ProtocolSessionPromise when connection...
authorTony Tkacik <ttkacik@cisco.com>
Mon, 17 Feb 2014 16:31:35 +0000 (16:31 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Mon, 17 Feb 2014 16:31:35 +0000 (16:31 +0000)
181 files changed:
opendaylight/arphandler/src/main/java/org/opendaylight/controller/arphandler/ARPReply.java
opendaylight/arphandler/src/main/java/org/opendaylight/controller/arphandler/ARPRequest.java
opendaylight/commons/opendaylight/pom.xml
opendaylight/config/config-manager/pom.xml
opendaylight/config/config-persister-directory-autodetect-adapter/pom.xml
opendaylight/config/config-persister-directory-xml-adapter/pom.xml
opendaylight/config/config-util/src/test/java/org/opendaylight/controller/config/util/ConfigRegistryClientsTest.java
opendaylight/config/netty-event-executor-config/pom.xml
opendaylight/config/netty-threadgroup-config/pom.xml
opendaylight/config/netty-timer-config/pom.xml
opendaylight/config/pom.xml
opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntry.java
opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntryBuilder.java [new file with mode: 0644]
opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/RuntimeBeanEntry.java
opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/TypeProviderWrapper.java
opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/AbstractAttribute.java
opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/TOAttribute.java
opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntryTest.java
opendaylight/config/yang-jmx-generator/src/test/resources/config-jmx-it-impl.yang
opendaylight/config/yang-test/pom.xml
opendaylight/configuration/api/src/main/java/org/opendaylight/controller/configuration/IConfigurationContainerService.java
opendaylight/configuration/implementation/src/main/java/org/opendaylight/controller/configuration/internal/ConfigurationService.java
opendaylight/configuration/implementation/src/main/java/org/opendaylight/controller/configuration/internal/ContainerConfigurationService.java
opendaylight/connectionmanager/implementation/pom.xml
opendaylight/containermanager/implementation/src/main/java/org/opendaylight/controller/containermanager/internal/ContainerManager.java
opendaylight/distribution/opendaylight/pom.xml
opendaylight/forwardingrulesmanager/implementation/pom.xml
opendaylight/md-sal/compatibility/flow-management-compatibility/pom.xml
opendaylight/md-sal/compatibility/inventory-topology-compatibility/pom.xml
opendaylight/md-sal/compatibility/pom.xml
opendaylight/md-sal/compatibility/sal-compatibility/pom.xml
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/ComponentActivator.xtend
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/FlowProgrammerAdapter.xtend
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/InventoryAndReadAdapter.xtend
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/InventoryNotificationProvider.java [new file with mode: 0644]
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/NodeConnectorDataChangeListener.java [new file with mode: 0644]
opendaylight/md-sal/forwardingrules-manager/pom.xml
opendaylight/md-sal/inventory-manager/pom.xml
opendaylight/md-sal/inventory-manager/src/main/java/org/opendaylight/controller/md/inventory/manager/FlowCapableInventoryProvider.xtend
opendaylight/md-sal/model/model-flow-management/pom.xml
opendaylight/md-sal/model/model-flow-statistics/pom.xml
opendaylight/md-sal/model/model-topology/pom.xml
opendaylight/md-sal/pom.xml
opendaylight/md-sal/sal-binding-api/pom.xml
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/RpcConsumerRegistry.java
opendaylight/md-sal/sal-binding-broker/pom.xml
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/DataBrokerImplModule.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/RuntimeMappingModule.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/SingletonHolder.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/DataBrokerImpl.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationBrokerImpl.xtend
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/RootBindingAwareBroker.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentConnector.java
opendaylight/md-sal/sal-binding-config/pom.xml
opendaylight/md-sal/sal-binding-dom-it/pom.xml
opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/PutAugmentationTest.java
opendaylight/md-sal/sal-binding-it/pom.xml
opendaylight/md-sal/sal-binding-util/pom.xml
opendaylight/md-sal/sal-common-api/pom.xml
opendaylight/md-sal/sal-common-api/src/main/java/org/opendaylight/controller/md/sal/common/api/TransactionStatus.java
opendaylight/md-sal/sal-common-impl/pom.xml
opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/routing/RoutingUtils.java
opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/service/AbstractDataBroker.java [new file with mode: 0644]
opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/service/AbstractDataBroker.xtend [deleted file]
opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/service/AbstractDataTransaction.java [new file with mode: 0644]
opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/service/DataChangeEventImpl.java
opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/service/DataChangeListenerRegistration.java [new file with mode: 0644]
opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/service/ImmutableDataChangeEvent.java [new file with mode: 0644]
opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/service/ListenerStateCapture.java [new file with mode: 0644]
opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/service/RootedChangeSet.java [new file with mode: 0644]
opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/service/TwoPhaseCommit.java [new file with mode: 0644]
opendaylight/md-sal/sal-common-util/pom.xml
opendaylight/md-sal/sal-connector-api/pom.xml
opendaylight/md-sal/sal-dom-api/pom.xml
opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/RpcProvisionRegistry.java
opendaylight/md-sal/sal-dom-broker/pom.xml
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/BrokerImpl.xtend
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/ConsumerContextImpl.xtend
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/MountPointImpl.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/SchemaAwareDataStoreAdapter.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/osgi/RpcProvisionRegistryProxy.java
opendaylight/md-sal/sal-dom-spi/pom.xml
opendaylight/md-sal/sal-netconf-connector/pom.xml
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceTwoPhaseCommitTransaction.java
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfMapping.xtend
opendaylight/md-sal/sal-remote/pom.xml
opendaylight/md-sal/sal-remote/src/main/java/org/opendaylight/controller/sal/restconf/service/impl/SalRemoteServiceImpl.java [deleted file]
opendaylight/md-sal/sal-rest-connector/pom.xml
opendaylight/md-sal/sal-restconf-broker/pom.xml
opendaylight/md-sal/sal-restconf-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationServiceImpl.java [deleted file]
opendaylight/md-sal/sal-restconf-broker/src/main/java/org/opendaylight/controller/sal/restconf/binding/impl/DataBrokerServiceImpl.java [moved from opendaylight/md-sal/sal-restconf-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/DataBrokerServiceImpl.java with 98% similarity]
opendaylight/md-sal/sal-restconf-broker/src/main/java/org/opendaylight/controller/sal/restconf/broker/SalRemoteServiceBroker.java
opendaylight/md-sal/sal-restconf-broker/src/main/java/org/opendaylight/controller/sal/restconf/broker/event/RemoteDataChangeEvent.java [new file with mode: 0644]
opendaylight/md-sal/sal-restconf-broker/src/main/java/org/opendaylight/controller/sal/restconf/broker/impl/DataBrokerServiceImpl.java [new file with mode: 0644]
opendaylight/md-sal/sal-restconf-broker/src/main/java/org/opendaylight/controller/sal/restconf/broker/impl/NotificationServiceImpl.java [new file with mode: 0644]
opendaylight/md-sal/sal-restconf-broker/src/main/java/org/opendaylight/controller/sal/restconf/broker/impl/RemoteServicesFactory.java [new file with mode: 0644]
opendaylight/md-sal/sal-restconf-broker/src/main/java/org/opendaylight/controller/sal/restconf/broker/impl/RpcConsumerRegistryImpl.java [moved from opendaylight/md-sal/sal-restconf-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/RpcConsumerRegistryImpl.java with 58% similarity]
opendaylight/md-sal/sal-restconf-broker/src/main/java/org/opendaylight/controller/sal/restconf/broker/listeners/RemoteDataChangeNotificationListener.java [new file with mode: 0644]
opendaylight/md-sal/sal-restconf-broker/src/main/java/org/opendaylight/controller/sal/restconf/broker/listeners/RemoteNotificationListener.java [new file with mode: 0644]
opendaylight/md-sal/sal-restconf-broker/src/main/java/org/opendaylight/controller/sal/restconf/broker/listeners/SalNotificationListener.java [new file with mode: 0644]
opendaylight/md-sal/sal-restconf-broker/src/main/java/org/opendaylight/controller/sal/restconf/broker/tools/RemoteStreamTools.java [new file with mode: 0644]
opendaylight/md-sal/sal-restconf-broker/src/main/java/org/opendaylight/controller/sal/restconf/broker/transactions/RemoteDataModificationTransaction.java [new file with mode: 0644]
opendaylight/md-sal/sal-restconf-broker/src/test/java/org/opendaylight/controller/sal/binding/impl/test/DataBrokerImplTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-restconf-broker/src/test/java/org/opendaylight/controller/sal/binding/impl/test/NotificationServiceImplTest.java [new file with mode: 0644]
opendaylight/md-sal/samples/toaster-consumer/pom.xml
opendaylight/md-sal/samples/toaster-provider/pom.xml
opendaylight/md-sal/statistics-manager/pom.xml
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/AbstractListeningStatsTracker.java [new file with mode: 0644]
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/AbstractStatsTracker.java [new file with mode: 0644]
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowCapableContext.java [new file with mode: 0644]
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowCapableTracker.java [new file with mode: 0644]
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowStatsEntry.java [new file with mode: 0644]
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowStatsTracker.java [new file with mode: 0644]
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowTableStatsTracker.java [new file with mode: 0644]
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/GroupDescStatsTracker.java [new file with mode: 0644]
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/GroupStatsTracker.java [new file with mode: 0644]
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/MeterConfigStatsTracker.java [new file with mode: 0644]
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/MeterStatsTracker.java [new file with mode: 0644]
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/MultipartMessageManager.java
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/NodeConnectorStatsTracker.java [new file with mode: 0644]
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/NodeStatisticsHandler.java
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/QueueStatsEntry.java [new file with mode: 0644]
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/QueueStatsTracker.java [new file with mode: 0644]
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/RPCFailedException.java [new file with mode: 0644]
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsListener.java
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsManagerActivator.java
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsProvider.java
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsUpdateHandler.java [deleted file]
opendaylight/md-sal/topology-lldp-discovery/pom.xml
opendaylight/md-sal/topology-manager/pom.xml
opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/ConfigPusher.java
opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/NetconfMessage.java
opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClientDispatcher.java
opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClientSessionNegotiator.java
opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClientSessionNegotiatorFactory.java
opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfSshClientDispatcher.java
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerDispatcher.java
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSession.java
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionNegotiator.java
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionNegotiatorFactory.java
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/util/AdditionalHeaderUtil.java [deleted file]
opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/AdditionalHeaderParserTest.java
opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/ConcurrentClientsTest.java
opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/MonitoringConstants.java
opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/xml/model/MonitoringSession.java
opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/xml/model/package-info.java
opendaylight/netconf/netconf-monitoring/src/test/java/org/opendaylight/controller/netconf/monitoring/xml/JaxBSerializerTest.java
opendaylight/netconf/netconf-ssh/pom.xml
opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/AuthProvider.java
opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/threads/IOThread.java
opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/threads/SocketThread.java
opendaylight/netconf/netconf-ssh/src/test/java/org/opendaylight/controller/netconf/StubUserManager.java
opendaylight/netconf/netconf-util/pom.xml
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/AbstractChannelInitializer.java
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/AbstractNetconfSessionNegotiator.java
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/NetconfHelloMessageToXMLEncoder.java [new file with mode: 0644]
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/NetconfMessageToXMLEncoder.java
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/NetconfXMLToHelloMessageDecoder.java [new file with mode: 0644]
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/NetconfXMLToMessageDecoder.java
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/messages/NetconfHelloMessage.java [new file with mode: 0644]
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/messages/NetconfHelloMessageAdditionalHeader.java [new file with mode: 0644]
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/messages/NetconfMessageAdditionalHeader.java [deleted file]
opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/messages/NetconfMessageFactoryTest.java
opendaylight/northbound/connectionmanager/pom.xml
opendaylight/northbound/containermanager/pom.xml
opendaylight/northbound/controllermanager/pom.xml
opendaylight/northbound/flowprogrammer/pom.xml
opendaylight/northbound/hosttracker/pom.xml
opendaylight/northbound/java-client/pom.xml
opendaylight/northbound/networkconfiguration/bridgedomain/pom.xml
opendaylight/northbound/statistics/pom.xml
opendaylight/northbound/subnets/pom.xml
opendaylight/northbound/switchmanager/pom.xml
opendaylight/northbound/topology/pom.xml
opendaylight/northbound/usermanager/pom.xml
opendaylight/sal/implementation/pom.xml
opendaylight/samples/northbound/loadbalancer/pom.xml
opendaylight/samples/simpleforwarding/src/main/java/org/opendaylight/controller/samples/simpleforwarding/internal/SimpleBroadcastHandlerImpl.java
opendaylight/statisticsmanager/implementation/src/main/java/org/opendaylight/controller/statisticsmanager/internal/StatisticsManager.java
opendaylight/switchmanager/implementation/src/main/java/org/opendaylight/controller/switchmanager/internal/SwitchManager.java
opendaylight/web/flows/src/main/resources/js/page.js

index e4388c5..a6ee60f 100644 (file)
@@ -18,7 +18,7 @@ import org.opendaylight.controller.sal.utils.HexEncode;
  * ARP Reply event wrapper
  */
 public class ARPReply extends ARPEvent {
-
+    private static final long serialVersionUID = 1L;
     private final NodeConnector port;
     private final byte[] tMac;
     private final byte[] sMac;
index 1b125dd..051635a 100644 (file)
@@ -19,6 +19,7 @@ import org.opendaylight.controller.switchmanager.Subnet;
  * specified host
  */
 public class ARPRequest extends ARPEvent {
+    private static final long serialVersionUID = 1L;
     private final Subnet subnet;
     private final HostNodeConnector host;
 
index 93845a3..0d74b99 100644 (file)
        <artifactId>ietf-topology</artifactId>
        <version>${ietf-topology.version}</version>
       </dependency>
+      <dependency>
+       <groupId>org.opendaylight.yangtools.model</groupId>
+       <artifactId>ietf-topology-l3-unicast-igp</artifactId>
+       <version>${ietf-topology.version}</version>
+      </dependency>
       <dependency>
        <groupId>org.opendaylight.yangtools.model</groupId>
        <artifactId>opendaylight-l2-types</artifactId>
         <artifactId>concepts</artifactId>
         <version>${yangtools.version}</version>
       </dependency>
+      <dependency>
+        <groupId>org.opendaylight.yangtools</groupId>
+        <artifactId>restconf-client-api</artifactId>
+        <version>${yangtools.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.opendaylight.yangtools</groupId>
+        <artifactId>restconf-client-impl</artifactId>
+        <version>${yangtools.version}</version>
+      </dependency>
 
         <!--Netty-->
         <dependency>
           <artifactId>sal-binding-broker-impl</artifactId>
           <version>${mdsal.version}</version>
         </dependency>
+        <dependency>
+          <groupId>org.opendaylight.controller</groupId>
+          <artifactId>sal-binding-broker-impl</artifactId>
+          <version>${mdsal.version}</version>
+          <type>test-jar</type>
+          <scope>test</scope>
+        </dependency>
         <dependency>
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>sal-compatibility</artifactId>
           <artifactId>statistics-manager</artifactId>
           <version>${mdsal.version}</version>
         </dependency>
+        <dependency>
+          <groupId>org.opendaylight.controller</groupId>
+          <artifactId>sal-remote</artifactId>
+          <version>${mdsal.version}</version>
+        </dependency>
+        <dependency>
+          <groupId>org.opendaylight.controller</groupId>
+          <artifactId>sal-restconf-broker</artifactId>
+          <version>${mdsal.version}</version>
+        </dependency>
+        <dependency>
+          <groupId>org.opendaylight.controller</groupId>
+          <artifactId>sal-binding-util</artifactId>
+          <version>${mdsal.version}</version>
+        </dependency>
         <dependency>
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>concepts</artifactId>
           <artifactId>config-persister-impl</artifactId>
           <version>${netconf.version}</version>
         </dependency>
+        <dependency>
+          <groupId>${project.groupId}</groupId>
+          <artifactId>ietf-netconf-monitoring</artifactId>
+          <version>${netconf.version}</version>
+        </dependency>
+        <dependency>
+          <groupId>${project.groupId}</groupId>
+          <artifactId>ietf-netconf-monitoring-extension</artifactId>
+          <version>${netconf.version}</version>
+        </dependency>
 
          <!-- threadpool -->
           <dependency>
index f50f769..52377ae 100644 (file)
         <dependency>
             <groupId>org.opendaylight.yangtools</groupId>
             <artifactId>concepts</artifactId>
-            <version>${yangtools.version}</version>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.yangtools</groupId>
             <artifactId>yang-data-impl</artifactId>
-            <version>${yangtools.version}</version>
         </dependency>
     </dependencies>
 
index 301f00f..92f7e27 100644 (file)
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>config-persister-directory-adapter</artifactId>
-            <version>${config.version}</version>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>config-persister-directory-xml-adapter</artifactId>
-            <version>${config.version}</version>
         </dependency>
 
         <dependency>
index 36fa530..2c5d235 100644 (file)
@@ -28,7 +28,6 @@
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>config-persister-file-xml-adapter</artifactId>
-            <version>${config.version}</version>
         </dependency>
 
         <dependency>
index 4c99c77..1304345 100644 (file)
@@ -47,7 +47,7 @@ public class ConfigRegistryClientsTest {
     @Test
     public void testLookupRuntimeBeans() throws Exception {
         Set<ObjectName> jmxLookup = lookupRuntimeBeans(jmxRegistryClient);
-        assertEquals(Sets.newHashSet(testingRegistry.run2, testingRegistry.run1, testingRegistry.run3), jmxLookup);
+        assertEquals(Sets.newHashSet(TestingConfigRegistry.run2, TestingConfigRegistry.run1, TestingConfigRegistry.run3), jmxLookup);
     }
 
     private Set<ObjectName> lookupRuntimeBeans(ConfigRegistryClient client)
@@ -67,13 +67,13 @@ public class ConfigRegistryClientsTest {
                 jmxRegistryClient, TestingConfigRegistry.moduleName1,
                 TestingConfigRegistry.instName1);
         assertEquals(1, jmxLookup.size());
-        assertEquals(Sets.newHashSet(testingRegistry.run2), jmxLookup);
+        assertEquals(Sets.newHashSet(TestingConfigRegistry.run2), jmxLookup);
 
         jmxLookup = clientLookupRuntimeBeansWithModuleAndInstance(
                 jmxRegistryClient, TestingConfigRegistry.moduleName2,
                 TestingConfigRegistry.instName2);
         assertEquals(1, jmxLookup.size());
-        assertEquals(Sets.newHashSet(testingRegistry.run3), jmxLookup);
+        assertEquals(Sets.newHashSet(TestingConfigRegistry.run3), jmxLookup);
 
         jmxLookup = clientLookupRuntimeBeansWithModuleAndInstance(
                 jmxRegistryClient, TestingConfigRegistry.moduleName1,
index c1e0cca..88afa13 100644 (file)
@@ -24,7 +24,6 @@
       <dependency>
          <groupId>org.opendaylight.controller</groupId>
          <artifactId>netty-config-api</artifactId>
-         <version>${project.version}</version>
       </dependency>
       <dependency>
          <groupId>org.slf4j</groupId>
index 2e7777f..172fe7f 100644 (file)
@@ -26,7 +26,6 @@
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>netty-config-api</artifactId>
-            <version>${project.version}</version>
         </dependency>
         <dependency>
             <groupId>org.slf4j</groupId>
index 1e0c917..9d3b550 100644 (file)
       <dependency>
          <groupId>org.opendaylight.controller</groupId>
          <artifactId>netty-config-api</artifactId>
-         <version>${project.version}</version>
       </dependency>
       <dependency>
          <groupId>org.opendaylight.controller</groupId>
          <artifactId>threadpool-config-api</artifactId>
-         <version>${project.version}</version>
       </dependency>
       <dependency>
          <groupId>org.slf4j</groupId>
@@ -65,7 +63,6 @@
       <dependency>
          <groupId>org.opendaylight.controller</groupId>
          <artifactId>threadpool-config-impl</artifactId>
-         <version>${project.version}</version>
          <scope>test</scope>
       </dependency>
 
index 80621a4..3474740 100644 (file)
@@ -80,7 +80,6 @@
         <dependency>
             <groupId>ch.qos.logback</groupId>
             <artifactId>logback-classic</artifactId>
-            <version>${logback.version}</version>
             <scope>test</scope>
         </dependency>
     </dependencies>
             </plugins>
         </pluginManagement>
     </build>
-</project>
\ No newline at end of file
+</project>
index 5bcc540..0cc950a 100644 (file)
@@ -7,52 +7,16 @@
  */
 package org.opendaylight.controller.config.yangjmxgenerator;
 
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Optional;
-import com.google.common.collect.Sets;
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import org.opendaylight.controller.config.yangjmxgenerator.attribute.AbstractDependencyAttribute;
+
 import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIfc;
-import org.opendaylight.controller.config.yangjmxgenerator.attribute.DependencyAttribute;
-import org.opendaylight.controller.config.yangjmxgenerator.attribute.JavaAttribute;
-import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListAttribute;
-import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListDependenciesAttribute;
-import org.opendaylight.controller.config.yangjmxgenerator.attribute.TOAttribute;
 import org.opendaylight.controller.config.yangjmxgenerator.plugin.util.FullyQualifiedNameHelper;
-import org.opendaylight.controller.config.yangjmxgenerator.plugin.util.NameConflictException;
-import org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil;
 import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
-import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
-import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
-import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.api.ModuleImport;
-import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.api.SchemaNode;
-import org.opendaylight.yangtools.yang.model.api.SchemaPath;
-import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.UsesNode;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkState;
-import static java.lang.String.format;
-import static org.opendaylight.controller.config.yangjmxgenerator.ConfigConstants.createConfigQName;
 
 /**
  * Represents part of yang model that describes a module.
@@ -96,67 +60,34 @@ import static org.opendaylight.controller.config.yangjmxgenerator.ConfigConstant
  * </p>
  */
 public class ModuleMXBeanEntry extends AbstractEntry {
-    private static final Logger logger = LoggerFactory
-            .getLogger(ModuleMXBeanEntry.class);
-
-    // TODO: the XPath should be parsed by code generator IMO
-    private static final String MAGIC_STRING = "MAGIC_STRING";
-    private static final String MODULE_CONDITION_XPATH_TEMPLATE = "^/MAGIC_STRING:modules/MAGIC_STRING:module/MAGIC_STRING:type\\s*=\\s*['\"](.+)['\"]$";
-    private static final SchemaPath expectedConfigurationAugmentationSchemaPath = new SchemaPath(
-            Arrays.asList(createConfigQName("modules"),
-                    createConfigQName("module"),
-                    createConfigQName("configuration")), true);
-    private static final SchemaPath expectedStateAugmentationSchemaPath = new SchemaPath(
-            Arrays.asList(createConfigQName("modules"),
-                    createConfigQName("module"), createConfigQName("state")),
-            true);
-
-    private static final Pattern PREFIX_COLON_LOCAL_NAME = Pattern
-            .compile("^(.+):(.+)$");
 
     private static final String MODULE_SUFFIX = "Module";
     private static final String FACTORY_SUFFIX = MODULE_SUFFIX + "Factory";
     private static final String CLASS_NAME_SUFFIX = MODULE_SUFFIX + "MXBean";
     private static final String ABSTRACT_PREFIX = "Abstract";
 
-    /*
-     * threadpool-dynamic from the example above, taken from when condition, not
-     * the case name
-     */
-    private final String globallyUniqueName;
+    private final ModuleMXBeanEntryInitial initial;
 
     private Map<String, AttributeIfc> yangToAttributes;
 
-    private final String nullableDescription, packageName, javaNamePrefix,
-            namespace;
-
     private final Map<String, QName> providedServices;
 
     private Collection<RuntimeBeanEntry> runtimeBeans;
-    private final QName yangModuleQName;
-
-    public ModuleMXBeanEntry(IdentitySchemaNode id,
-            Map<String, AttributeIfc> yangToAttributes, String packageName,
-            Map<String, QName> providedServices2, String javaNamePrefix,
-            String namespace, Collection<RuntimeBeanEntry> runtimeBeans,
-            QName yangModuleQName) {
-        this.globallyUniqueName = id.getQName().getLocalName();
+
+    ModuleMXBeanEntry(ModuleMXBeanEntryInitial initials, Map<String, AttributeIfc> yangToAttributes,
+            Map<String, QName> providedServices2, Collection<RuntimeBeanEntry> runtimeBeans) {
         this.yangToAttributes = yangToAttributes;
-        this.nullableDescription = id.getDescription();
-        this.packageName = packageName;
-        this.javaNamePrefix = checkNotNull(javaNamePrefix);
-        this.namespace = checkNotNull(namespace);
         this.providedServices = Collections.unmodifiableMap(providedServices2);
         this.runtimeBeans = runtimeBeans;
-        this.yangModuleQName = yangModuleQName;
+        this.initial = initials;
     }
 
     public String getMXBeanInterfaceName() {
-        return javaNamePrefix + CLASS_NAME_SUFFIX;
+        return initial.javaNamePrefix + CLASS_NAME_SUFFIX;
     }
 
     public String getStubFactoryName() {
-        return javaNamePrefix + FACTORY_SUFFIX;
+        return initial.javaNamePrefix + FACTORY_SUFFIX;
     }
 
     public String getAbstractFactoryName() {
@@ -164,7 +95,7 @@ public class ModuleMXBeanEntry extends AbstractEntry {
     }
 
     public String getStubModuleName() {
-        return javaNamePrefix + MODULE_SUFFIX;
+        return initial.javaNamePrefix + MODULE_SUFFIX;
     }
 
     public String getAbstractModuleName() {
@@ -172,16 +103,16 @@ public class ModuleMXBeanEntry extends AbstractEntry {
     }
 
     public String getFullyQualifiedName(String typeName) {
-        return FullyQualifiedNameHelper.getFullyQualifiedName(packageName,
+        return FullyQualifiedNameHelper.getFullyQualifiedName(initial.packageName,
                 typeName);
     }
 
     public String getGloballyUniqueName() {
-        return globallyUniqueName;
+        return initial.localName;
     }
 
     public String getPackageName() {
-        return packageName;
+        return initial.packageName;
     }
 
     /**
@@ -202,31 +133,11 @@ public class ModuleMXBeanEntry extends AbstractEntry {
     }
 
     public String getJavaNamePrefix() {
-        return javaNamePrefix;
+        return initial.javaNamePrefix;
     }
 
     public String getNamespace() {
-        return namespace;
-    }
-
-    @VisibleForTesting
-    static Matcher getWhenConditionMatcher(String prefix,
-            RevisionAwareXPath whenConstraint) {
-        String xpathRegex = MODULE_CONDITION_XPATH_TEMPLATE.replace(
-                MAGIC_STRING, prefix);
-        Pattern pattern = Pattern.compile(xpathRegex);
-        return pattern.matcher(whenConstraint.toString());
-    }
-
-    static String getConfigModulePrefixFromImport(Module currentModule) {
-        for (ModuleImport currentImport : currentModule.getImports()) {
-            if (currentImport.getModuleName().equals(
-                    ConfigConstants.CONFIG_MODULE)) {
-                return currentImport.getPrefix();
-            }
-        }
-        throw new IllegalArgumentException("Cannot find import "
-                + ConfigConstants.CONFIG_MODULE + " in " + currentModule);
+        return initial.namespace;
     }
 
     /**
@@ -241,504 +152,93 @@ public class ModuleMXBeanEntry extends AbstractEntry {
             Map<QName, ServiceInterfaceEntry> qNamesToSIEs,
             SchemaContext schemaContext,
             TypeProviderWrapper typeProviderWrapper, String packageName) {
-        Map<String, QName> uniqueGeneratedClassesNames = new HashMap<>();
-        logger.debug("Generating ModuleMXBeans of {} to package {}",
-                currentModule.getNamespace(), packageName);
-        String configModulePrefix;
-        try {
-            configModulePrefix = getConfigModulePrefixFromImport(currentModule);
-        } catch (IllegalArgumentException e) {
-            // this module does not import config module
-            return Collections.emptyMap();
-        }
 
-        // get identities of base config:module-type
-        Map<String, IdentitySchemaNode> moduleIdentities = new HashMap<>();
-
-        for (IdentitySchemaNode id : currentModule.getIdentities()) {
-            if (id.getBaseIdentity() != null
-                    && ConfigConstants.MODULE_TYPE_Q_NAME.equals(id
-                            .getBaseIdentity().getQName())) {
-                String identityLocalName = id.getQName().getLocalName();
-                if (moduleIdentities.containsKey(identityLocalName)) {
-                    throw new IllegalStateException(
-                            "Module name already defined in this module: "
-                                    + identityLocalName);
-                } else {
-                    moduleIdentities.put(identityLocalName, id);
-                    logger.debug("Found identity {}", identityLocalName);
-                }
-                // validation check on unknown schema nodes
-                boolean providedServiceWasSet = false;
-                for (UnknownSchemaNode unknownNode : id.getUnknownSchemaNodes()) {
-                    // TODO: test this
-                    if (ConfigConstants.PROVIDED_SERVICE_EXTENSION_QNAME
-                            .equals(unknownNode.getNodeType())) {
-                        // no op: 0 or more provided identities are allowed
-                    } else if (ConfigConstants.JAVA_NAME_PREFIX_EXTENSION_QNAME
-                            .equals(unknownNode.getNodeType())) {
-                        // 0..1 allowed
-                        checkState(
-                                providedServiceWasSet == false,
-                                format("More than one language extension %s is not allowed here: %s",
-                                        ConfigConstants.JAVA_NAME_PREFIX_EXTENSION_QNAME,
-                                        id));
-                        providedServiceWasSet = true;
-                    } else {
-                        throw new IllegalStateException(
-                                "Unexpected language extension "
-                                        + unknownNode.getNodeType());
-                    }
-                }
-            }
-        }
-        Map<String, ModuleMXBeanEntry> result = new HashMap<>();
-        // each module name should have an augmentation defined
-        Map<String, IdentitySchemaNode> unaugmentedModuleIdentities = new HashMap<>(
-                moduleIdentities);
-        for (AugmentationSchema augmentation : currentModule.getAugmentations()) {
-            Set<DataSchemaNode> childNodes = augmentation.getChildNodes();
-            if (childNodes.size() == 1) {
-                DataSchemaNode when = childNodes.iterator().next();
-                if (when instanceof ChoiceCaseNode) {
-                    ChoiceCaseNode choiceCaseNode = (ChoiceCaseNode) when;
-                    if (choiceCaseNode.getConstraints() == null
-                            || choiceCaseNode.getConstraints()
-                                    .getWhenCondition() == null) {
-                        continue;
-                    }
-                    RevisionAwareXPath xPath = choiceCaseNode.getConstraints()
-                            .getWhenCondition();
-                    Matcher matcher = getWhenConditionMatcher(
-                            configModulePrefix, xPath);
-                    if (matcher.matches() == false) {
-                        continue;
-                    }
-                    String moduleLocalNameFromXPath = matcher.group(1);
-                    IdentitySchemaNode moduleIdentity = moduleIdentities
-                            .get(moduleLocalNameFromXPath);
-                    unaugmentedModuleIdentities
-                            .remove(moduleLocalNameFromXPath);
-                    checkState(moduleIdentity != null, "Cannot find identity "
-                            + moduleLocalNameFromXPath
-                            + " matching augmentation " + augmentation);
-                    Map<String, QName> providedServices = findProvidedServices(
-                            moduleIdentity, currentModule, qNamesToSIEs,
-                            schemaContext);
-
-                    if (moduleIdentity == null) {
-                        throw new IllegalStateException(
-                                "Cannot find identity specified by augmentation xpath constraint: "
-                                        + moduleLocalNameFromXPath + " of "
-                                        + augmentation);
-                    }
-                    String javaNamePrefix = findJavaNamePrefix(moduleIdentity);
-
-                    Map<String, AttributeIfc> yangToAttributes = null;
-                    // runtime-data
-                    Collection<RuntimeBeanEntry> runtimeBeans = null;
-
-                    if (expectedConfigurationAugmentationSchemaPath
-                            .equals(augmentation.getTargetPath())) {
-                        logger.debug("Parsing configuration of {}",
-                                moduleLocalNameFromXPath);
-                        yangToAttributes = fillConfiguration(choiceCaseNode,
-                                currentModule, typeProviderWrapper,
-                                qNamesToSIEs, schemaContext, packageName);
-                        checkUniqueAttributesWithGeneratedClass(
-                                uniqueGeneratedClassesNames, when.getQName(),
-                                yangToAttributes);
-                    } else if (expectedStateAugmentationSchemaPath
-                            .equals(augmentation.getTargetPath())) {
-                        logger.debug("Parsing state of {}",
-                                moduleLocalNameFromXPath);
-                        try {
-                            runtimeBeans = fillRuntimeBeans(choiceCaseNode,
-                                    currentModule, typeProviderWrapper,
-                                    packageName, moduleLocalNameFromXPath,
-                                    javaNamePrefix);
-                        } catch (NameConflictException e) {
-                            throw new NameConflictException(
-                                    e.getConflictingName(), when.getQName(),
-                                    when.getQName());
-                        }
-                        checkUniqueRuntimeBeansGeneratedClasses(
-                                uniqueGeneratedClassesNames, when, runtimeBeans);
-                        Set<RuntimeBeanEntry> runtimeBeanEntryValues = Sets
-                                .newHashSet(runtimeBeans);
-                        for (RuntimeBeanEntry entry : runtimeBeanEntryValues) {
-                            checkUniqueAttributesWithGeneratedClass(
-                                    uniqueGeneratedClassesNames,
-                                    when.getQName(),
-                                    entry.getYangPropertiesToTypesMap());
-                        }
-
-                    } else {
-                        throw new IllegalArgumentException(
-                                "Cannot parse augmentation " + augmentation);
-                    }
-                    if (result.containsKey(moduleLocalNameFromXPath)) {
-                        // either fill runtimeBeans or yangToAttributes
-                        ModuleMXBeanEntry moduleMXBeanEntry = result
-                                .get(moduleLocalNameFromXPath);
-                        if (yangToAttributes != null
-                                && moduleMXBeanEntry.getAttributes() == null) {
-                            moduleMXBeanEntry
-                                    .setYangToAttributes(yangToAttributes);
-                        } else if (runtimeBeans != null
-                                && moduleMXBeanEntry.getRuntimeBeans() == null) {
-                            moduleMXBeanEntry.setRuntimeBeans(runtimeBeans);
-                        }
-                    } else {
-                        // construct ModuleMXBeanEntry
-                        ModuleMXBeanEntry moduleMXBeanEntry = new ModuleMXBeanEntry(
-                                moduleIdentity, yangToAttributes, packageName,
-                                providedServices, javaNamePrefix, currentModule
-                                        .getNamespace().toString(),
-                                runtimeBeans,
-                                ModuleUtil.getQName(currentModule));
-                        moduleMXBeanEntry.setYangModuleName(currentModule
-                                .getName());
-                        moduleMXBeanEntry
-                                .setYangModuleLocalname(moduleLocalNameFromXPath);
-                        result.put(moduleLocalNameFromXPath, moduleMXBeanEntry);
-                    }
-                } // skip if child node is not ChoiceCaseNode
-            } // skip if childNodes != 1
-        }
-        // clean up nulls
-        for (Entry<String, ModuleMXBeanEntry> entry : result.entrySet()) {
-            ModuleMXBeanEntry module = entry.getValue();
-            if (module.getAttributes() == null) {
-                module.setYangToAttributes(Collections
-                        .<String, AttributeIfc> emptyMap());
-            } else if (module.getRuntimeBeans() == null) {
-                module.setRuntimeBeans(Collections
-                        .<RuntimeBeanEntry> emptyList());
-            }
-        }
-        // check attributes name uniqueness
-        for (Entry<String, ModuleMXBeanEntry> entry : result.entrySet()) {
-            checkUniqueRuntimeBeanAttributesName(entry.getValue(),
-                    uniqueGeneratedClassesNames);
-        }
-        if (unaugmentedModuleIdentities.size() > 0) {
-            logger.warn("Augmentation not found for all module identities: {}",
-                    unaugmentedModuleIdentities.keySet());
-        }
+        ModuleMXBeanEntryBuilder builder = new ModuleMXBeanEntryBuilder().setModule(currentModule).setqNamesToSIEs(qNamesToSIEs)
+                .setSchemaContext(schemaContext).setTypeProviderWrapper(typeProviderWrapper)
+                .setPackageName(packageName);
 
-        logger.debug("Number of ModuleMXBeans to be generated: {}",
-                result.size());
-        return result;
+        return builder.build();
     }
 
-    private static void checkUniqueRuntimeBeansGeneratedClasses(
-            Map<String, QName> uniqueGeneratedClassesNames,
-            DataSchemaNode when, Collection<RuntimeBeanEntry> runtimeBeans) {
-        for (RuntimeBeanEntry runtimeBean : runtimeBeans) {
-            final String javaNameOfRuntimeMXBean = runtimeBean
-                    .getJavaNameOfRuntimeMXBean();
-            if (uniqueGeneratedClassesNames
-                    .containsKey(javaNameOfRuntimeMXBean)) {
-                QName firstDefinedQName = uniqueGeneratedClassesNames
-                        .get(javaNameOfRuntimeMXBean);
-                throw new NameConflictException(javaNameOfRuntimeMXBean,
-                        firstDefinedQName, when.getQName());
-            }
-            uniqueGeneratedClassesNames.put(javaNameOfRuntimeMXBean,
-                    when.getQName());
-        }
-    }
-
-    private static void checkUniqueRuntimeBeanAttributesName(
-            ModuleMXBeanEntry mxBeanEntry,
-            Map<String, QName> uniqueGeneratedClassesNames) {
-        for (RuntimeBeanEntry runtimeBeanEntry : mxBeanEntry.getRuntimeBeans()) {
-            for (String runtimeAttName : runtimeBeanEntry
-                    .getYangPropertiesToTypesMap().keySet()) {
-                if (mxBeanEntry.getAttributes().keySet()
-                        .contains(runtimeAttName)) {
-                    QName qName1 = uniqueGeneratedClassesNames
-                            .get(runtimeBeanEntry.getJavaNameOfRuntimeMXBean());
-                    QName qName2 = uniqueGeneratedClassesNames.get(mxBeanEntry
-                            .getGloballyUniqueName());
-                    throw new NameConflictException(runtimeAttName, qName1,
-                            qName2);
-                }
-            }
-        }
-    }
-
-    private static void checkUniqueAttributesWithGeneratedClass(
-            Map<String, QName> uniqueGeneratedClassNames, QName parentQName,
-            Map<String, AttributeIfc> yangToAttributes) {
-        for (Entry<String, AttributeIfc> attr : yangToAttributes.entrySet()) {
-            if (attr.getValue() instanceof TOAttribute) {
-                checkUniqueTOAttr(uniqueGeneratedClassNames, parentQName,
-                        (TOAttribute) attr.getValue());
-            } else if (attr.getValue() instanceof ListAttribute
-                    && ((ListAttribute) attr.getValue()).getInnerAttribute() instanceof TOAttribute) {
-                checkUniqueTOAttr(uniqueGeneratedClassNames, parentQName,
-                        (TOAttribute) ((ListAttribute) attr.getValue())
-                                .getInnerAttribute());
-            }
-        }
+    public Map<String, AttributeIfc> getAttributes() {
+        return yangToAttributes;
     }
 
-    private static void checkUniqueTOAttr(
-            Map<String, QName> uniqueGeneratedClassNames, QName parentQName,
-            TOAttribute attr) {
-        final String upperCaseCammelCase = attr.getUpperCaseCammelCase();
-        if (uniqueGeneratedClassNames.containsKey(upperCaseCammelCase)) {
-            QName firstDefinedQName = uniqueGeneratedClassNames
-                    .get(upperCaseCammelCase);
-            throw new NameConflictException(upperCaseCammelCase,
-                    firstDefinedQName, parentQName);
-        } else {
-            uniqueGeneratedClassNames.put(upperCaseCammelCase, parentQName);
-        }
+    void setYangToAttributes(Map<String, AttributeIfc> newAttributes) {
+        this.yangToAttributes = newAttributes;
     }
 
-    private static Collection<RuntimeBeanEntry> fillRuntimeBeans(
-            ChoiceCaseNode choiceCaseNode, Module currentModule,
-            TypeProviderWrapper typeProviderWrapper, String packageName,
-            String moduleLocalNameFromXPath, String javaNamePrefix) {
-
-        return RuntimeBeanEntry.extractClassNameToRuntimeBeanMap(packageName,
-                choiceCaseNode, moduleLocalNameFromXPath, typeProviderWrapper,
-                javaNamePrefix, currentModule).values();
-
+    public String getNullableDescription() {
+        return initial.description;
     }
 
-    private static Map<String, AttributeIfc> fillConfiguration(
-            ChoiceCaseNode choiceCaseNode, Module currentModule,
-            TypeProviderWrapper typeProviderWrapper,
-            Map<QName, ServiceInterfaceEntry> qNamesToSIEs,
-            SchemaContext schemaContext, String packageName) {
-        Map<String, AttributeIfc> yangToAttributes = new HashMap<>();
-        for (DataSchemaNode attrNode : choiceCaseNode.getChildNodes()) {
-            AttributeIfc attributeValue = getAttributeValue(attrNode,
-                    currentModule, qNamesToSIEs, typeProviderWrapper,
-                    schemaContext, packageName);
-            yangToAttributes.put(attributeValue.getAttributeYangName(),
-                    attributeValue);
-        }
-        return yangToAttributes;
+    public QName getYangModuleQName() {
+        return initial.qName;
     }
 
-    private static Map<String, QName> findProvidedServices(
-            IdentitySchemaNode moduleIdentity, Module currentModule,
-            Map<QName, ServiceInterfaceEntry> qNamesToSIEs,
-            SchemaContext schemaContext) {
-        Map<String, QName> result = new HashMap<>();
-        for (UnknownSchemaNode unknownNode : moduleIdentity
-                .getUnknownSchemaNodes()) {
-            if (ConfigConstants.PROVIDED_SERVICE_EXTENSION_QNAME
-                    .equals(unknownNode.getNodeType())) {
-                String prefixAndIdentityLocalName = unknownNode
-                        .getNodeParameter();
-                ServiceInterfaceEntry sie = findSIE(prefixAndIdentityLocalName,
-                        currentModule, qNamesToSIEs, schemaContext);
-                result.put(sie.getFullyQualifiedName(), sie.getQName());
-            }
-        }
-        return result;
+    @Override
+    public String toString() {
+        return "ModuleMXBeanEntry{" + "globallyUniqueName='"
+                + initial.localName + '\'' + ", packageName='" + initial.packageName
+                + '\'' + '}';
     }
 
-    /**
-     * For input node, find if it contains config:java-name-prefix extension. If
-     * not found, convert local name of node converted to cammel case.
-     */
-    public static String findJavaNamePrefix(SchemaNode schemaNode) {
-        return convertToJavaName(schemaNode, true);
-    }
+    static final class ModuleMXBeanEntryInitial {
 
-    public static String findJavaParameter(SchemaNode schemaNode) {
-        return convertToJavaName(schemaNode, false);
-    }
+        private String localName;
+        private String description;
+        private String packageName;
+        private String javaNamePrefix;
+        private String namespace;
+        private QName qName;
 
-    public static String convertToJavaName(SchemaNode schemaNode,
-            boolean capitalizeFirstLetter) {
-        for (UnknownSchemaNode unknownNode : schemaNode.getUnknownSchemaNodes()) {
-            if (ConfigConstants.JAVA_NAME_PREFIX_EXTENSION_QNAME
-                    .equals(unknownNode.getNodeType())) {
-                String value = unknownNode.getNodeParameter();
-                return convertToJavaName(value, capitalizeFirstLetter);
-            }
+        ModuleMXBeanEntryInitial(String localName, String description, String packageName, String javaNamePrefix, String namespace, QName qName) {
+            this.localName = localName;
+            this.description = description;
+            this.packageName = packageName;
+            this.javaNamePrefix = javaNamePrefix;
+            this.namespace = namespace;
+            this.qName = qName;
         }
-        return convertToJavaName(schemaNode.getQName().getLocalName(),
-                capitalizeFirstLetter);
     }
 
-    public static String convertToJavaName(String localName,
-            boolean capitalizeFirstLetter) {
-        if (capitalizeFirstLetter) {
-            return BindingGeneratorUtil.parseToClassName(localName);
-        } else {
-            return BindingGeneratorUtil.parseToValidParamName(localName);
-        }
-    }
+    static final class ModuleMXBeanEntryInitialBuilder {
+        private String localName;
+        private String description;
+        private String packageName;
+        private String javaNamePrefix;
+        private String namespace;
+        private QName qName;
 
-    private static int getChildNodeSizeWithoutUses(DataNodeContainer csn) {
-        int result = 0;
-        for (DataSchemaNode dsn : csn.getChildNodes()) {
-            if (dsn.isAddedByUses() == false) {
-                result++;
-            }
+        public ModuleMXBeanEntryInitialBuilder setPackageName(String packageName) {
+            this.packageName = packageName;
+            return this;
         }
-        return result;
-    }
 
-    private static AttributeIfc getAttributeValue(DataSchemaNode attrNode,
-            Module currentModule,
-            Map<QName, ServiceInterfaceEntry> qNamesToSIEs,
-            TypeProviderWrapper typeProviderWrapper,
-            SchemaContext schemaContext, String packageName) {
-
-        if (attrNode instanceof LeafSchemaNode) {
-            // simple type
-            LeafSchemaNode leaf = (LeafSchemaNode) attrNode;
-            return new JavaAttribute(leaf, typeProviderWrapper);
-        } else if (attrNode instanceof ContainerSchemaNode) {
-            // reference or TO
-            ContainerSchemaNode containerSchemaNode = (ContainerSchemaNode) attrNode;
-            Optional<? extends AbstractDependencyAttribute> dependencyAttributeOptional = extractDependency(
-                    containerSchemaNode, attrNode, currentModule, qNamesToSIEs,
-                    schemaContext);
-            if (dependencyAttributeOptional.isPresent()) {
-                return dependencyAttributeOptional.get();
-            } else {
-                return TOAttribute.create(containerSchemaNode,
-                        typeProviderWrapper, packageName);
-            }
-
-        } else if (attrNode instanceof LeafListSchemaNode) {
-            return ListAttribute.create((LeafListSchemaNode) attrNode,
-                    typeProviderWrapper);
-        } else if (attrNode instanceof ListSchemaNode) {
-            ListSchemaNode listSchemaNode = (ListSchemaNode) attrNode;
-            Optional<? extends AbstractDependencyAttribute> dependencyAttributeOptional = extractDependency(
-                    listSchemaNode, attrNode, currentModule, qNamesToSIEs,
-                    schemaContext);
-            if (dependencyAttributeOptional.isPresent()) {
-                return dependencyAttributeOptional.get();
-            } else {
-                return ListAttribute.create(listSchemaNode,
-                        typeProviderWrapper, packageName);
-            }
-        } else {
-            throw new UnsupportedOperationException(
-                    "Unknown configuration node " + attrNode.toString());
+        public ModuleMXBeanEntryInitialBuilder setJavaNamePrefix(String javaNamePrefix) {
+            this.javaNamePrefix = javaNamePrefix;
+            return this;
         }
-    }
 
-    private static Optional<? extends AbstractDependencyAttribute> extractDependency(
-            DataNodeContainer dataNodeContainer, DataSchemaNode attrNode,
-            Module currentModule,
-            Map<QName, ServiceInterfaceEntry> qNamesToSIEs,
-            SchemaContext schemaContext) {
-        if (dataNodeContainer.getUses().size() == 1
-                && getChildNodeSizeWithoutUses(dataNodeContainer) == 0) {
-            // reference
-            UsesNode usesNode = dataNodeContainer.getUses().iterator().next();
-            checkState(usesNode.getRefines().size() == 1,
-                    "Unexpected 'refine' child node size of "
-                            + dataNodeContainer);
-            LeafSchemaNode refine = (LeafSchemaNode) usesNode.getRefines()
-                    .values().iterator().next();
-            checkState(refine.getUnknownSchemaNodes().size() == 1,
-                    "Unexpected unknown schema node size of " + refine);
-            UnknownSchemaNode requiredIdentity = refine.getUnknownSchemaNodes()
-                    .iterator().next();
-            checkState(
-                    ConfigConstants.REQUIRED_IDENTITY_EXTENSION_QNAME.equals(requiredIdentity
-                            .getNodeType()), "Unexpected language extension "
-                            + requiredIdentity);
-            String prefixAndIdentityLocalName = requiredIdentity
-                    .getNodeParameter();
-            // import should point to a module
-            ServiceInterfaceEntry serviceInterfaceEntry = findSIE(
-                    prefixAndIdentityLocalName, currentModule, qNamesToSIEs,
-                    schemaContext);
-            boolean mandatory = refine.getConstraints().isMandatory();
-            AbstractDependencyAttribute reference;
-            if (dataNodeContainer instanceof ContainerSchemaNode) {
-                reference = new DependencyAttribute(attrNode,
-                        serviceInterfaceEntry, mandatory,
-                        attrNode.getDescription());
-            } else {
-                reference = new ListDependenciesAttribute(attrNode,
-                        serviceInterfaceEntry, mandatory,
-                        attrNode.getDescription());
-            }
-            return Optional.of(reference);
+        public ModuleMXBeanEntryInitialBuilder setNamespace(String namespace) {
+            this.namespace = namespace;
+            return this;
         }
-        return Optional.absent();
-    }
 
-    private static ServiceInterfaceEntry findSIE(
-            String prefixAndIdentityLocalName, Module currentModule,
-            Map<QName, ServiceInterfaceEntry> qNamesToSIEs,
-            SchemaContext schemaContext) {
-
-        Matcher m = PREFIX_COLON_LOCAL_NAME.matcher(prefixAndIdentityLocalName);
-        Module foundModule;
-        String localSIName;
-        if (m.matches()) {
-            // if there is a prefix, look for ModuleImport with this prefix. Get
-            // Module from SchemaContext
-            String prefix = m.group(1);
-            ModuleImport moduleImport = findModuleImport(currentModule, prefix);
-            foundModule = schemaContext.findModuleByName(
-                    moduleImport.getModuleName(), moduleImport.getRevision());
-            checkState(
-                    foundModule != null,
-                    format("Module not found in SchemaContext by %s",
-                            moduleImport));
-            localSIName = m.group(2);
-        } else {
-            foundModule = currentModule; // no prefix => SIE is in currentModule
-            localSIName = prefixAndIdentityLocalName;
+        public ModuleMXBeanEntryInitialBuilder setqName(QName qName) {
+            this.qName = qName;
+            return this;
         }
-        QName siQName = new QName(foundModule.getNamespace(),
-                foundModule.getRevision(), localSIName);
-        ServiceInterfaceEntry sie = qNamesToSIEs.get(siQName);
-        checkState(sie != null, "Cannot find referenced Service Interface by "
-                + prefixAndIdentityLocalName);
-        return sie;
-    }
 
-    private static ModuleImport findModuleImport(Module module, String prefix) {
-        for (ModuleImport moduleImport : module.getImports()) {
-            if (moduleImport.getPrefix().equals(prefix)) {
-                return moduleImport;
-            }
+        public ModuleMXBeanEntry.ModuleMXBeanEntryInitial build() {
+            return new ModuleMXBeanEntry.ModuleMXBeanEntryInitial(localName, description, packageName, javaNamePrefix, namespace, qName);
         }
-        throw new IllegalStateException(format(
-                "Import not found with prefix %s in %s", prefix, module));
-    }
 
-    public Map<String, AttributeIfc> getAttributes() {
-        return yangToAttributes;
-    }
-
-    private void setYangToAttributes(Map<String, AttributeIfc> newAttributes) {
-        this.yangToAttributes = newAttributes;
-
-    }
-
-    public String getNullableDescription() {
-        return nullableDescription;
-    }
-
-    public QName getYangModuleQName() {
-        return yangModuleQName;
-    }
+        public ModuleMXBeanEntryInitialBuilder setIdSchemaNode(IdentitySchemaNode idSchemaNode) {
+            this.localName = idSchemaNode.getQName().getLocalName();
+            this.description = idSchemaNode.getDescription();
+            return this;
+        }
 
-    @Override
-    public String toString() {
-        return "ModuleMXBeanEntry{" + "globallyUniqueName='"
-                + globallyUniqueName + '\'' + ", packageName='" + packageName
-                + '\'' + '}';
     }
 }
diff --git a/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntryBuilder.java b/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntryBuilder.java
new file mode 100644 (file)
index 0000000..4a9d551
--- /dev/null
@@ -0,0 +1,523 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.config.yangjmxgenerator;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import org.opendaylight.controller.config.yangjmxgenerator.attribute.AbstractDependencyAttribute;
+import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIfc;
+import org.opendaylight.controller.config.yangjmxgenerator.attribute.DependencyAttribute;
+import org.opendaylight.controller.config.yangjmxgenerator.attribute.JavaAttribute;
+import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListAttribute;
+import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListDependenciesAttribute;
+import org.opendaylight.controller.config.yangjmxgenerator.attribute.TOAttribute;
+import org.opendaylight.controller.config.yangjmxgenerator.plugin.util.NameConflictException;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
+import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
+import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
+import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.ModuleImport;
+import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.UsesNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.annotation.Nullable;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import static com.google.common.base.Preconditions.checkState;
+import static java.lang.String.format;
+import static org.opendaylight.controller.config.yangjmxgenerator.ConfigConstants.createConfigQName;
+
+final class ModuleMXBeanEntryBuilder {
+
+    private Module currentModule;
+    private Map<QName, ServiceInterfaceEntry> qNamesToSIEs;
+    private SchemaContext schemaContext;
+    private TypeProviderWrapper typeProviderWrapper;
+    private String packageName;
+
+    public ModuleMXBeanEntryBuilder setModule(Module module) {
+        this.currentModule = module;
+        return this;
+    }
+
+    public ModuleMXBeanEntryBuilder setqNamesToSIEs(Map<QName, ServiceInterfaceEntry> qNamesToSIEs) {
+        this.qNamesToSIEs = qNamesToSIEs;
+        return this;
+    }
+
+    public ModuleMXBeanEntryBuilder setSchemaContext(SchemaContext schemaContext) {
+        this.schemaContext = schemaContext;
+        return this;
+    }
+
+    public ModuleMXBeanEntryBuilder setTypeProviderWrapper(TypeProviderWrapper typeProviderWrapper) {
+        this.typeProviderWrapper = typeProviderWrapper;
+        return this;
+    }
+
+    public ModuleMXBeanEntryBuilder setPackageName(String packageName) {
+        this.packageName = packageName;
+        return this;
+    }
+
+    private static final Logger logger = LoggerFactory
+            .getLogger(ModuleMXBeanEntryBuilder.class);
+
+    // TODO: the XPath should be parsed by code generator IMO
+    private static final String MAGIC_STRING = "MAGIC_STRING";
+    private static final String MODULE_CONDITION_XPATH_TEMPLATE = "^/MAGIC_STRING:modules/MAGIC_STRING:module/MAGIC_STRING:type\\s*=\\s*['\"](.+)['\"]$";
+    private static final SchemaPath expectedConfigurationAugmentationSchemaPath = new SchemaPath(
+            Arrays.asList(createConfigQName("modules"),
+                    createConfigQName("module"),
+                    createConfigQName("configuration")), true);
+    private static final SchemaPath expectedStateAugmentationSchemaPath = new SchemaPath(
+            Arrays.asList(createConfigQName("modules"),
+                    createConfigQName("module"), createConfigQName("state")),
+            true);
+    private static final Pattern PREFIX_COLON_LOCAL_NAME = Pattern
+            .compile("^(.+):(.+)$");
+
+
+    public Map<String, ModuleMXBeanEntry> build() {
+        logger.debug("Generating ModuleMXBeans of {} to package {}",
+                currentModule.getNamespace(), packageName);
+
+        String configModulePrefix;
+        try {
+            configModulePrefix = getConfigModulePrefixFromImport(currentModule);
+        } catch (IllegalArgumentException e) {
+            // this currentModule does not import config currentModule
+            return Collections.emptyMap();
+        }
+
+        // get identities of base config:currentModule-type
+        Map<String, IdentitySchemaNode> moduleIdentities =  getIdentityMap();
+
+        Map<String, QName> uniqueGeneratedClassesNames = new HashMap<>();
+
+        // each currentModule name should have an augmentation defined
+        Map<String, IdentitySchemaNode> unaugmentedModuleIdentities = new HashMap<>(
+                moduleIdentities);
+
+        Map<String, ModuleMXBeanEntry> result = new HashMap<>();
+
+        for (AugmentationSchema augmentation : currentModule.getAugmentations()) {
+            Set<DataSchemaNode> childNodes = augmentation.getChildNodes();
+            if (areAllChildrenChoiceCaseNodes(childNodes)) {
+                for (ChoiceCaseNode childCase : castChildNodesToChoiceCases(childNodes)) {
+                    // TODO refactor, extract to standalone builder class
+                    processChoiceCaseNode(result, uniqueGeneratedClassesNames, configModulePrefix, moduleIdentities,
+                            unaugmentedModuleIdentities, augmentation, childCase);
+                }
+            } // skip if child nodes are not all cases
+        }
+        // clean up nulls
+        cleanUpNulls(result);
+        // check attributes name uniqueness
+        checkAttributeNamesUniqueness(uniqueGeneratedClassesNames, result);
+        checkUnaugumentedIdentities(unaugmentedModuleIdentities);
+
+        logger.debug("Number of ModuleMXBeans to be generated: {}", result.size());
+
+        return result;
+    }
+
+    private static void cleanUpNulls(Map<String, ModuleMXBeanEntry> result) {
+        for (Map.Entry<String, ModuleMXBeanEntry> entry : result.entrySet()) {
+            ModuleMXBeanEntry module = entry.getValue();
+            if (module.getAttributes() == null) {
+                module.setYangToAttributes(Collections
+                        .<String, AttributeIfc> emptyMap());
+            } else if (module.getRuntimeBeans() == null) {
+                module.setRuntimeBeans(Collections
+                        .<RuntimeBeanEntry> emptyList());
+            }
+        }
+    }
+
+    private static void checkUnaugumentedIdentities(Map<String, IdentitySchemaNode> unaugmentedModuleIdentities) {
+        if (unaugmentedModuleIdentities.size() > 0) {
+            logger.warn("Augmentation not found for all currentModule identities: {}",
+                    unaugmentedModuleIdentities.keySet());
+        }
+    }
+
+    private static void checkAttributeNamesUniqueness(Map<String, QName> uniqueGeneratedClassesNames, Map<String, ModuleMXBeanEntry> result) {
+        for (Map.Entry<String, ModuleMXBeanEntry> entry : result.entrySet()) {
+            checkUniqueRuntimeBeanAttributesName(entry.getValue(),
+                    uniqueGeneratedClassesNames);
+        }
+    }
+
+    private Map<String, IdentitySchemaNode> getIdentityMap() {
+        Map<String, IdentitySchemaNode> moduleIdentities = Maps.newHashMap();
+
+        for (IdentitySchemaNode id : currentModule.getIdentities()) {
+            if (id.getBaseIdentity() != null
+                    && ConfigConstants.MODULE_TYPE_Q_NAME.equals(id.getBaseIdentity().getQName())) {
+                String identityLocalName = id.getQName().getLocalName();
+                if (moduleIdentities.containsKey(identityLocalName)) {
+                    throw new IllegalStateException("Module name already defined in this currentModule: "
+                            + identityLocalName);
+                } else {
+                    moduleIdentities.put(identityLocalName, id);
+                    logger.debug("Found identity {}", identityLocalName);
+                }
+                // validation check on unknown schema nodes
+                boolean providedServiceWasSet = false;
+                for (UnknownSchemaNode unknownNode : id.getUnknownSchemaNodes()) {
+                    // TODO: test this
+                    if (ConfigConstants.PROVIDED_SERVICE_EXTENSION_QNAME.equals(unknownNode.getNodeType())) {
+                        // no op: 0 or more provided identities are allowed
+                    } else if (ConfigConstants.JAVA_NAME_PREFIX_EXTENSION_QNAME.equals(unknownNode.getNodeType())) {
+                        // 0..1 allowed
+                        checkState(
+                                providedServiceWasSet == false,
+                                format("More than one language extension %s is not allowed here: %s",
+                                        ConfigConstants.JAVA_NAME_PREFIX_EXTENSION_QNAME, id));
+                        providedServiceWasSet = true;
+                    } else {
+                        throw new IllegalStateException("Unexpected language extension " + unknownNode.getNodeType());
+                    }
+                }
+            }
+        }
+
+        return moduleIdentities;
+    }
+
+    private Collection<ChoiceCaseNode> castChildNodesToChoiceCases(Set<DataSchemaNode> childNodes) {
+        return Collections2.transform(childNodes, new Function<DataSchemaNode, ChoiceCaseNode>() {
+            @Nullable
+            @Override
+            public ChoiceCaseNode apply(@Nullable DataSchemaNode input) {
+                return (ChoiceCaseNode) input;
+            }
+        });
+    }
+
+    private boolean areAllChildrenChoiceCaseNodes(Set<DataSchemaNode> childNodes) {
+        for (DataSchemaNode childNode : childNodes) {
+            if (childNode instanceof ChoiceCaseNode == false)
+                return false;
+        }
+        return true;
+    }
+
+    private void processChoiceCaseNode(Map<String, ModuleMXBeanEntry> result,
+            Map<String, QName> uniqueGeneratedClassesNames, String configModulePrefix,
+            Map<String, IdentitySchemaNode> moduleIdentities,
+            Map<String, IdentitySchemaNode> unaugmentedModuleIdentities, AugmentationSchema augmentation,
+            DataSchemaNode when) {
+
+        ChoiceCaseNode choiceCaseNode = (ChoiceCaseNode) when;
+        if (choiceCaseNode.getConstraints() == null || choiceCaseNode.getConstraints().getWhenCondition() == null) {
+            return;
+        }
+        RevisionAwareXPath xPath = choiceCaseNode.getConstraints().getWhenCondition();
+        Matcher matcher = getWhenConditionMatcher(configModulePrefix, xPath);
+        if (matcher.matches() == false) {
+            return;
+        }
+        String moduleLocalNameFromXPath = matcher.group(1);
+        IdentitySchemaNode moduleIdentity = moduleIdentities.get(moduleLocalNameFromXPath);
+        unaugmentedModuleIdentities.remove(moduleLocalNameFromXPath);
+        checkState(moduleIdentity != null, "Cannot find identity " + moduleLocalNameFromXPath
+                + " matching augmentation " + augmentation);
+        Map<String, QName> providedServices = findProvidedServices(moduleIdentity, currentModule, qNamesToSIEs,
+                schemaContext);
+
+        if (moduleIdentity == null) {
+            throw new IllegalStateException("Cannot find identity specified by augmentation xpath constraint: "
+                    + moduleLocalNameFromXPath + " of " + augmentation);
+        }
+        String javaNamePrefix = TypeProviderWrapper.findJavaNamePrefix(moduleIdentity);
+
+        Map<String, AttributeIfc> yangToAttributes = null;
+        // runtime-data
+        Collection<RuntimeBeanEntry> runtimeBeans = null;
+
+        if (expectedConfigurationAugmentationSchemaPath.equals(augmentation.getTargetPath())) {
+            logger.debug("Parsing configuration of {}", moduleLocalNameFromXPath);
+            yangToAttributes = fillConfiguration(choiceCaseNode, currentModule, typeProviderWrapper, qNamesToSIEs,
+                    schemaContext, packageName);
+            checkUniqueAttributesWithGeneratedClass(uniqueGeneratedClassesNames, when.getQName(), yangToAttributes);
+        } else if (expectedStateAugmentationSchemaPath.equals(augmentation.getTargetPath())) {
+            logger.debug("Parsing state of {}", moduleLocalNameFromXPath);
+            try {
+                runtimeBeans = fillRuntimeBeans(choiceCaseNode, currentModule, typeProviderWrapper, packageName,
+                        moduleLocalNameFromXPath, javaNamePrefix);
+            } catch (NameConflictException e) {
+                throw new NameConflictException(e.getConflictingName(), when.getQName(), when.getQName());
+            }
+            checkUniqueRuntimeBeansGeneratedClasses(uniqueGeneratedClassesNames, when, runtimeBeans);
+            Set<RuntimeBeanEntry> runtimeBeanEntryValues = Sets.newHashSet(runtimeBeans);
+            for (RuntimeBeanEntry entry : runtimeBeanEntryValues) {
+                checkUniqueAttributesWithGeneratedClass(uniqueGeneratedClassesNames, when.getQName(),
+                        entry.getYangPropertiesToTypesMap());
+            }
+
+        } else {
+            throw new IllegalArgumentException("Cannot parse augmentation " + augmentation);
+        }
+        if (result.containsKey(moduleLocalNameFromXPath)) {
+            // either fill runtimeBeans or yangToAttributes
+            ModuleMXBeanEntry moduleMXBeanEntry = result.get(moduleLocalNameFromXPath);
+            if (yangToAttributes != null && moduleMXBeanEntry.getAttributes() == null) {
+                moduleMXBeanEntry.setYangToAttributes(yangToAttributes);
+            } else if (runtimeBeans != null && moduleMXBeanEntry.getRuntimeBeans() == null) {
+                moduleMXBeanEntry.setRuntimeBeans(runtimeBeans);
+            }
+        } else {
+            ModuleMXBeanEntry.ModuleMXBeanEntryInitial initial = new ModuleMXBeanEntry.ModuleMXBeanEntryInitialBuilder()
+                    .setIdSchemaNode(moduleIdentity).setPackageName(packageName).setJavaNamePrefix(javaNamePrefix)
+                    .setNamespace(currentModule.getNamespace().toString()).setqName(ModuleUtil.getQName(currentModule))
+                    .build();
+
+            // construct ModuleMXBeanEntry
+            ModuleMXBeanEntry moduleMXBeanEntry = new ModuleMXBeanEntry(initial, yangToAttributes, providedServices,
+                    runtimeBeans);
+
+            moduleMXBeanEntry.setYangModuleName(currentModule.getName());
+            moduleMXBeanEntry.setYangModuleLocalname(moduleLocalNameFromXPath);
+            result.put(moduleLocalNameFromXPath, moduleMXBeanEntry);
+        }
+    }
+
+    private void checkUniqueRuntimeBeansGeneratedClasses(Map<String, QName> uniqueGeneratedClassesNames,
+            DataSchemaNode when, Collection<RuntimeBeanEntry> runtimeBeans) {
+        for (RuntimeBeanEntry runtimeBean : runtimeBeans) {
+            final String javaNameOfRuntimeMXBean = runtimeBean.getJavaNameOfRuntimeMXBean();
+            if (uniqueGeneratedClassesNames.containsKey(javaNameOfRuntimeMXBean)) {
+                QName firstDefinedQName = uniqueGeneratedClassesNames.get(javaNameOfRuntimeMXBean);
+                throw new NameConflictException(javaNameOfRuntimeMXBean, firstDefinedQName, when.getQName());
+            }
+            uniqueGeneratedClassesNames.put(javaNameOfRuntimeMXBean, when.getQName());
+        }
+    }
+
+    private static void checkUniqueRuntimeBeanAttributesName(ModuleMXBeanEntry mxBeanEntry,
+            Map<String, QName> uniqueGeneratedClassesNames) {
+        for (RuntimeBeanEntry runtimeBeanEntry : mxBeanEntry.getRuntimeBeans()) {
+            for (String runtimeAttName : runtimeBeanEntry.getYangPropertiesToTypesMap().keySet()) {
+                if (mxBeanEntry.getAttributes().keySet().contains(runtimeAttName)) {
+                    QName qName1 = uniqueGeneratedClassesNames.get(runtimeBeanEntry.getJavaNameOfRuntimeMXBean());
+                    QName qName2 = uniqueGeneratedClassesNames.get(mxBeanEntry.getGloballyUniqueName());
+                    throw new NameConflictException(runtimeAttName, qName1, qName2);
+                }
+            }
+        }
+    }
+
+    private void checkUniqueAttributesWithGeneratedClass(Map<String, QName> uniqueGeneratedClassNames,
+            QName parentQName, Map<String, AttributeIfc> yangToAttributes) {
+        for (Map.Entry<String, AttributeIfc> attr : yangToAttributes.entrySet()) {
+            if (attr.getValue() instanceof TOAttribute) {
+                checkUniqueTOAttr(uniqueGeneratedClassNames, parentQName, (TOAttribute) attr.getValue());
+            } else if (attr.getValue() instanceof ListAttribute
+                    && ((ListAttribute) attr.getValue()).getInnerAttribute() instanceof TOAttribute) {
+                checkUniqueTOAttr(uniqueGeneratedClassNames, parentQName,
+                        (TOAttribute) ((ListAttribute) attr.getValue()).getInnerAttribute());
+            }
+        }
+    }
+
+    private void checkUniqueTOAttr(Map<String, QName> uniqueGeneratedClassNames, QName parentQName, TOAttribute attr) {
+        final String upperCaseCammelCase = attr.getUpperCaseCammelCase();
+        if (uniqueGeneratedClassNames.containsKey(upperCaseCammelCase)) {
+            QName firstDefinedQName = uniqueGeneratedClassNames.get(upperCaseCammelCase);
+            throw new NameConflictException(upperCaseCammelCase, firstDefinedQName, parentQName);
+        } else {
+            uniqueGeneratedClassNames.put(upperCaseCammelCase, parentQName);
+        }
+    }
+
+    private Collection<RuntimeBeanEntry> fillRuntimeBeans(ChoiceCaseNode choiceCaseNode, Module currentModule,
+            TypeProviderWrapper typeProviderWrapper, String packageName, String moduleLocalNameFromXPath,
+            String javaNamePrefix) {
+
+        return RuntimeBeanEntry.extractClassNameToRuntimeBeanMap(packageName, choiceCaseNode, moduleLocalNameFromXPath,
+                typeProviderWrapper, javaNamePrefix, currentModule).values();
+
+    }
+
+    private Map<String, AttributeIfc> fillConfiguration(ChoiceCaseNode choiceCaseNode, Module currentModule,
+            TypeProviderWrapper typeProviderWrapper, Map<QName, ServiceInterfaceEntry> qNamesToSIEs,
+            SchemaContext schemaContext, String packageName) {
+        Map<String, AttributeIfc> yangToAttributes = new HashMap<>();
+        for (DataSchemaNode attrNode : choiceCaseNode.getChildNodes()) {
+            AttributeIfc attributeValue = getAttributeValue(attrNode, currentModule, qNamesToSIEs, typeProviderWrapper,
+                    schemaContext, packageName);
+            yangToAttributes.put(attributeValue.getAttributeYangName(), attributeValue);
+        }
+        return yangToAttributes;
+    }
+
+    private Map<String, QName> findProvidedServices(IdentitySchemaNode moduleIdentity, Module currentModule,
+            Map<QName, ServiceInterfaceEntry> qNamesToSIEs, SchemaContext schemaContext) {
+        Map<String, QName> result = new HashMap<>();
+        for (UnknownSchemaNode unknownNode : moduleIdentity.getUnknownSchemaNodes()) {
+            if (ConfigConstants.PROVIDED_SERVICE_EXTENSION_QNAME.equals(unknownNode.getNodeType())) {
+                String prefixAndIdentityLocalName = unknownNode.getNodeParameter();
+                ServiceInterfaceEntry sie = findSIE(prefixAndIdentityLocalName, currentModule, qNamesToSIEs,
+                        schemaContext);
+                result.put(sie.getFullyQualifiedName(), sie.getQName());
+            }
+        }
+        return result;
+    }
+
+    private AttributeIfc getAttributeValue(DataSchemaNode attrNode, Module currentModule,
+            Map<QName, ServiceInterfaceEntry> qNamesToSIEs, TypeProviderWrapper typeProviderWrapper,
+            SchemaContext schemaContext, String packageName) {
+
+        if (attrNode instanceof LeafSchemaNode) {
+            // simple type
+            LeafSchemaNode leaf = (LeafSchemaNode) attrNode;
+            return new JavaAttribute(leaf, typeProviderWrapper);
+        } else if (attrNode instanceof ContainerSchemaNode) {
+            // reference or TO
+            ContainerSchemaNode containerSchemaNode = (ContainerSchemaNode) attrNode;
+            Optional<? extends AbstractDependencyAttribute> dependencyAttributeOptional = extractDependency(
+                    containerSchemaNode, attrNode, currentModule, qNamesToSIEs, schemaContext);
+            if (dependencyAttributeOptional.isPresent()) {
+                return dependencyAttributeOptional.get();
+            } else {
+                return TOAttribute.create(containerSchemaNode, typeProviderWrapper, packageName);
+            }
+
+        } else if (attrNode instanceof LeafListSchemaNode) {
+            return ListAttribute.create((LeafListSchemaNode) attrNode, typeProviderWrapper);
+        } else if (attrNode instanceof ListSchemaNode) {
+            ListSchemaNode listSchemaNode = (ListSchemaNode) attrNode;
+            Optional<? extends AbstractDependencyAttribute> dependencyAttributeOptional = extractDependency(
+                    listSchemaNode, attrNode, currentModule, qNamesToSIEs, schemaContext);
+            if (dependencyAttributeOptional.isPresent()) {
+                return dependencyAttributeOptional.get();
+            } else {
+                return ListAttribute.create(listSchemaNode, typeProviderWrapper, packageName);
+            }
+        } else {
+            throw new UnsupportedOperationException("Unknown configuration node " + attrNode.toString());
+        }
+    }
+
+    private Optional<? extends AbstractDependencyAttribute> extractDependency(DataNodeContainer dataNodeContainer,
+            DataSchemaNode attrNode, Module currentModule, Map<QName, ServiceInterfaceEntry> qNamesToSIEs,
+            SchemaContext schemaContext) {
+        if (dataNodeContainer.getUses().size() == 1 && getChildNodeSizeWithoutUses(dataNodeContainer) == 0) {
+            // reference
+            UsesNode usesNode = dataNodeContainer.getUses().iterator().next();
+            checkState(usesNode.getRefines().size() == 1, "Unexpected 'refine' child node size of " + dataNodeContainer);
+            LeafSchemaNode refine = (LeafSchemaNode) usesNode.getRefines().values().iterator().next();
+            checkState(refine.getUnknownSchemaNodes().size() == 1, "Unexpected unknown schema node size of " + refine);
+            UnknownSchemaNode requiredIdentity = refine.getUnknownSchemaNodes().iterator().next();
+            checkState(ConfigConstants.REQUIRED_IDENTITY_EXTENSION_QNAME.equals(requiredIdentity.getNodeType()),
+                    "Unexpected language extension " + requiredIdentity);
+            String prefixAndIdentityLocalName = requiredIdentity.getNodeParameter();
+            // import should point to a module
+            ServiceInterfaceEntry serviceInterfaceEntry = findSIE(prefixAndIdentityLocalName, currentModule,
+                    qNamesToSIEs, schemaContext);
+            boolean mandatory = refine.getConstraints().isMandatory();
+            AbstractDependencyAttribute reference;
+            if (dataNodeContainer instanceof ContainerSchemaNode) {
+                reference = new DependencyAttribute(attrNode, serviceInterfaceEntry, mandatory,
+                        attrNode.getDescription());
+            } else {
+                reference = new ListDependenciesAttribute(attrNode, serviceInterfaceEntry, mandatory,
+                        attrNode.getDescription());
+            }
+            return Optional.of(reference);
+        }
+        return Optional.absent();
+    }
+
+    private int getChildNodeSizeWithoutUses(DataNodeContainer csn) {
+        int result = 0;
+        for (DataSchemaNode dsn : csn.getChildNodes()) {
+            if (dsn.isAddedByUses() == false) {
+                result++;
+            }
+        }
+        return result;
+    }
+
+    private ServiceInterfaceEntry findSIE(String prefixAndIdentityLocalName, Module currentModule,
+            Map<QName, ServiceInterfaceEntry> qNamesToSIEs, SchemaContext schemaContext) {
+
+        Matcher m = PREFIX_COLON_LOCAL_NAME.matcher(prefixAndIdentityLocalName);
+        Module foundModule;
+        String localSIName;
+        if (m.matches()) {
+            // if there is a prefix, look for ModuleImport with this prefix. Get
+            // Module from SchemaContext
+            String prefix = m.group(1);
+            ModuleImport moduleImport = findModuleImport(currentModule, prefix);
+            foundModule = schemaContext.findModuleByName(moduleImport.getModuleName(), moduleImport.getRevision());
+            checkState(foundModule != null, format("Module not found in SchemaContext by %s", moduleImport));
+            localSIName = m.group(2);
+        } else {
+            foundModule = currentModule; // no prefix => SIE is in currentModule
+            localSIName = prefixAndIdentityLocalName;
+        }
+        QName siQName = new QName(foundModule.getNamespace(), foundModule.getRevision(), localSIName);
+        ServiceInterfaceEntry sie = qNamesToSIEs.get(siQName);
+        checkState(sie != null, "Cannot find referenced Service Interface by " + prefixAndIdentityLocalName);
+        return sie;
+    }
+
+    private ModuleImport findModuleImport(Module module, String prefix) {
+        for (ModuleImport moduleImport : module.getImports()) {
+            if (moduleImport.getPrefix().equals(prefix)) {
+                return moduleImport;
+            }
+        }
+        throw new IllegalStateException(format("Import not found with prefix %s in %s", prefix, module));
+    }
+
+    @VisibleForTesting
+    static Matcher getWhenConditionMatcher(String prefix, RevisionAwareXPath whenConstraint) {
+        String xpathRegex = MODULE_CONDITION_XPATH_TEMPLATE.replace(MAGIC_STRING, prefix);
+        Pattern pattern = Pattern.compile(xpathRegex);
+        return pattern.matcher(whenConstraint.toString());
+    }
+
+    String getConfigModulePrefixFromImport(Module currentModule) {
+        for (ModuleImport currentImport : currentModule.getImports()) {
+            if (currentImport.getModuleName().equals(ConfigConstants.CONFIG_MODULE)) {
+                return currentImport.getPrefix();
+            }
+        }
+        throw new IllegalArgumentException("Cannot find import " + ConfigConstants.CONFIG_MODULE + " in "
+                + currentModule);
+    }
+
+}
index 4831545..cd14458 100644 (file)
@@ -272,7 +272,7 @@ public class RuntimeBeanEntry {
                 }
                 // convert RpcDefinition to Rpc
                 for (RpcDefinition rpcDefinition : rpcDefinitions) {
-                    String name = ModuleMXBeanEntry
+                    String name = TypeProviderWrapper
                             .findJavaParameter(rpcDefinition);
                     AttributeIfc returnType;
                     if (rpcDefinition.getOutput() == null
@@ -376,7 +376,7 @@ public class RuntimeBeanEntry {
                     "More than one key is not supported in " + listSchemaNode);
         }
 
-        String javaNamePrefix = ModuleMXBeanEntry
+        String javaNamePrefix = TypeProviderWrapper
                 .findJavaNamePrefix(listSchemaNode);
 
         RuntimeBeanEntry rbFromAttributes = new RuntimeBeanEntry(packageName,
index c43fead..3c8c8aa 100644 (file)
@@ -7,12 +7,14 @@
  */
 package org.opendaylight.controller.config.yangjmxgenerator;
 
+import org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil;
 import org.opendaylight.yangtools.sal.binding.generator.spi.TypeProvider;
 import org.opendaylight.yangtools.sal.binding.model.api.Type;
 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
 
 public class TypeProviderWrapper {
     private final TypeProvider typeProvider;
@@ -21,6 +23,40 @@ public class TypeProviderWrapper {
         this.typeProvider = typeProvider;
     }
 
+    /**
+     * For input node, find if it contains config:java-name-prefix extension. If
+     * not found, convert local name of node converted to cammel case.
+     */
+    public static String findJavaNamePrefix(SchemaNode schemaNode) {
+        return convertToJavaName(schemaNode, true);
+    }
+
+    public static String findJavaParameter(SchemaNode schemaNode) {
+        return convertToJavaName(schemaNode, false);
+    }
+
+    public static String convertToJavaName(SchemaNode schemaNode,
+                                           boolean capitalizeFirstLetter) {
+        for (UnknownSchemaNode unknownNode : schemaNode.getUnknownSchemaNodes()) {
+            if (ConfigConstants.JAVA_NAME_PREFIX_EXTENSION_QNAME
+                    .equals(unknownNode.getNodeType())) {
+                String value = unknownNode.getNodeParameter();
+                return convertToJavaName(value, capitalizeFirstLetter);
+            }
+        }
+        return convertToJavaName(schemaNode.getQName().getLocalName(),
+                capitalizeFirstLetter);
+    }
+
+    public static String convertToJavaName(String localName,
+                                           boolean capitalizeFirstLetter) {
+        if (capitalizeFirstLetter) {
+            return BindingGeneratorUtil.parseToClassName(localName);
+        } else {
+            return BindingGeneratorUtil.parseToValidParamName(localName);
+        }
+    }
+
     public Type getType(LeafSchemaNode leaf) {
         TypeDefinition<?> type = leaf.getType();
         return getType(leaf, type);
index ba2edc4..edfb4c5 100644 (file)
@@ -7,7 +7,7 @@
  */
 package org.opendaylight.controller.config.yangjmxgenerator.attribute;
 
-import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
+import org.opendaylight.controller.config.yangjmxgenerator.TypeProviderWrapper;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 
 public abstract class AbstractAttribute implements AttributeIfc {
@@ -22,8 +22,8 @@ public abstract class AbstractAttribute implements AttributeIfc {
     AbstractAttribute(DataSchemaNode attrNode) {
         this.attributeYangName = getLocalName(attrNode);
         this.node = attrNode;
-        this.upperCaseCammelCase = ModuleMXBeanEntry.findJavaNamePrefix(node);
-        this.lowerCaseCammelCase = ModuleMXBeanEntry.findJavaParameter(node);
+        this.upperCaseCammelCase = TypeProviderWrapper.findJavaNamePrefix(node);
+        this.lowerCaseCammelCase = TypeProviderWrapper.findJavaParameter(node);
     }
 
     @Override
index 6a540b5..84300cb 100644 (file)
@@ -11,7 +11,6 @@ import com.google.common.base.Function;
 import com.google.common.collect.Collections2;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
-import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
 import org.opendaylight.controller.config.yangjmxgenerator.TypeProviderWrapper;
 import org.opendaylight.yangtools.binding.generator.util.ReferencedTypeImpl;
 import org.opendaylight.yangtools.sal.binding.model.api.Type;
@@ -121,7 +120,7 @@ public class TOAttribute extends AbstractAttribute implements TypedAttribute {
                 .entrySet()) {
 
             capitalizedPropertiesToTypesMap.put(
-                    ModuleMXBeanEntry.convertToJavaName(entry.getKey(), true),
+                    TypeProviderWrapper.convertToJavaName(entry.getKey(), true),
                     entry.getValue());
         }
         return capitalizedPropertiesToTypesMap;
@@ -133,7 +132,7 @@ public class TOAttribute extends AbstractAttribute implements TypedAttribute {
                 .entrySet()) {
 
             jmxPropertiesToTypesMap.put(
-                    ModuleMXBeanEntry.convertToJavaName(entry.getKey(), false),
+                    TypeProviderWrapper.convertToJavaName(entry.getKey(), false),
                     entry.getValue());
         }
         return jmxPropertiesToTypesMap;
index 9ea34ca..8ca2bb5 100644 (file)
@@ -113,6 +113,9 @@ public class ModuleMXBeanEntryTest extends AbstractYangTest {
                         , PACKAGE_NAME);
         Map<String, AttributeIfc> attributes = namesToMBEs.get("impl-netconf")
                 .getAttributes();
+
+        assertCorrectAttributesSize(namesToMBEs, attributes);
+
         //
         DependencyAttribute threadFactoryAttribute = (DependencyAttribute) attributes
                 .get("thread-factory");
@@ -132,6 +135,16 @@ public class ModuleMXBeanEntryTest extends AbstractYangTest {
         assertThat(threadFactoryAttribute.getType().getName(), is("ObjectName"));
     }
 
+    private void assertCorrectAttributesSize(Map<String, ModuleMXBeanEntry> namesToMBEs, Map<String, AttributeIfc> attributes) {
+        assertEquals(14, attributes.size());
+        assertEquals(1, namesToMBEs.get("impl-netconf").getRuntimeBeans().size());
+        assertEquals(2, namesToMBEs.get("impl-netconf").getRuntimeBeans().iterator().next().getAttributes().size());
+
+        assertEquals(4, namesToMBEs.get("impl").getAttributes().size());
+        assertEquals(1, namesToMBEs.get("impl").getRuntimeBeans().size());
+        assertEquals(1, namesToMBEs.get("impl").getRuntimeBeans().iterator().next().getAttributes().size());
+    }
+
     protected RuntimeBeanEntry findFirstByYangName(
             Collection<RuntimeBeanEntry> runtimeBeans, String yangName) {
         for (RuntimeBeanEntry rb : runtimeBeans) {
@@ -155,7 +168,7 @@ public class ModuleMXBeanEntryTest extends AbstractYangTest {
     private void assertMatches(String prefix, String input) {
         RevisionAwareXPath whenConstraint = mock(RevisionAwareXPath.class);
         doReturn(input).when(whenConstraint).toString();
-        Matcher output = ModuleMXBeanEntry.getWhenConditionMatcher(prefix,
+        Matcher output = ModuleMXBeanEntryBuilder.getWhenConditionMatcher(prefix,
                 whenConstraint);
         assertTrue(output.matches());
         assertEquals("threadpool-dynamic", output.group(1));
index 97078e0..16085ef 100644 (file)
@@ -8,8 +8,6 @@ module config-jmx-it-impl {
     import ietf-inet-types { prefix inet; revision-date 2010-09-24;}
     import config-threads { prefix th; revision-date 2013-04-09; }
 
-
-
     description
         "Testing IMPL";
 
@@ -67,19 +65,7 @@ module config-jmx-it-impl {
             }
 
         }
-    }
-
-    augment "/config:modules/config:module/config:state" {
-        case impl {
-            when "/config:modules/config:module/config:type = 'impl'";
-            // root runtime bean
-            leaf created-sessions {
-                type uint32;
-            }
-        }
-    }
 
-    augment "/config:modules/config:module/config:configuration" {
         case impl-netconf {
             when "/config:modules/config:module/config:type = 'impl-netconf'";
 
@@ -205,6 +191,14 @@ module config-jmx-it-impl {
     }
 
     augment "/config:modules/config:module/config:state" {
+        case impl {
+            when "/config:modules/config:module/config:type = 'impl'";
+            // root runtime bean
+            leaf created-sessions {
+                type uint32;
+            }
+        }
+
         case impl-netconf {
             when "/config:modules/config:module/config:type = 'impl-netconf'";
             // root runtime bean
@@ -212,6 +206,11 @@ module config-jmx-it-impl {
                 type uint32;
             }
 
+            leaf created-sessions-2 {
+                type uint32;
+            }
+
         }
     }
+
 }
index 9c6e98e..9037ff0 100644 (file)
             <plugin>
                 <groupId>org.opendaylight.yangtools</groupId>
                 <artifactId>yang-maven-plugin</artifactId>
-                <version>${yangtools.version}</version>
                 <executions>
                     <execution>
                         <id>config</id>
index 2123f6b..ee571b8 100644 (file)
@@ -13,4 +13,12 @@ package org.opendaylight.controller.configuration;
  * Container configuration service
  */
 public interface IConfigurationContainerService extends IConfigurationServiceCommon {
+
+    /**
+     * Bundle will call this function to ask ContainerConfigurationService to provide the
+     * directory location of container
+     *
+     * @return The path to active container directory
+     */
+    String getConfigurationRoot();
 }
index e4d55d1..4c0f3a2 100644 (file)
@@ -9,6 +9,7 @@
 
 package org.opendaylight.controller.configuration.internal;
 
+import java.io.File;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.EnumSet;
@@ -25,6 +26,7 @@ import org.opendaylight.controller.clustering.services.IClusterServices;
 import org.opendaylight.controller.configuration.ConfigurationEvent;
 import org.opendaylight.controller.configuration.ConfigurationObject;
 import org.opendaylight.controller.configuration.IConfigurationAware;
+import org.opendaylight.controller.configuration.IConfigurationContainerService;
 import org.opendaylight.controller.configuration.IConfigurationService;
 import org.opendaylight.controller.sal.utils.GlobalConstants;
 import org.opendaylight.controller.sal.utils.IObjectReader;
@@ -46,7 +48,7 @@ public class ConfigurationService implements IConfigurationService, ICacheUpdate
     private static final Logger logger = LoggerFactory
             .getLogger(ConfigurationService.class);
     public static final String SAVE_EVENT_CACHE = "config.event.save";
-    private static final Object ROOT = GlobalConstants.STARTUPHOME.toString();
+    private static final String ROOT = GlobalConstants.STARTUPHOME.toString();
     private IClusterGlobalServices clusterServices;
     private ConcurrentMap <ConfigurationEvent, String> configEvent;
     private Set<IConfigurationAware> configurationAwareList = Collections
@@ -105,21 +107,66 @@ public class ConfigurationService implements IConfigurationService, ICacheUpdate
         return saveConfigurationsInternal();
     }
 
+
+    private List<String> getContainerDirectoryList() {
+        List<String> containerList = new ArrayList<String>();
+        for (IConfigurationAware configurationAware : this.configurationAwareList) {
+            if (configurationAware instanceof IConfigurationContainerService) {
+                String containerFilePath = ((ContainerConfigurationService)configurationAware).getConfigurationRoot();
+                containerList.add(containerFilePath);
+            }
+        }
+        return containerList;
+    }
+
+    private void createContainerDirectory(IConfigurationAware configurationAware) {
+        String containerFilePath = ((ContainerConfigurationService) configurationAware).getConfigurationRoot();
+        if (!new File(containerFilePath).exists()) {
+            boolean created = new File(containerFilePath).mkdir();
+            if (!created) {
+               logger.error("Failed to create startup config directory: {}", containerFilePath);
+            }
+        }
+    }
+
+    private void clearStaleContainerDirectories() {
+        List<String> activeContainers = getContainerDirectoryList();
+        for (File file : new File(ROOT).listFiles()) {
+            if (file.isDirectory() && !activeContainers.contains(file.toPath() + File.separator)) {
+                logger.trace("Removing directory for container {}", file.getName());
+                for (File innerFile : file.listFiles()) {
+                      innerFile.delete();
+                }
+                boolean removed = file.delete();
+                if (!removed) {
+                   logger.warn("Failed to remove stale directory: {}", file.getName());
+                }
+            }
+        }
+    }
+
+
     private Status saveConfigurationsInternal() {
         boolean success = true;
         for (IConfigurationAware configurationAware : configurationAwareList) {
+            if (configurationAware instanceof IConfigurationContainerService) {
+                // Create directory for new containers
+                createContainerDirectory(configurationAware);
+            }
             Status status = configurationAware.saveConfiguration();
             if (!status.isSuccess()) {
                 success = false;
-                logger.warn("Failed to save config for {}",
-                        configurationAware.getClass().getName());
+                logger.warn("Failed to save config for {}", configurationAware.getClass().getName());
             }
         }
+        // Remove startup directories of containers that were removed from
+        // the configuration but not saved
+        clearStaleContainerDirectories();
+
         if (success) {
             return new Status(StatusCode.SUCCESS);
         } else {
-            return new Status(StatusCode.INTERNALERROR,
-                    "Failed to Save All Configurations");
+            return new Status(StatusCode.INTERNALERROR, "Failed to Save All Configurations");
         }
     }
 
index 9c1d391..3e06725 100644 (file)
@@ -9,7 +9,6 @@
 
 package org.opendaylight.controller.configuration.internal;
 
-import java.io.File;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Dictionary;
@@ -52,14 +51,10 @@ public class ContainerConfigurationService implements IConfigurationContainerSer
     private static final Logger logger = LoggerFactory.getLogger(ContainerConfigurationService.class);
     private IClusterContainerServices clusterServices;
     private ConcurrentMap <ConfigurationEvent, String> containerConfigEvent;
-    /*
-     * Collection containing the configuration objects.
-     * This is configuration world: container names (also the map key)
-     * are maintained as they were configured by user, same case
-     */
+    // Directory which contains the startup files for this container
+    private String root;
     private Set<IConfigurationContainerAware> configurationAwareList = Collections
             .synchronizedSet(new HashSet<IConfigurationContainerAware>());
-    private String root;
     private ObjectReader objReader;
     private ObjectWriter objWriter;
 
@@ -93,14 +88,9 @@ public class ContainerConfigurationService implements IConfigurationContainerSer
 
     void init(Component c) {
         Dictionary<?, ?> props = c.getServiceProperties();
-        String containerName = (props != null) ? (String) props.get("containerName") : GlobalConstants.DEFAULT.toString();
-        root = String.format("%s%s/", GlobalConstants.STARTUPHOME.toString(), containerName);
-        if (!new File(root).exists()) {
-            boolean created = new File(root).mkdir();
-            if (!created) {
-                logger.error("Failed to create startup config directory for container {}", containerName);
-            }
-        }
+        String containerName = (props != null) ? (String) props.get("containerName") :
+            GlobalConstants.DEFAULT.toString();
+        root =  String.format("%s%s/", GlobalConstants.STARTUPHOME.toString(), containerName);
     }
 
     public void start() {
@@ -119,17 +109,18 @@ public class ContainerConfigurationService implements IConfigurationContainerSer
      * Function called by the dependency manager before Container is Stopped and Destroyed.
      */
     public void containerStop() {
-        // Remove container directory along with its startup files
-        File[] files = new File(root).listFiles();
-        for (File file : files) {
-            file.delete();
-        }
-        new File(root).delete();
+        // Do nothing
+    }
+
+    @Override
+    public String getConfigurationRoot() {
+        return root;
     }
 
     @Override
     public Status saveConfiguration() {
         boolean success = true;
+
         for (IConfigurationContainerAware configurationAware : configurationAwareList) {
             logger.trace("Save Config triggered for {}", configurationAware.getClass().getSimpleName());
 
index 7de4396..3bd7ea1 100644 (file)
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>clustering.services</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>connectionmanager</artifactId>
-      <version>0.1.2-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.7.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal.connection</artifactId>
-      <version>0.1.2-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>equinoxSDK381</groupId>
index ad897fd..0fee183 100644 (file)
@@ -9,7 +9,6 @@
 
 package org.opendaylight.controller.containermanager.internal;
 
-import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.ObjectInputStream;
@@ -751,26 +750,6 @@ public class ContainerManager extends Authorization<String> implements IContaine
         return status;
     }
 
-    private void removeComponentsStartUpfiles(String containerName) {
-        String startupLocation = String.format("./%s", GlobalConstants.STARTUPHOME.toString());
-        String containerPrint = String.format("_%s.", containerName.toLowerCase(Locale.ENGLISH));
-
-        File directory = new File(startupLocation);
-        String[] fileList = directory.list();
-
-        logger.trace("Deleting startup configuration files for container {}", containerName);
-        if (fileList != null) {
-            for (String fileName : fileList) {
-                if (fileName.contains(containerPrint)) {
-                    String fullPath = String.format("%s/%s", startupLocation, fileName);
-                    File file = new File(fullPath);
-                    boolean done = file.delete();
-                    logger.trace("{} {}", (done ? "Deleted: " : "Failed to delete: "), fileName);
-                }
-            }
-        }
-    }
-
     /**
      * Create and initialize default all resource group and create association
      * with default well known users and profiles, if not already learnt from
@@ -1013,19 +992,6 @@ public class ContainerManager extends Authorization<String> implements IContaine
         notifyContainerModeChange(delete, notifyLocal);
         // Notify listeners
         notifyContainerAwareListeners(container, delete);
-
-        /*
-         * This is a quick fix until configuration service becomes the
-         * centralized configuration management place. Here container manager
-         * will remove the startup files for all the bundles that are present in
-         * the container being deleted. Do the cleanup here in Container manger
-         * as do not want to put this temporary code in Configuration manager
-         * yet which is ODL.
-         */
-        if (delete) {
-            // TODO: remove when Config Mgr takes over
-            removeComponentsStartUpfiles(containerName);
-        }
     }
 
     private void notifyContainerEntryChangeInternal(String containerName, List<NodeConnector> ncList, UpdateType update, boolean notifyLocal) {
index 5aba5ca..79b9cce 100644 (file)
         <dependency>
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>sal-common</artifactId>
-          <version>${mdsal.version}</version>
         </dependency>
         <dependency>
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>sal-common-util</artifactId>
-          <version>${mdsal.version}</version>
         </dependency>
         <dependency>
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>sal-netconf-connector</artifactId>
-          <version>${mdsal.version}</version>
         </dependency>
         <dependency>
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>sal-core-api</artifactId>
-          <version>${mdsal.version}</version>
         </dependency>
         <dependency>
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>sal-broker-impl</artifactId>
-          <version>${mdsal.version}</version>
+        </dependency>
+        <dependency>
+          <groupId>org.opendaylight.controller</groupId>
+          <artifactId>sal-remote</artifactId>
+        </dependency>
+        <dependency>
+          <groupId>org.opendaylight.controller</groupId>
+          <artifactId>sal-restconf-broker</artifactId>
         </dependency>
         <dependency>
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>sal-core-spi</artifactId>
-          <version>${mdsal.version}</version>
         </dependency>
         <dependency>
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>sal-common-api</artifactId>
-          <version>${mdsal.version}</version>
         </dependency>
         <dependency>
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>sal-common-impl</artifactId>
-          <version>${mdsal.version}</version>
         </dependency>
         <dependency>
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>sal-binding-api</artifactId>
-          <version>${mdsal.version}</version>
         </dependency>
         <dependency>
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>sal-binding-config</artifactId>
-          <version>${mdsal.version}</version>
         </dependency>
         <dependency>
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>sal-binding-broker-impl</artifactId>
-          <version>${mdsal.version}</version>
         </dependency>
         <dependency>
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>sal-compatibility</artifactId>
-          <version>${mdsal.version}</version>
         </dependency>
         <dependency>
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>sal-connector-api</artifactId>
-          <version>${mdsal.version}</version>
         </dependency>
         <dependency>
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>sal-rest-connector</artifactId>
-          <version>${mdsal.version}</version>
         </dependency>
         <dependency>
           <groupId>org.opendaylight.controller.model</groupId>
           <artifactId>model-inventory</artifactId>
-          <version>${mdsal.version}</version>
         </dependency>
         <dependency>
           <groupId>org.opendaylight.controller.model</groupId>
           <artifactId>model-flow-base</artifactId>
-          <version>${mdsal.version}</version>
         </dependency>
         <dependency>
           <groupId>org.opendaylight.controller.model</groupId>
           <artifactId>model-flow-service</artifactId>
-          <version>${mdsal.version}</version>
         </dependency>
         <dependency>
           <groupId>org.opendaylight.controller.model</groupId>
           <artifactId>model-flow-statistics</artifactId>
-          <version>${mdsal.version}</version>
         </dependency>
         <dependency>
           <groupId>org.opendaylight.controller.model</groupId>
           <artifactId>model-flow-management</artifactId>
-          <version>${mdsal.version}</version>
         </dependency>
         <dependency>
           <groupId>org.opendaylight.controller.md</groupId>
           <artifactId>inventory-manager</artifactId>
-          <version>${mdsal.version}</version>
         </dependency>
         <dependency>
           <groupId>org.opendaylight.controller.md</groupId>
           <artifactId>forwardingrules-manager</artifactId>
-          <version>${mdsal.version}</version>
         </dependency>
         <dependency>
           <groupId>org.opendaylight.controller.md</groupId>
           <artifactId>topology-lldp-discovery</artifactId>
-          <version>${mdsal.version}</version>
         </dependency>
         <dependency>
           <groupId>org.opendaylight.controller.md</groupId>
           <artifactId>topology-manager</artifactId>
-          <version>${mdsal.version}</version>
         </dependency>
         <dependency>
-            <groupId>org.opendaylight.controller.model</groupId>
-            <artifactId>model-topology</artifactId>
-            <version>1.1-SNAPSHOT</version>
+          <groupId>org.opendaylight.controller.model</groupId>
+          <artifactId>model-topology</artifactId>
+          <version>1.1-SNAPSHOT</version>
         </dependency>
         <dependency>
          <groupId>org.opendaylight.yangtools.model</groupId>
          <artifactId>ietf-topology</artifactId>
         </dependency>
         <dependency>
-            <groupId>org.opendaylight.controller</groupId>
-            <artifactId>sal-binding-util</artifactId>
-            <version>1.1-SNAPSHOT</version>
+          <groupId>org.opendaylight.controller</groupId>
+          <artifactId>sal-binding-util</artifactId>
         </dependency>
         <dependency>
           <groupId>org.opendaylight.controller.md</groupId>
           <artifactId>statistics-manager</artifactId>
-          <version>${mdsal.version}</version>
         </dependency>
         <dependency>
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>concepts</artifactId>
-          <version>${concepts.version}</version>
         </dependency>
         <dependency>
           <groupId>org.opendaylight.controller</groupId>
         <dependency>
           <groupId>org.opendaylight.yangtools</groupId>
           <artifactId>concepts</artifactId>
-          <version>${yangtools.version}</version>
+        </dependency>
+        <dependency>
+          <groupId>org.opendaylight.yangtools</groupId>
+          <artifactId>restconf-client-api</artifactId>
+        </dependency>
+        <dependency>
+          <groupId>org.opendaylight.yangtools</groupId>
+          <artifactId>restconf-client-impl</artifactId>
         </dependency>
 
         <!-- config-->
         <dependency>
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>config-api</artifactId>
-          <version>${config.version}</version>
         </dependency>
         <dependency>
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>config-manager</artifactId>
-          <version>${config.version}</version>
         </dependency>
         <dependency>
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>yang-jmx-generator</artifactId>
-          <version>${config.version}</version>
         </dependency>
         <dependency>
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>yang-store-api</artifactId>
-          <version>${config.version}</version>
         </dependency>
         <dependency>
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>yang-store-impl</artifactId>
-          <version>${config.version}</version>
         </dependency>
         <dependency>
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>logback-config</artifactId>
-          <version>${config.version}</version>
         </dependency>
         <dependency>
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>config-persister-api</artifactId>
-          <version>${config.version}</version>
         </dependency>
         <dependency>
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>config-persister-file-adapter</artifactId>
-          <version>${config.version}</version>
         </dependency>
         <dependency>
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>config-persister-file-xml-adapter</artifactId>
-          <version>${config.version}</version>
         </dependency>
         <dependency>
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>config-persister-directory-adapter</artifactId>
-          <version>${config.version}</version>
         </dependency>
         <dependency>
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>config-persister-directory-xml-adapter</artifactId>
-          <version>${config.version}</version>
         </dependency>
         <dependency>
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>config-persister-directory-autodetect-adapter</artifactId>
-          <version>${config.version}</version>
         </dependency>
 
         <dependency>
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>shutdown-api</artifactId>
-          <version>${config.version}</version>
         </dependency>
         <dependency>
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>shutdown-impl</artifactId>
-          <version>${config.version}</version>
         </dependency>
 
        <!-- Netconf -->
         <dependency>
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>netconf-api</artifactId>
-          <version>${netconf.version}</version>
         </dependency>
         <dependency>
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>netconf-impl</artifactId>
-          <version>${netconf.version}</version>
         </dependency>
         <dependency>
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>netconf-util</artifactId>
-          <version>${netconf.version}</version>
         </dependency>
         <dependency>
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>netconf-client</artifactId>
-          <version>${netconf.version}</version>
         </dependency>
         <dependency>
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>netconf-mapping-api</artifactId>
-          <version>${netconf.version}</version>
         </dependency>
         <dependency>
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>netconf-ssh</artifactId>
-          <version>${netconf.version}</version>
         </dependency>
         <dependency>
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>config-netconf-connector</artifactId>
-          <version>${netconf.version}</version>
         </dependency>
         <dependency>
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>netconf-monitoring</artifactId>
-          <version>${netconf.version}</version>
         </dependency>
         <dependency>
           <groupId>${project.groupId}</groupId>
           <artifactId>ietf-netconf-monitoring</artifactId>
-          <version>${netconf.version}</version>
         </dependency>
         <dependency>
           <groupId>${project.groupId}</groupId>
           <artifactId>ietf-netconf-monitoring-extension</artifactId>
-          <version>${netconf.version}</version>
         </dependency>
         <dependency>
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>config-persister-impl</artifactId>
-          <version>${netconf.version}</version>
         </dependency>
         <dependency>
             <groupId>org.apache.servicemix.bundles</groupId>
           <dependency>
               <groupId>org.opendaylight.controller</groupId>
               <artifactId>threadpool-config-api</artifactId>
-              <version>${config.version}</version>
           </dependency>
           <dependency>
               <groupId>org.opendaylight.controller</groupId>
               <artifactId>netty-config-api</artifactId>
-              <version>${config.version}</version>
           </dependency>
           <dependency>
               <groupId>org.opendaylight.controller</groupId>
               <artifactId>threadpool-config-impl</artifactId>
-              <version>${config.version}</version>
           </dependency>
           <dependency>
               <groupId>org.opendaylight.controller</groupId>
               <artifactId>netty-threadgroup-config</artifactId>
-              <version>${config.version}</version>
           </dependency>
           <dependency>
               <groupId>org.opendaylight.controller</groupId>
               <artifactId>netty-event-executor-config</artifactId>
-              <version>${config.version}</version>
           </dependency>
           <dependency>
               <groupId>org.opendaylight.controller</groupId>
               <artifactId>netty-timer-config</artifactId>
-              <version>${config.version}</version>
           </dependency>
 
-
           <!-- toaster example I'm pretty sure we should trim -->
          <dependency>
           <groupId>org.opendaylight.controller.samples</groupId>
          <dependency>
           <groupId>org.opendaylight.yangtools</groupId>
           <artifactId>yang-binding</artifactId>
-          <version>${yangtools.version}</version>
          </dependency>
          <dependency>
           <groupId>org.opendaylight.yangtools</groupId>
          <dependency>
           <groupId>org.opendaylight.yangtools</groupId>
           <artifactId>yang-model-util</artifactId>
-          <version>${yangtools.version}</version>
          </dependency>
          <dependency>
           <groupId>org.opendaylight.yangtools</groupId>
index 8db8a0b..f7bbdc1 100644 (file)
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>configuration</artifactId>
-      <version>0.4.2-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>clustering.services</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.7.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal.connection</artifactId>
-      <version>0.1.2-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>forwardingrulesmanager</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>equinoxSDK381</groupId>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>connectionmanager</artifactId>
-      <version>0.1.2-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>containermanager</artifactId>
-      <version>0.5.2-SNAPSHOT</version>
     </dependency>
   </dependencies>
 </project>
index 41db8af..fc0ef32 100644 (file)
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal-common-util</artifactId>
-      <version>1.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal-binding-api</artifactId>
-      <version>1.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.slf4j</groupId>
     <dependency>
       <groupId>org.opendaylight.controller.model</groupId>
       <artifactId>model-flow-management</artifactId>
-      <version>1.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>forwardingrulesmanager</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal-compatibility</artifactId>
-      <version>1.1-SNAPSHOT</version>
     </dependency>
 
   </dependencies>
index 46f1c4f..b7e193b 100644 (file)
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>sal-common-util</artifactId>
-            <version>1.1-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>sal-binding-api</artifactId>
-            <version>1.1-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>switchmanager</artifactId>
-            <version>0.7.1-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>topologymanager</artifactId>
-            <version>0.4.2-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>org.slf4j</groupId>
         <dependency>
             <groupId>org.opendaylight.controller.model</groupId>
             <artifactId>model-flow-management</artifactId>
-            <version>1.1-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>sal-binding-util</artifactId>
-            <version>1.1-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.controller.model</groupId>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>forwardingrulesmanager</artifactId>
-            <version>0.5.1-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>sal-compatibility</artifactId>
-            <version>1.1-SNAPSHOT</version>
         </dependency>
     </dependencies>
 </project>
index 606cf21..c5c5cd3 100644 (file)
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>sal</artifactId>
-            <version>0.7.1-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.controller.model</groupId>
             <artifactId>model-flow-service</artifactId>
-            <version>1.1-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>sal-common-util</artifactId>
-            <version>1.1-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>sal-binding-api</artifactId>
-            <version>1.1-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>com.google.guava</groupId>
index daef089..6914ef3 100644 (file)
@@ -18,7 +18,6 @@
     <dependency>
       <groupId>org.opendaylight.controller.model</groupId>
       <artifactId>model-flow-statistics</artifactId>
-      <version>1.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller.model</groupId>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal-binding-util</artifactId>
-      <version>1.1-SNAPSHOT</version>
     </dependency>
     <dependency>
         <groupId>org.opendaylight.controller</groupId>
         <artifactId>clustering.services</artifactId>
-        <version>0.5.1-SNAPSHOT</version>
     </dependency>
   </dependencies>
   <packaging>bundle</packaging>
index a6fc4b0..a59c2c1 100644 (file)
@@ -251,6 +251,7 @@ package class SalCompatibilityProvider implements BindingAwareProvider {
         topology.dataService = session.getSALService(DataProviderService)
         tpProvider.dataService = session.getSALService(DataProviderService)
 
+        inventory.start();
 
         tpProvider.start();
 
index fac12ee..8a0874e 100644 (file)
@@ -199,9 +199,11 @@ class FlowProgrammerAdapter implements IPluginInFlowProgrammerService, SalFlowLi
     }
 
     private def Future<RpcResult<TransactionStatus>> internalModifyFlowAsync(Node node, Flow oldFlow, Flow newFlow, long rid) {
-        val flowId = getCache().remove(oldFlow);
+        var flowId = getCache().remove(oldFlow);
         if(flowId == null){
-            throw new IllegalArgumentException("oldFlow is unknown");
+            LOG.error("oldFlow not found in cache : " + oldFlow.hashCode);
+            flowId = UUID.randomUUID();
+            getCache().put(oldFlow, flowId);
         }
 
         getCache().put(newFlow, flowId);
@@ -212,7 +214,9 @@ class FlowProgrammerAdapter implements IPluginInFlowProgrammerService, SalFlowLi
     private def Future<RpcResult<TransactionStatus>> internalRemoveFlowAsync(Node node, Flow adflow, long rid){
         val flowId = getCache().remove(adflow);
         if(flowId == null){
-            throw new IllegalArgumentException("adflow is unknown");
+            //throw new IllegalArgumentException("adflow not found in cache : " + adflow.hashCode);
+            LOG.error("adflow not found in cache : " + adflow.hashCode);
+            return null;
         }
         val flow = adflow.toMDFlow(flowId.toString());
         val modification = this._dataBrokerService.beginTransaction();
@@ -227,6 +231,10 @@ class FlowProgrammerAdapter implements IPluginInFlowProgrammerService, SalFlowLi
     }
 
     private def toFutureStatus(Future<RpcResult<TransactionStatus>> future){
+        if(future == null){
+            return toStatus(true);
+        }
+
         try {
             val result = future.get();
             return toStatus(result);
index 60e4324..0c211fd 100644 (file)
@@ -11,6 +11,9 @@ import java.util.ArrayList
 import java.util.Collections
 import java.util.List
 import java.util.Set
+import java.util.ArrayList;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.concurrent.locks.Lock;
 import java.util.concurrent.CopyOnWriteArrayList;
 import org.opendaylight.controller.sal.binding.api.data.DataBrokerService
 import org.opendaylight.controller.sal.binding.api.data.DataProviderService
@@ -76,17 +79,18 @@ import static extension org.opendaylight.controller.sal.compatibility.NodeMappin
 import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader
 import java.util.concurrent.ConcurrentHashMap
 import java.util.Map
+import java.util.HashMap
 
 class InventoryAndReadAdapter implements IPluginInReadService,
-                                                                                        IPluginInInventoryService,
-                                                                                        OpendaylightInventoryListener,
-                                                                                        OpendaylightFlowStatisticsListener,
-                                                                                        OpendaylightFlowTableStatisticsListener,
-                                                                                        OpendaylightPortStatisticsListener {
+                                             IPluginInInventoryService,
+                                             OpendaylightInventoryListener,
+                                             OpendaylightFlowStatisticsListener,
+                                             OpendaylightFlowTableStatisticsListener,
+                                             OpendaylightPortStatisticsListener {
 
     private static val LOG = LoggerFactory.getLogger(InventoryAndReadAdapter);
 
-       private static val OPENFLOWV10_TABLE_ID = new Integer(0).shortValue;
+    private static val OPENFLOWV10_TABLE_ID = new Integer(0).shortValue;
     @Property
     DataBrokerService dataService;
 
@@ -111,21 +115,34 @@ class InventoryAndReadAdapter implements IPluginInReadService,
     @Property
     List<IPluginOutInventoryService> inventoryPublisher = new CopyOnWriteArrayList<IPluginOutInventoryService>();
 
-       def setInventoryPublisher(IPluginOutInventoryService listener){
+    private final InventoryNotificationProvider inventoryNotificationProvider = new InventoryNotificationProvider();
+
+    private final Map<InstanceIdentifier.PathArgument, List<InstanceIdentifier.PathArgument>> nodeToNodeConnectorsMap = new ConcurrentHashMap<InstanceIdentifier.PathArgument, List<InstanceIdentifier.PathArgument>>();
+
+    private final Lock nodeToNodeConnectorsLock = new ReentrantLock();
+
+
+    def start(){
+        inventoryNotificationProvider.dataProviderService = dataProviderService;
+        inventoryNotificationProvider.inventoryPublisher = inventoryPublisher;
+        // inventoryNotificationProvider.start();
+    }
+
+    def setInventoryPublisher(IPluginOutInventoryService listener){
         inventoryPublisher.add(listener);
-       }
+    }
 
-       def unsetInventoryPublisher(IPluginOutInventoryService listener){
+    def unsetInventoryPublisher(IPluginOutInventoryService listener){
         inventoryPublisher.remove(listener);
-       }
+    }
 
     def setReadPublisher(IPluginOutReadService listener) {
-       statisticsPublisher.add(listener);
+        statisticsPublisher.add(listener);
     }
     
     def unsetReadPublisher (IPluginOutReadService listener) {
-       if( listener != null)
-               statisticsPublisher.remove(listener);
+        if( listener != null)
+            statisticsPublisher.remove(listener);
     }
 
     protected def startChange() {
@@ -140,33 +157,33 @@ class InventoryAndReadAdapter implements IPluginInReadService,
     override readAllFlow(Node node, boolean cached) {
 
         val output = new ArrayList<FlowOnNode>();
-               val tableRef = InstanceIdentifier.builder(Nodes)
-                                                                               .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(node))
-                                                       .augmentation(FlowCapableNode).child(Table, new TableKey(OPENFLOWV10_TABLE_ID)).toInstance();
-               
-               val it = this.startChange();
-               
-               val table= it.readConfigurationData(tableRef) as Table;
-               
-               if(table != null){
-                       LOG.trace("Number of flows installed in table 0 of node {} : {}",node,table.flow.size);
-                       
-                       for(flow : table.flow){
-                               
-                               val adsalFlow = ToSalConversionsUtils.toFlow(flow,node);
-                               val statsFromDataStore = flow.getAugmentation(FlowStatisticsData);
-                               
-                               if(statsFromDataStore != null){
-                                       val it = new FlowOnNode(adsalFlow);
-                                       byteCount =  statsFromDataStore.flowStatistics.byteCount.value.longValue;
-                                       packetCount = statsFromDataStore.flowStatistics.packetCount.value.longValue;
-                                       durationSeconds = statsFromDataStore.flowStatistics.duration.second.value.intValue;
-                                       durationNanoseconds = statsFromDataStore.flowStatistics.duration.nanosecond.value.intValue;
-                                       
-                                       output.add(it);
-                               }
-                       }
-               }
+        val tableRef = InstanceIdentifier.builder(Nodes)
+                                        .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(node))
+                                        .augmentation(FlowCapableNode).child(Table, new TableKey(OPENFLOWV10_TABLE_ID)).toInstance();
+        
+        val it = this.startChange();
+        
+        val table= it.readConfigurationData(tableRef) as Table;
+        
+        if(table != null){
+            LOG.trace("Number of flows installed in table 0 of node {} : {}",node,table.flow.size);
+            
+            for(flow : table.flow){
+                
+                val adsalFlow = ToSalConversionsUtils.toFlow(flow,node);
+                val statsFromDataStore = flow.getAugmentation(FlowStatisticsData);
+                
+                if(statsFromDataStore != null){
+                    val it = new FlowOnNode(adsalFlow);
+                    byteCount =  statsFromDataStore.flowStatistics.byteCount.value.longValue;
+                    packetCount = statsFromDataStore.flowStatistics.packetCount.value.longValue;
+                    durationSeconds = statsFromDataStore.flowStatistics.duration.second.value.intValue;
+                    durationNanoseconds = statsFromDataStore.flowStatistics.duration.nanosecond.value.intValue;
+                    
+                    output.add(it);
+                }
+            }
+        }
         
         //TODO (main): Shell we send request to the switch? It will make async request to the switch.
         // Once plugin receive response, it will let adaptor know through onFlowStatisticsUpdate()
@@ -180,35 +197,35 @@ class InventoryAndReadAdapter implements IPluginInReadService,
     }
 
     override readAllNodeConnector(Node node, boolean cached) {
-       
-       val ret = new ArrayList<NodeConnectorStatistics>();
-               val nodeRef = InstanceIdentifier.builder(Nodes)
-                                                                       .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(node))
-                                                                       .toInstance();
-               
-               val provider = this.startChange();
-               
-               val dsNode= provider.readConfigurationData(nodeRef) as org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
-               
-               if(dsNode != null){
-                       
-                       for (dsNodeConnector : dsNode.nodeConnector){
-                               val nodeConnectorRef = InstanceIdentifier.builder(Nodes)
-                                                                       .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(node))
-                                                                       .child(NodeConnector, dsNodeConnector.key)
-                                                                       .toInstance();
-                               
-                               val nodeConnectorFromDS = provider.readConfigurationData(nodeConnectorRef) as NodeConnector;
-                               
-                               if(nodeConnectorFromDS != null){
-                                       val nodeConnectorStatsFromDs = nodeConnectorFromDS.getAugmentation(FlowCapableNodeConnectorStatisticsData) as FlowCapableNodeConnectorStatistics;
-                                       
-                                       ret.add(toNodeConnectorStatistics(nodeConnectorStatsFromDs.flowCapableNodeConnectorStatistics,dsNode.id,dsNodeConnector.id));
-                               }
-                       }
-               }
-
-               //TODO: Refer TODO (main)
+        
+        val ret = new ArrayList<NodeConnectorStatistics>();
+        val nodeRef = InstanceIdentifier.builder(Nodes)
+                                    .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(node))
+                                    .toInstance();
+        
+        val provider = this.startChange();
+        
+        val dsNode= provider.readConfigurationData(nodeRef) as org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+        
+         if(dsNode != null){
+             
+             for (dsNodeConnector : dsNode.nodeConnector){
+                val nodeConnectorRef = InstanceIdentifier.builder(Nodes)
+                                    .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(node))
+                                    .child(NodeConnector, dsNodeConnector.key)
+                                    .toInstance();
+                 
+                 val nodeConnectorFromDS = provider.readConfigurationData(nodeConnectorRef) as NodeConnector;
+                 
+                 if(nodeConnectorFromDS != null){
+                     val nodeConnectorStatsFromDs = nodeConnectorFromDS.getAugmentation(FlowCapableNodeConnectorStatisticsData) as FlowCapableNodeConnectorStatistics;
+                     
+                    ret.add(toNodeConnectorStatistics(nodeConnectorStatsFromDs.flowCapableNodeConnectorStatistics,dsNode.id,dsNodeConnector.id));
+                 }
+             }
+         }
+
+        //TODO: Refer TODO (main)
         val input = new GetAllNodeConnectorsStatisticsInputBuilder();
         input.setNode(node.toNodeRef);
         nodeConnectorStatisticsService.getAllNodeConnectorsStatistics(input.build());
@@ -216,23 +233,23 @@ class InventoryAndReadAdapter implements IPluginInReadService,
     }
 
     override readAllNodeTable(Node node, boolean cached) {
-       val ret = new ArrayList<NodeTableStatistics>();
-       
-               val dsFlowCapableNode= readFlowCapableNode(node.toNodeRef)
-               
-               if(dsFlowCapableNode != null){
-                       
-                       for (table : dsFlowCapableNode.table){
-                               
-                               val tableStats = table.getAugmentation(FlowTableStatisticsData);
-                               
-                               if(tableStats != null){
-                                       ret.add(toNodeTableStatistics(tableStats.flowTableStatistics,table.id,node));
-                               }
-                       }
-               }
-
-               //TODO: Refer TODO (main)
+        val ret = new ArrayList<NodeTableStatistics>();
+        
+        val dsFlowCapableNode= readFlowCapableNode(node.toNodeRef)
+        
+         if(dsFlowCapableNode != null){
+             
+             for (table : dsFlowCapableNode.table){
+                 
+                 val tableStats = table.getAugmentation(FlowTableStatisticsData);
+                 
+                 if(tableStats != null){
+                     ret.add(toNodeTableStatistics(tableStats.flowTableStatistics,table.id,node));
+                 }
+             }
+         }
+
+        //TODO: Refer TODO (main)
         val input = new GetFlowTablesStatisticsInputBuilder();
         input.setNode(node.toNodeRef);
         flowTableStatisticsService.getFlowTablesStatistics(input.build);
@@ -241,39 +258,39 @@ class InventoryAndReadAdapter implements IPluginInReadService,
 
     override readDescription(Node node, boolean cached) {
         return toNodeDescription(node.toNodeRef);
-       }
+    }
 
     override readFlow(Node node, Flow targetFlow, boolean cached) {
-               var FlowOnNode ret= null;
-               
-               val tableRef = InstanceIdentifier.builder(Nodes)
-                                                                               .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(node))
-                                                       .augmentation(FlowCapableNode).child(Table, new TableKey(OPENFLOWV10_TABLE_ID)).toInstance();
-               
-               val it = this.startChange();
-               
-               val table= it.readConfigurationData(tableRef) as Table;
-               
-               if(table != null){
-                       LOG.trace("Number of flows installed in table 0 of node {} : {}",node,table.flow.size);
-                       
-                       for(mdsalFlow : table.flow){
-                               if(FromSalConversionsUtils.flowEquals(mdsalFlow, MDFlowMapping.toMDSalflow(targetFlow))){
-                                       val statsFromDataStore = mdsalFlow.getAugmentation(FlowStatisticsData);
-                                       
-                                       if(statsFromDataStore != null){
-                                               LOG.debug("Found matching flow in the data store flow table ");
-                                               val it = new FlowOnNode(targetFlow);
-                                               byteCount =  statsFromDataStore.flowStatistics.byteCount.value.longValue;
-                                               packetCount = statsFromDataStore.flowStatistics.packetCount.value.longValue;
-                                               durationSeconds = statsFromDataStore.flowStatistics.duration.second.value.intValue;
-                                               durationNanoseconds = statsFromDataStore.flowStatistics.duration.nanosecond.value.intValue;
-                                               
-                                               ret = it;
-                                       }
-                               }                       
-                       }
-               }
+        var FlowOnNode ret= null;
+        
+        val tableRef = InstanceIdentifier.builder(Nodes)
+                                        .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(node))
+                                        .augmentation(FlowCapableNode).child(Table, new TableKey(OPENFLOWV10_TABLE_ID)).toInstance();
+        
+        val it = this.startChange();
+        
+        val table= it.readConfigurationData(tableRef) as Table;
+        
+        if(table != null){
+            LOG.trace("Number of flows installed in table 0 of node {} : {}",node,table.flow.size);
+            
+            for(mdsalFlow : table.flow){
+                if(FromSalConversionsUtils.flowEquals(mdsalFlow, MDFlowMapping.toMDSalflow(targetFlow))){
+                    val statsFromDataStore = mdsalFlow.getAugmentation(FlowStatisticsData);
+                    
+                    if(statsFromDataStore != null){
+                        LOG.debug("Found matching flow in the data store flow table ");
+                        val it = new FlowOnNode(targetFlow);
+                        byteCount =  statsFromDataStore.flowStatistics.byteCount.value.longValue;
+                        packetCount = statsFromDataStore.flowStatistics.packetCount.value.longValue;
+                        durationSeconds = statsFromDataStore.flowStatistics.duration.second.value.intValue;
+                        durationNanoseconds = statsFromDataStore.flowStatistics.duration.nanosecond.value.intValue;
+                        
+                        ret = it;
+                    }
+                }            
+            }
+        }
         
         //TODO: Refer TODO (main)
         val input = new GetFlowStatisticsFromFlowTableInputBuilder;
@@ -282,30 +299,30 @@ class InventoryAndReadAdapter implements IPluginInReadService,
         flowStatisticsService.getFlowStatisticsFromFlowTable(input.build)
         
         return ret;
-       
+        
     }
 
     override readNodeConnector(org.opendaylight.controller.sal.core.NodeConnector connector, boolean cached) {
-       var NodeConnectorStatistics  nodeConnectorStatistics = null;
-       
-               val nodeConnectorRef = InstanceIdentifier.builder(Nodes)
-                                                                       .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(connector.node))
-                                                                       .child(NodeConnector, InventoryMapping.toNodeConnectorKey(connector))
-                                                                       .toInstance();
-               val provider = this.startChange();
-                               
-               val nodeConnectorFromDS = provider.readConfigurationData(nodeConnectorRef) as NodeConnector;
-                               
-               if(nodeConnectorFromDS != null){
-                       val nodeConnectorStatsFromDs = nodeConnectorFromDS.getAugmentation(FlowCapableNodeConnectorStatisticsData) as FlowCapableNodeConnectorStatistics;
-                       if(nodeConnectorStatsFromDs != null) {
-                               nodeConnectorStatistics = toNodeConnectorStatistics(nodeConnectorStatsFromDs.flowCapableNodeConnectorStatistics,
-                                                                                                                                               InventoryMapping.toNodeKey(connector.node).id,
-                                                                                                                                               InventoryMapping.toNodeConnectorKey(connector).id);
-                       }
-               }
-
-               //TODO: Refer TODO (main)
+        var NodeConnectorStatistics  nodeConnectorStatistics = null;
+    
+        val nodeConnectorRef = InstanceIdentifier.builder(Nodes)
+                                    .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(connector.node))
+                                    .child(NodeConnector, InventoryMapping.toNodeConnectorKey(connector))
+                                    .toInstance();
+         val provider = this.startChange();
+                 
+         val nodeConnectorFromDS = provider.readConfigurationData(nodeConnectorRef) as NodeConnector;
+                 
+         if(nodeConnectorFromDS != null){
+            val nodeConnectorStatsFromDs = nodeConnectorFromDS.getAugmentation(FlowCapableNodeConnectorStatisticsData) as FlowCapableNodeConnectorStatistics;
+            if(nodeConnectorStatsFromDs != null) {
+                nodeConnectorStatistics = toNodeConnectorStatistics(nodeConnectorStatsFromDs.flowCapableNodeConnectorStatistics,
+                                                                        InventoryMapping.toNodeKey(connector.node).id,
+                                                                        InventoryMapping.toNodeConnectorKey(connector).id);
+            }
+        }
+
+        //TODO: Refer TODO (main)
         val input = new GetNodeConnectorStatisticsInputBuilder();
         input.setNode(connector.node.toNodeRef);
         input.setNodeConnectorId(InventoryMapping.toNodeConnectorKey(connector).id);
@@ -314,25 +331,25 @@ class InventoryAndReadAdapter implements IPluginInReadService,
     }
 
     override readNodeTable(NodeTable nodeTable, boolean cached) {
-       var NodeTableStatistics nodeStats = null
-       
-       val tableRef = InstanceIdentifier.builder(Nodes)
-                                                                               .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(nodeTable.node))
-                                                       .augmentation(FlowCapableNode).child(Table, new TableKey(nodeTable.ID as Short)).toInstance();
-               
-               val it = this.startChange();
-               
-               val table= it.readConfigurationData(tableRef) as Table;
-               
-               if(table != null){
-                       val tableStats = table.getAugmentation(FlowTableStatisticsData);
-                               
-                       if(tableStats != null){
-                               nodeStats =  toNodeTableStatistics(tableStats.flowTableStatistics,table.id,nodeTable.node);
-                       }
-               }
-
-               //TODO: Refer TODO (main)
+        var NodeTableStatistics nodeStats = null
+        
+        val tableRef = InstanceIdentifier.builder(Nodes)
+                                        .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(nodeTable.node))
+                                        .augmentation(FlowCapableNode).child(Table, new TableKey(nodeTable.ID as Short)).toInstance();
+        
+        val it = this.startChange();
+        
+        val table= it.readConfigurationData(tableRef) as Table;
+        
+        if(table != null){
+            val tableStats = table.getAugmentation(FlowTableStatisticsData);
+                 
+             if(tableStats != null){
+                 nodeStats =  toNodeTableStatistics(tableStats.flowTableStatistics,table.id,nodeTable.node);
+            }
+        }
+
+        //TODO: Refer TODO (main)
         val input = new GetFlowTablesStatisticsInputBuilder();
         input.setNode(nodeTable.node.toNodeRef);
         flowTableStatisticsService.getFlowTablesStatistics(input.build);
@@ -341,19 +358,22 @@ class InventoryAndReadAdapter implements IPluginInReadService,
     }
 
     override onNodeConnectorRemoved(NodeConnectorRemoved update) {
-        // NOOP
+        // Never received
     }
 
     override onNodeRemoved(NodeRemoved notification) {
         val properties = Collections.<org.opendaylight.controller.sal.core.Property>emptySet();
 
+        removeNodeConnectors(notification.nodeRef.value);
+
         publishNodeUpdate(notification.nodeRef.toADNode, UpdateType.REMOVED, properties);
     }
 
     override onNodeConnectorUpdated(NodeConnectorUpdated update) {
         var updateType = UpdateType.CHANGED;
-        if ( this._dataService.readOperationalData(update.nodeConnectorRef.value as InstanceIdentifier<? extends DataObject>) == null ){
+        if(!isKnownNodeConnector(update.nodeConnectorRef.value)){
             updateType = UpdateType.ADDED;
+            recordNodeConnector(update.nodeConnectorRef.value);
         }
 
         var nodeConnector = update.nodeConnectorRef.toADNodeConnector
@@ -369,16 +389,16 @@ class InventoryAndReadAdapter implements IPluginInReadService,
             updateType = UpdateType.ADDED;
         }
         publishNodeUpdate(notification.nodeRef.toADNode, updateType, notification.toADNodeProperties);
-        
-               //Notify the listeners of IPluginOutReadService
-        
+
+        //Notify the listeners of IPluginOutReadService
+
         for (statsPublisher : statisticsPublisher){
-                       val nodeRef = InstanceIdentifier.builder(Nodes).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(notification.id)).toInstance;
+            val nodeRef = InstanceIdentifier.builder(Nodes).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(notification.id)).toInstance;
             val description = notification.nodeRef.toNodeDescription
             if(description != null) {
-                         statsPublisher.descriptionStatisticsUpdated(nodeRef.toADNode,description);
-                       }
-               }
+              statsPublisher.descriptionStatisticsUpdated(nodeRef.toADNode,description);
+            }
+        }
     }
 
     override getNodeProps() {
@@ -461,50 +481,50 @@ class InventoryAndReadAdapter implements IPluginInReadService,
 
     private def toNodeConnectorStatistics(
         org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.NodeConnectorStatistics nodeConnectorStatistics, NodeId nodeId, NodeConnectorId nodeConnectorId) {
-               
-                       val it = new NodeConnectorStatistics();
-                       
-                       receivePacketCount = nodeConnectorStatistics.packets.received.longValue;
-                       transmitPacketCount = nodeConnectorStatistics.packets.transmitted.longValue;
-                       
-                       receiveByteCount = nodeConnectorStatistics.bytes.received.longValue;
-                       transmitByteCount = nodeConnectorStatistics.bytes.transmitted.longValue;
-                       
-                       receiveDropCount = nodeConnectorStatistics.receiveDrops.longValue;
-                       transmitDropCount = nodeConnectorStatistics.transmitDrops.longValue;
-                       
-                       receiveErrorCount = nodeConnectorStatistics.receiveErrors.longValue;
-                       transmitErrorCount = nodeConnectorStatistics.transmitErrors.longValue;
-                       
-                       receiveFrameErrorCount = nodeConnectorStatistics.receiveFrameError.longValue;
-                       receiveOverRunErrorCount = nodeConnectorStatistics.receiveOverRunError.longValue;
-                       receiveCRCErrorCount = nodeConnectorStatistics.receiveCrcError.longValue;
-                       collisionCount = nodeConnectorStatistics.collisionCount.longValue;
-                       
-                       val nodeConnectorRef = InstanceIdentifier.builder(Nodes)
-                                                               .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(nodeId))
-                                                               .child(NodeConnector,new NodeConnectorKey(nodeConnectorId)).toInstance;
-                       
-                       nodeConnector = NodeMapping.toADNodeConnector(new NodeConnectorRef(nodeConnectorRef));
-                       
-                       return it;
-    }
-
-       private def toNodeTableStatistics(
-               FlowTableStatistics tableStats,
-               Short tableId,Node node){
-               var it = new NodeTableStatistics();
-               
-               activeCount = tableStats.activeFlows.value.intValue;
-               lookupCount = tableStats.packetsLookedUp.value.intValue;
-               matchedCount = tableStats.packetsMatched.value.intValue;
-               name = tableId.toString;
-               nodeTable = new NodeTable(NodeMapping.MD_SAL_TYPE,tableId,node);
-               return it;
-       }
-       
-       private def toNodeDescription(NodeRef nodeRef){
-               val capableNode = readFlowCapableNode(nodeRef);
+            
+            val it = new NodeConnectorStatistics();
+            
+            receivePacketCount = nodeConnectorStatistics.packets.received.longValue;
+            transmitPacketCount = nodeConnectorStatistics.packets.transmitted.longValue;
+            
+            receiveByteCount = nodeConnectorStatistics.bytes.received.longValue;
+            transmitByteCount = nodeConnectorStatistics.bytes.transmitted.longValue;
+            
+            receiveDropCount = nodeConnectorStatistics.receiveDrops.longValue;
+            transmitDropCount = nodeConnectorStatistics.transmitDrops.longValue;
+            
+            receiveErrorCount = nodeConnectorStatistics.receiveErrors.longValue;
+            transmitErrorCount = nodeConnectorStatistics.transmitErrors.longValue;
+            
+            receiveFrameErrorCount = nodeConnectorStatistics.receiveFrameError.longValue;
+            receiveOverRunErrorCount = nodeConnectorStatistics.receiveOverRunError.longValue;
+            receiveCRCErrorCount = nodeConnectorStatistics.receiveCrcError.longValue;
+            collisionCount = nodeConnectorStatistics.collisionCount.longValue;
+            
+            val nodeConnectorRef = InstanceIdentifier.builder(Nodes)
+                                .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(nodeId))
+                                .child(NodeConnector,new NodeConnectorKey(nodeConnectorId)).toInstance;
+            
+            nodeConnector = NodeMapping.toADNodeConnector(new NodeConnectorRef(nodeConnectorRef));
+            
+            return it;
+    }
+
+    private def toNodeTableStatistics(
+        FlowTableStatistics tableStats,
+        Short tableId,Node node){
+        var it = new NodeTableStatistics();
+        
+        activeCount = tableStats.activeFlows.value.intValue;
+        lookupCount = tableStats.packetsLookedUp.value.intValue;
+        matchedCount = tableStats.packetsMatched.value.intValue;
+        name = tableId.toString;
+        nodeTable = new NodeTable(NodeMapping.MD_SAL_TYPE,tableId,node);
+        return it;
+    }
+    
+    private def toNodeDescription(NodeRef nodeRef){
+        val capableNode = readFlowCapableNode(nodeRef);
         if(capableNode !=null) {
             val it = new NodeDescription()
             manufacturer = capableNode.manufacturer
@@ -515,101 +535,148 @@ class InventoryAndReadAdapter implements IPluginInReadService,
             return it;
          }
          return null;
-       }
+    }
     
     
     def Edge toADEdge(Link link) {
         new Edge(link.source.toADNodeConnector,link.destination.toADNodeConnector)
     }
-       
-       /*
-        * OpendaylightFlowStatisticsListener interface implementation
-        */
-       override onAggregateFlowStatisticsUpdate(AggregateFlowStatisticsUpdate notification) {
+    
+    /*
+     * OpendaylightFlowStatisticsListener interface implementation
+     */
+    override onAggregateFlowStatisticsUpdate(AggregateFlowStatisticsUpdate notification) {
         //Ignoring this notification as there does not seem to be a way to bubble this up to AD-SAL
-       }
-       
-       override onFlowsStatisticsUpdate(FlowsStatisticsUpdate notification) {
-               
-               val adsalFlowsStatistics = new ArrayList<FlowOnNode>();
-               val nodeRef = InstanceIdentifier.builder(Nodes).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(notification.id)).toInstance;
-               
-               for(flowStats : notification.flowAndStatisticsMapList){
-                       if(flowStats.tableId == 0)
-                               adsalFlowsStatistics.add(toFlowOnNode(flowStats,nodeRef.toADNode));
-               }
-               
-               for (statsPublisher : statisticsPublisher){
-                       statsPublisher.nodeFlowStatisticsUpdated(nodeRef.toADNode,adsalFlowsStatistics);
-               }
-               
-       }
-       /*
-        * OpendaylightFlowTableStatisticsListener interface implementation
-        */     
-       override onFlowTableStatisticsUpdate(FlowTableStatisticsUpdate notification) {
-               var adsalFlowTableStatistics = new ArrayList<NodeTableStatistics>();
-               
-               for(stats : notification.flowTableAndStatisticsMap){
-                       if (stats.tableId.value == 0){
-                               val it = new NodeTableStatistics();
-                               activeCount = stats.activeFlows.value.intValue;
-                               lookupCount = stats.packetsLookedUp.value.longValue;
-                               matchedCount = stats.packetsMatched.value.longValue;
-                               
-                               adsalFlowTableStatistics.add(it);
-                       }
-               }
-               for (statsPublisher : statisticsPublisher){
-                       val nodeRef = InstanceIdentifier.builder(Nodes).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(notification.id)).toInstance;
-                       statsPublisher.nodeTableStatisticsUpdated(nodeRef.toADNode,adsalFlowTableStatistics);
-               }
-       }
-       
-       /*
-        * OpendaylightPortStatisticsUpdate interface implementation
-        */
-       override onNodeConnectorStatisticsUpdate(NodeConnectorStatisticsUpdate notification) {
-               
-               val adsalPortStatistics  = new ArrayList<NodeConnectorStatistics>();
-               
-               for(nodeConnectorStatistics : notification.nodeConnectorStatisticsAndPortNumberMap){
-                       adsalPortStatistics.add(toNodeConnectorStatistics(nodeConnectorStatistics,notification.id,nodeConnectorStatistics.nodeConnectorId));
-               }
-               
-               for (statsPublisher : statisticsPublisher){
-                       val nodeRef = InstanceIdentifier.builder(Nodes).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(notification.id)).toInstance;
-                       statsPublisher.nodeConnectorStatisticsUpdated(nodeRef.toADNode,adsalPortStatistics);
-               }
-               
-       }
-       
-       private static def toFlowOnNode (FlowAndStatisticsMapList flowAndStatsMap,Node node){
-               
-               val it = new FlowOnNode(ToSalConversionsUtils.toFlow(flowAndStatsMap,node));
-               
-               byteCount = flowAndStatsMap.byteCount.value.longValue;
-               packetCount = flowAndStatsMap.packetCount.value.longValue;
-               durationSeconds = flowAndStatsMap.duration.second.value.intValue;
-               durationNanoseconds = flowAndStatsMap.duration.nanosecond.value.intValue;
-               
-               return it;
-       }
-
-       override  getConfiguredNotConnectedNodes() {
+    }
+    
+    override onFlowsStatisticsUpdate(FlowsStatisticsUpdate notification) {
+        
+        val adsalFlowsStatistics = new ArrayList<FlowOnNode>();
+        val nodeRef = InstanceIdentifier.builder(Nodes).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(notification.id)).toInstance;
+        
+        for(flowStats : notification.flowAndStatisticsMapList){
+            if(flowStats.tableId == 0)
+                adsalFlowsStatistics.add(toFlowOnNode(flowStats,nodeRef.toADNode));
+        }
+        
+        for (statsPublisher : statisticsPublisher){
+            statsPublisher.nodeFlowStatisticsUpdated(nodeRef.toADNode,adsalFlowsStatistics);
+        }
+        
+    }
+    /*
+     * OpendaylightFlowTableStatisticsListener interface implementation
+     */    
+    override onFlowTableStatisticsUpdate(FlowTableStatisticsUpdate notification) {
+        var adsalFlowTableStatistics = new ArrayList<NodeTableStatistics>();
+        
+        for(stats : notification.flowTableAndStatisticsMap){
+            if (stats.tableId.value == 0){
+                val it = new NodeTableStatistics();
+                activeCount = stats.activeFlows.value.intValue;
+                lookupCount = stats.packetsLookedUp.value.longValue;
+                matchedCount = stats.packetsMatched.value.longValue;
+                
+                adsalFlowTableStatistics.add(it);
+            }
+        }
+        for (statsPublisher : statisticsPublisher){
+            val nodeRef = InstanceIdentifier.builder(Nodes).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(notification.id)).toInstance;
+            statsPublisher.nodeTableStatisticsUpdated(nodeRef.toADNode,adsalFlowTableStatistics);
+        }
+    }
+    
+    /*
+     * OpendaylightPortStatisticsUpdate interface implementation
+     */
+    override onNodeConnectorStatisticsUpdate(NodeConnectorStatisticsUpdate notification) {
+        
+        val adsalPortStatistics  = new ArrayList<NodeConnectorStatistics>();
+        
+        for(nodeConnectorStatistics : notification.nodeConnectorStatisticsAndPortNumberMap){
+            adsalPortStatistics.add(toNodeConnectorStatistics(nodeConnectorStatistics,notification.id,nodeConnectorStatistics.nodeConnectorId));
+        }
+        
+        for (statsPublisher : statisticsPublisher){
+            val nodeRef = InstanceIdentifier.builder(Nodes).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(notification.id)).toInstance;
+            statsPublisher.nodeConnectorStatisticsUpdated(nodeRef.toADNode,adsalPortStatistics);
+        }
+        
+    }
+    
+    private static def toFlowOnNode (FlowAndStatisticsMapList flowAndStatsMap,Node node){
+        
+        val it = new FlowOnNode(ToSalConversionsUtils.toFlow(flowAndStatsMap,node));
+        
+        byteCount = flowAndStatsMap.byteCount.value.longValue;
+        packetCount = flowAndStatsMap.packetCount.value.longValue;
+        durationSeconds = flowAndStatsMap.duration.second.value.intValue;
+        durationNanoseconds = flowAndStatsMap.duration.nanosecond.value.intValue;
+        
+        return it;
+    }
+
+    override  getConfiguredNotConnectedNodes() {
         return Collections.emptySet();
-       }
+    }
+
+
+    private def publishNodeUpdate(Node node, UpdateType updateType, Set<org.opendaylight.controller.sal.core.Property> properties){
+        for( publisher : inventoryPublisher){
+            publisher.updateNode(node, updateType, properties);
+        }
+    }
+
+    private def publishNodeConnectorUpdate(org.opendaylight.controller.sal.core.NodeConnector nodeConnector, UpdateType updateType, Set<org.opendaylight.controller.sal.core.Property> properties){
+        for( publisher : inventoryPublisher){
+            publisher.updateNodeConnector(nodeConnector, updateType, properties);
+        }
+    }
+
+    private def isKnownNodeConnector(InstanceIdentifier<? extends Object> nodeConnectorIdentifier){
+        if(nodeConnectorIdentifier.path.size() < 3) {
+            return false;
+        }
 
+        val nodePath = nodeConnectorIdentifier.path.get(1);
+        val nodeConnectorPath = nodeConnectorIdentifier.getPath().get(2);
 
-       private def publishNodeUpdate(Node node, UpdateType updateType, Set<org.opendaylight.controller.sal.core.Property> properties){
-           for( publisher : inventoryPublisher){
-               publisher.updateNode(node, updateType, properties);
-           }
-       }
+        val nodeConnectors = nodeToNodeConnectorsMap.get(nodePath);
 
-       private def publishNodeConnectorUpdate(org.opendaylight.controller.sal.core.NodeConnector nodeConnector, UpdateType updateType, Set<org.opendaylight.controller.sal.core.Property> properties){
-           for( publisher : inventoryPublisher){
-               publisher.updateNodeConnector(nodeConnector, updateType, properties);
-           }
-       }
+        if(nodeConnectors == null){
+            return false;
+        }
+        return nodeConnectors.contains(nodeConnectorPath);
+    }
+
+
+    private def recordNodeConnector(InstanceIdentifier<? extends Object> nodeConnectorIdentifier){
+        if(nodeConnectorIdentifier.path.size() < 3) {
+            return false;
+        }
+
+        val nodePath = nodeConnectorIdentifier.path.get(1);
+        val nodeConnectorPath = nodeConnectorIdentifier.getPath().get(2);
+
+        nodeToNodeConnectorsLock.lock();
+
+        try {
+            var nodeConnectors = nodeToNodeConnectorsMap.get(nodePath);
+
+            if(nodeConnectors == null){
+                nodeConnectors = new ArrayList<InstanceIdentifier.PathArgument>();
+                nodeToNodeConnectorsMap.put(nodePath, nodeConnectors);
+            }
+
+            nodeConnectors.add(nodeConnectorPath);
+        } finally {
+            nodeToNodeConnectorsLock.unlock();
+        }
+    }
+
+    private def removeNodeConnectors(InstanceIdentifier<? extends Object> nodeIdentifier){
+        val nodePath = nodeIdentifier.path.get(1);
+
+        nodeToNodeConnectorsMap.remove(nodePath);
+    }
 }
diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/InventoryNotificationProvider.java b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/InventoryNotificationProvider.java
new file mode 100644 (file)
index 0000000..23a98ff
--- /dev/null
@@ -0,0 +1,59 @@
+package org.opendaylight.controller.sal.compatibility;
+
+import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.controller.sal.inventory.IPluginOutInventoryService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+
+public class InventoryNotificationProvider implements AutoCloseable{
+
+    private ListenerRegistration<DataChangeListener> nodeConnectorDataChangeListenerRegistration;
+
+    private NodeConnectorDataChangeListener nodeConnectorDataChangeListener;
+
+    private DataProviderService dataProviderService;
+
+    private List<IPluginOutInventoryService> inventoryPublisher;
+
+    private final static Logger LOG = LoggerFactory.getLogger(NodeConnectorDataChangeListener.class);
+
+    public void start(){
+
+        LOG.info("InventoryNotificationProvider started");
+
+        if(dataProviderService != null
+                && inventoryPublisher!= null){
+
+            if(nodeConnectorDataChangeListener == null){
+                InstanceIdentifier nodeConnectorPath = InstanceIdentifier.builder(Nodes.class).child(Node.class).child(NodeConnector.class).build();
+                nodeConnectorDataChangeListener = new NodeConnectorDataChangeListener();
+                nodeConnectorDataChangeListener.setInventoryPublisher(inventoryPublisher);
+                nodeConnectorDataChangeListenerRegistration = dataProviderService.registerDataChangeListener(nodeConnectorPath, nodeConnectorDataChangeListener);
+            }
+
+        }
+    }
+
+    @Override
+    public void close() throws Exception {
+        if(nodeConnectorDataChangeListenerRegistration != null){
+            nodeConnectorDataChangeListenerRegistration.close();
+        }
+    }
+
+    public void setDataProviderService(DataProviderService dataProviderService) {
+        this.dataProviderService = dataProviderService;
+    }
+
+    public void setInventoryPublisher(List<IPluginOutInventoryService> inventoryPublisher) {
+        this.inventoryPublisher = inventoryPublisher;
+    }
+}
diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/NodeConnectorDataChangeListener.java b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/NodeConnectorDataChangeListener.java
new file mode 100644 (file)
index 0000000..eebba74
--- /dev/null
@@ -0,0 +1,77 @@
+package org.opendaylight.controller.sal.compatibility;
+
+import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
+import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;
+import org.opendaylight.controller.sal.core.ConstructionException;
+import org.opendaylight.controller.sal.core.NodeConnector;
+import org.opendaylight.controller.sal.core.Property;
+import org.opendaylight.controller.sal.core.UpdateType;
+import org.opendaylight.controller.sal.inventory.IPluginOutInventoryService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+// org.opendaylight.controller.sal.compatibility.NodeConnectorDataChangeListener
+public class NodeConnectorDataChangeListener implements DataChangeListener{
+    private final static Logger LOG = LoggerFactory.getLogger(NodeConnectorDataChangeListener.class);
+
+    private List<IPluginOutInventoryService> inventoryPublisher;
+
+    public List<IPluginOutInventoryService> getInventoryPublisher() {
+      return this.inventoryPublisher;
+    }
+
+    public void setInventoryPublisher(final List<IPluginOutInventoryService> inventoryPublisher) {
+      this.inventoryPublisher = inventoryPublisher;
+    }
+
+    @Override
+    public void onDataChanged(DataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
+        final Map<InstanceIdentifier<?>,DataObject> createdOperationalData = change.getCreatedOperationalData();
+        final Map<InstanceIdentifier<?>,DataObject> updatedOperationalData = change.getUpdatedOperationalData();
+
+        final Set<Map.Entry<InstanceIdentifier<?>,DataObject>> createdEntries = createdOperationalData.entrySet();
+        final Set<Map.Entry<InstanceIdentifier<?>,DataObject>> updatedEntries = new HashSet<>();
+
+        updatedEntries.addAll(updatedOperationalData.entrySet());
+        updatedEntries.removeAll(createdEntries);
+
+        for(final Map.Entry<InstanceIdentifier<?>,DataObject> entry : createdEntries){
+            publishNodeConnectorUpdate(entry, UpdateType.ADDED);
+        }
+
+        for(final Map.Entry<InstanceIdentifier<?>,DataObject> entry : updatedEntries){
+            publishNodeConnectorUpdate(entry, UpdateType.CHANGED);
+        }
+    }
+
+    private void publishNodeConnectorUpdate(final Map.Entry<InstanceIdentifier<?>,DataObject> entry, final UpdateType updateType) {
+        if (entry.getKey().getTargetType().equals(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector.class)) {
+            NodeConnectorRef nodeConnectorRef = new NodeConnectorRef(entry.getKey());
+            NodeConnector nodeConnector = null;
+            try {
+                nodeConnector = NodeMapping.toADNodeConnector(nodeConnectorRef);
+            } catch (ConstructionException e) {
+                e.printStackTrace();
+            }
+            HashSet<Property> _aDNodeConnectorProperties = NodeMapping.toADNodeConnectorProperties((org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector) entry.getValue());
+            this.publishNodeConnectorUpdate(nodeConnector, updateType, _aDNodeConnectorProperties);
+        }
+    }
+
+    private void publishNodeConnectorUpdate(final NodeConnector nodeConnector, final UpdateType updateType, final Set<Property> properties) {
+      LOG.debug("Publishing NodeConnector " + updateType.toString() + " nodeConnector Id = " + nodeConnector.getNodeConnectorIdAsString());
+
+      List<IPluginOutInventoryService> _inventoryPublisher = getInventoryPublisher();
+      for (final IPluginOutInventoryService publisher : _inventoryPublisher) {
+        publisher.updateNodeConnector(nodeConnector, updateType, properties);
+      }
+    }
+}
index a949e45..00cbc18 100644 (file)
@@ -46,7 +46,6 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal-binding-api</artifactId>
-      <version>1.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
     <dependency>
       <groupId>org.opendaylight.controller.model</groupId>
       <artifactId>model-flow-service</artifactId>
-      <version>1.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller.model</groupId>
       <artifactId>model-flow-management</artifactId>
-      <version>1.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.yangtools</groupId>
@@ -70,7 +67,6 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal-binding-broker-impl</artifactId>
-      <version>1.1-SNAPSHOT</version>
       <scope>provided</scope>
     </dependency>
   </dependencies>
index ffdac63..4d0465c 100644 (file)
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>sal-binding-api</artifactId>
-            <version>1.1-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.controller.model</groupId>
             <artifactId>model-flow-service</artifactId>
-            <version>1.1-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.controller.model</groupId>
             <artifactId>model-inventory</artifactId>
-            <version>1.1-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>org.eclipse.xtend</groupId>
index 1a66b3b..43f48a5 100644 (file)
@@ -64,6 +64,8 @@ class FlowCapableInventoryProvider implements AutoCloseable {
 
 class NodeChangeCommiter implements OpendaylightInventoryListener {
 
+    static val LOG = LoggerFactory.getLogger(NodeChangeCommiter);
+
     @Property
     val FlowCapableInventoryProvider manager;
 
@@ -76,6 +78,9 @@ class NodeChangeCommiter implements OpendaylightInventoryListener {
 
         // Check path
         val it = manager.startChange()
+
+        LOG.debug("removing node connector : " + ref.value.toString());
+
         removeOperationalData(ref.value as InstanceIdentifier<? extends DataObject>);
         commit()
     }
@@ -93,6 +98,8 @@ class NodeChangeCommiter implements OpendaylightInventoryListener {
             data.addAugmentation(FlowCapableNodeConnector, augment)
         }
 
+        LOG.debug("updating node connector : " + ref.value.toString());
+
         putOperationalData(ref.value as InstanceIdentifier<NodeConnector>, data.build());
         commit()
     }
@@ -101,6 +108,8 @@ class NodeChangeCommiter implements OpendaylightInventoryListener {
         val ref = node.nodeRef;
         val it = manager.startChange()
 
+        LOG.debug("removing node : " + ref.value.toString());
+
         removeOperationalData(ref.value as InstanceIdentifier<? extends DataObject>);
         commit()
     }
@@ -117,6 +126,8 @@ class NodeChangeCommiter implements OpendaylightInventoryListener {
             data.addAugmentation(FlowCapableNode, augment)
         }
 
+        LOG.debug("updating node : " + ref.value.toString());
+
         putOperationalData(ref.value as InstanceIdentifier<Node>, data.build())
         commit()
     }
index d816695..39f5060 100644 (file)
@@ -29,7 +29,6 @@
         <dependency>
             <groupId>org.opendaylight.yangtools.model</groupId>
             <artifactId>opendaylight-l2-types</artifactId>
-            <version>2013.08.27.3</version>
         </dependency>
     </dependencies>
     <packaging>bundle</packaging>
index 13efc4c..54f2322 100644 (file)
@@ -29,7 +29,6 @@
         <dependency>
             <groupId>org.opendaylight.yangtools.model</groupId>
             <artifactId>opendaylight-l2-types</artifactId>
-            <version>2013.08.27.3</version>
         </dependency>
     </dependencies>
     <packaging>bundle</packaging>
index cd44bd2..8e9f623 100644 (file)
@@ -20,7 +20,6 @@
         <dependency>
             <groupId>org.opendaylight.controller.model</groupId>
             <artifactId>model-inventory</artifactId>
-            <version>1.1-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.yangtools.model</groupId>
index 8b4e478..f900c0b 100644 (file)
                 <artifactId>sal-connector-api</artifactId>
                 <version>${project.version}</version>
             </dependency>
+            <dependency>
+                <groupId>org.opendaylight.controller</groupId>
+                <artifactId>sal-binding-api</artifactId>
+                <version>${project.version}</version>
+            </dependency>
             <dependency>
                 <groupId>org.opendaylight.controller</groupId>
                 <artifactId>sal</artifactId>
                     </exclusion>
                 </exclusions>
             </dependency>
+            <dependency>
+                <groupId>org.opendaylight.controller</groupId>
+                <artifactId>sal-remote</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.opendaylight.controller</groupId>
+                <artifactId>sal-binding-util</artifactId>
+                <version>${project.version}</version>
+            </dependency>
 
             <!-- Supporting Libraries -->
             <dependency>
index 86e14e4..f90031b 100644 (file)
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>sal-common</artifactId>
-            <version>1.1-SNAPSHOT</version>
         </dependency>
 
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>sal-common-api</artifactId>
-            <version>${project.version}</version>
         </dependency>
         <dependency>
             <groupId>org.osgi</groupId>
             <artifactId>org.osgi.core</artifactId>
-            <version>${osgi.core.version}</version>
             <scope>provided</scope>
         </dependency>
     </dependencies>
index 33b384a..69a2108 100644 (file)
@@ -19,8 +19,6 @@ public interface RpcConsumerRegistry extends BindingAwareService {
      * Returns a session specific instance (implementation) of requested
      * YANG module implentation / service provided by consumer.
      * 
-     * @param service
-     *            Broker service
      * @return Session specific implementation of service
      */
     <T extends RpcService> T getRpcService(Class<T> module);
index e5a74e4..5367498 100644 (file)
                             org.opendaylight.controller.sal.binding.impl.*,
                             org.opendaylight.controller.sal.binding.codegen,
                             org.opendaylight.controller.sal.binding.codegen.*,
-                            org.opendaylight.controller.sal.binding.dom.*,
+                            <!--org.opendaylight.controller.sal.binding.dom.*,-->
                             org.opendaylight.controller.sal.binding.osgi.*,
                         </Private-Package>
                     </instructions>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>sal-common-util</artifactId>
-            <version>1.1-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>sal-common-impl</artifactId>
-            <version>1.1-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>sal-binding-api</artifactId>
-            <version>1.1-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>sal-binding-util</artifactId>
-            <version>1.1-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>org.slf4j</groupId>
         <dependency>
             <groupId>org.osgi</groupId>
             <artifactId>org.osgi.core</artifactId>
-            <version>${osgi.core.version}</version>
             <scope>provided</scope>
         </dependency>
         <dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>sal-core-api</artifactId>
-            <version>1.1-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>sal-broker-impl</artifactId>
-            <version>1.1-SNAPSHOT</version>
             <scope>compile</scope>
         </dependency>
         <dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>sal-binding-config</artifactId>
-            <version>1.1-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.yangtools</groupId>
             <dependency>
             <groupId>org.opendaylight.yangtools.model</groupId>
             <artifactId>ietf-inet-types</artifactId>
-            <version>2010.09.24.3</version>
         </dependency>
         <dependency>
-        <groupId>org.opendaylight.yangtools.model</groupId>
-        <artifactId>ietf-topology-l3-unicast-igp</artifactId>
-        <version>2013.10.21.1</version>
-        <scope>test</scope>
+            <groupId>org.opendaylight.yangtools.model</groupId>
+            <artifactId>ietf-topology-l3-unicast-igp</artifactId>
+            <scope>test</scope>
         </dependency>
         <dependency>
-               <groupId>org.opendaylight.controller.model</groupId>
-               <artifactId>model-flow-base</artifactId>
-               <version>1.1-SNAPSHOT</version>
+            <groupId>org.opendaylight.controller.model</groupId>
+            <artifactId>model-flow-base</artifactId>
         </dependency>
         <dependency>
-               <groupId>org.opendaylight.controller.model</groupId>
-               <artifactId>model-flow-service</artifactId>
-               <version>1.1-SNAPSHOT</version>
+            <groupId>org.opendaylight.controller.model</groupId>
+            <artifactId>model-flow-service</artifactId>
         </dependency>
         <dependency>
-               <groupId>org.opendaylight.controller.model</groupId>
-               <artifactId>model-flow-statistics</artifactId>
-               <version>1.1-SNAPSHOT</version>
+            <groupId>org.opendaylight.controller.model</groupId>
+            <artifactId>model-flow-statistics</artifactId>
         </dependency>
     </dependencies>
 </project>
index 286b0c3..7357926 100644 (file)
@@ -7,17 +7,17 @@
  */
 package org.opendaylight.controller.config.yang.md.sal.binding.impl;\r
 \r
-import java.util.concurrent.ExecutorService;\r
-\r
-import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder;\r
-import org.opendaylight.controller.sal.binding.impl.RootDataBrokerImpl;\r
-import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingDomConnectorDeployer;\r
-import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentConnector;\r
-import org.opendaylight.controller.sal.binding.impl.forward.DomForwardedDataBrokerImpl;\r
-import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;\r
-import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;\r
-import org.osgi.framework.BundleContext;\r
-import org.osgi.framework.ServiceReference;\r
+import java.util.concurrent.ExecutorService;
+
+import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder;
+import org.opendaylight.controller.sal.binding.impl.RootDataBrokerImpl;
+import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingDomConnectorDeployer;
+import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentConnector;
+import org.opendaylight.controller.sal.binding.impl.forward.DomForwardedDataBrokerImpl;
+import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
+import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
 \r
 /**\r
 *\r
@@ -57,14 +57,14 @@ public final class DataBrokerImplModule extends
             dataBindingBroker = createStandAloneBroker(listeningExecutor);\r
         }\r
         dataBindingBroker.registerRuntimeBean(getRootRuntimeBeanRegistratorWrapper());\r
-\r
+        dataBindingBroker.setNotificationExecutor(SingletonHolder.getDefaultChangeEventExecutor());\r
         return dataBindingBroker;\r
     }\r
     private BindingIndependentMappingService resolveMappingServiceDependency() {\r
         if(getMappingService() != null) {\r
             return getMappingServiceDependency();\r
         }\r
-        \r
+\r
         ServiceReference<BindingIndependentMappingService> potentialMappingService = bundleContext.getServiceReference(BindingIndependentMappingService.class);\r
         if(potentialMappingService != null) {\r
             return bundleContext.getService(potentialMappingService);\r
index 0762739..14006a3 100644 (file)
@@ -7,10 +7,11 @@
  */
 package org.opendaylight.controller.config.yang.md.sal.binding.impl;
 
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
 import java.util.Hashtable;
 import java.util.Map.Entry;
 import java.util.Set;
-
 import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder;
 import org.opendaylight.yangtools.concepts.Delegator;
 import org.opendaylight.yangtools.sal.binding.generator.impl.RuntimeGeneratedMappingServiceImpl;
@@ -27,9 +28,6 @@ import org.opendaylight.yangtools.yang.model.api.SchemaServiceListener;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
 
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-
 /**
 *
 */
@@ -63,7 +61,7 @@ public final class RuntimeMappingModule extends
 
     @Override
     public java.lang.AutoCloseable createInstance() {
-
+        
         RuntimeGeneratedMappingServiceProxy potential = tryToReuseGlobalInstance();
         if(potential != null) {
             return potential;
@@ -100,7 +98,7 @@ public final class RuntimeMappingModule extends
     BindingIndependentMappingService, //
     Delegator<BindingIndependentMappingService>, //
     AutoCloseable {
-
+        
         private BindingIndependentMappingService delegate;
         private ServiceReference<BindingIndependentMappingService> reference;
         private BundleContext bundleContext;
@@ -113,56 +111,48 @@ public final class RuntimeMappingModule extends
             this.delegate = Preconditions.checkNotNull(delegate);
         }
 
-        @Override
         public CodecRegistry getCodecRegistry() {
             return delegate.getCodecRegistry();
         }
 
-        @Override
         public CompositeNode toDataDom(DataObject data) {
             return delegate.toDataDom(data);
         }
 
-        @Override
         public Entry<InstanceIdentifier, CompositeNode> toDataDom(
                 Entry<org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject>, DataObject> entry) {
             return delegate.toDataDom(entry);
         }
 
-        @Override
         public InstanceIdentifier toDataDom(
                 org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject> path) {
             return delegate.toDataDom(path);
         }
 
-        @Override
         public DataObject dataObjectFromDataDom(
                 org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject> path,
                 CompositeNode result) throws DeserializationException {
             return delegate.dataObjectFromDataDom(path, result);
         }
 
-        @Override
         public org.opendaylight.yangtools.yang.binding.InstanceIdentifier<?> fromDataDom(InstanceIdentifier entry)
                 throws DeserializationException {
             return delegate.fromDataDom(entry);
         }
 
-        @Override
         public Set<QName> getRpcQNamesFor(Class<? extends RpcService> service) {
             return delegate.getRpcQNamesFor(service);
         }
 
-        @Override
-        public DataContainer dataObjectFromDataDom(Class<? extends DataContainer> inputClass, CompositeNode domInput) {
-            return delegate.dataObjectFromDataDom(inputClass, domInput);
-        }
-
         @Override
         public Optional<Class<? extends RpcService>> getRpcServiceClassFor(String namespace, String revision) {
-            return delegate.getRpcServiceClassFor(namespace, revision);
+            return delegate.getRpcServiceClassFor(namespace,revision);
         }
 
+        public DataContainer dataObjectFromDataDom(Class<? extends DataContainer> inputClass, CompositeNode domInput) {
+            return delegate.dataObjectFromDataDom(inputClass, domInput);
+        }
+        
         @Override
         public void close() throws Exception {
             if(delegate != null) {
index 291677a..a0bbb28 100644 (file)
@@ -29,6 +29,7 @@ public class SingletonHolder {
     public static final NotificationInvokerFactory INVOKER_FACTORY = RPC_GENERATOR_IMPL.getInvokerFactory();
     private static ListeningExecutorService NOTIFICATION_EXECUTOR = null;
     private static ListeningExecutorService COMMIT_EXECUTOR = null;
+    private static ListeningExecutorService CHANGE_EVENT_EXECUTOR = null;
 
     public static synchronized final ListeningExecutorService getDefaultNotificationExecutor() {
         if (NOTIFICATION_EXECUTOR == null) {
@@ -64,4 +65,21 @@ public class SingletonHolder {
         ExecutorService executor = Executors.newCachedThreadPool(factory);
         return MoreExecutors.listeningDecorator(executor);
     }
+
+    public static ExecutorService getDefaultChangeEventExecutor() {
+        if (CHANGE_EVENT_EXECUTOR == null) {
+            ThreadFactory factory = new ThreadFactoryBuilder().setDaemon(true).setNameFormat("md-sal-binding-change-%d").build();
+            /*
+             * FIXME: this used to be newCacheThreadPool(), but MD-SAL does not have transaction
+             *        ordering guarantees, which means that using a concurrent threadpool results
+             *        in application data being committed in random order, potentially resulting
+             *        in inconsistent data being present. Once proper primitives are introduced,
+             *        concurrency can be reintroduced.
+             */
+            ExecutorService executor = Executors.newSingleThreadExecutor(factory);
+            CHANGE_EVENT_EXECUTOR  = MoreExecutors.listeningDecorator(executor);
+        }
+
+        return CHANGE_EVENT_EXECUTOR;
+    }
 }
index ddf6771..16d5a24 100644 (file)
@@ -7,7 +7,8 @@
  */
 package org.opendaylight.controller.sal.binding.impl;\r
 \r
-import java.util.Set;
+import java.util.Map;
+import java.util.Map.Entry;
 import java.util.concurrent.Future;
 import java.util.concurrent.atomic.AtomicLong;
 
@@ -19,12 +20,46 @@ import org.opendaylight.controller.sal.common.DataStoreIdentifier;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.DataRoot;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.util.DataObjectReadingUtil;
 import org.opendaylight.yangtools.yang.common.RpcResult;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableMap.Builder;
+import com.google.common.collect.Maps;
 \r
 \r
 public class DataBrokerImpl extends AbstractDataBroker<InstanceIdentifier<? extends DataObject>, DataObject, DataChangeListener> //\r
        implements DataProviderService, AutoCloseable {\r
 \r
+    private final static class ContainsWildcarded implements Predicate<InstanceIdentifier<? extends DataObject>> {
+
+        private final  InstanceIdentifier<? extends DataObject> key;
+
+        public ContainsWildcarded(InstanceIdentifier<? extends DataObject> key) {
+            this.key = key;
+        }
+
+        @Override
+        public boolean apply(InstanceIdentifier<? extends DataObject> input) {
+            return key.containsWildcarded(input);
+        }
+    }
+
+    private final static class IsContainedWildcarded implements Predicate<InstanceIdentifier<? extends DataObject>> {
+
+        private final  InstanceIdentifier<? extends DataObject> key;
+
+        public IsContainedWildcarded(InstanceIdentifier<? extends DataObject> key) {
+            this.key = key;
+        }
+
+        @Override
+        public boolean apply(InstanceIdentifier<? extends DataObject> input) {
+            return input.containsWildcarded(key);
+        }
+    }
+
     private final AtomicLong nextTransaction = new AtomicLong();\r
     private final AtomicLong createdTransactionsCount = new AtomicLong();\r
 \r
@@ -110,16 +145,33 @@ public class DataBrokerImpl extends AbstractDataBroker<InstanceIdentifier<? exte
     }
 
     @Override
-    protected boolean isAffectedBy(InstanceIdentifier<? extends DataObject> key,
-            Set<InstanceIdentifier<? extends DataObject>> paths) {
-        if (paths.contains(key)) {
-            return true;
-        }
-        for (InstanceIdentifier<?> path : paths) {
-            if (key.containsWildcarded(path)) {
-                return true;
+    protected Predicate<InstanceIdentifier<? extends DataObject>> createContainsPredicate(final
+            InstanceIdentifier<? extends DataObject> key) {
+        return new ContainsWildcarded(key);
+    }
+
+    @Override
+    protected Predicate<InstanceIdentifier<? extends DataObject>> createIsContainedPredicate(final
+            InstanceIdentifier<? extends DataObject> key) {
+        return new IsContainedWildcarded(key);
+    }
+
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    @Override
+    protected Map<InstanceIdentifier<? extends DataObject>, DataObject> deepGetBySubpath(
+            Map<InstanceIdentifier<? extends DataObject>, DataObject> dataSet,
+            InstanceIdentifier<? extends DataObject> path) {
+        Builder<InstanceIdentifier<? extends DataObject>, DataObject> builder = ImmutableMap.builder();
+        Map<InstanceIdentifier<? extends DataObject>, DataObject> potential = Maps.filterKeys(dataSet, createIsContainedPredicate(path));
+        for(Entry<InstanceIdentifier<? extends DataObject>, DataObject> entry : potential.entrySet()) {
+            try {
+                builder.putAll(DataObjectReadingUtil.readData(entry.getValue(),(InstanceIdentifier)entry.getKey(),path));
+            } catch (Exception e) {
+                // FIXME : Log exception;
             }
         }
-        return false;
-    }\r
+        return builder.build();
+
+    }
+\r
 }
index a7dcf80..9a431fe 100644 (file)
@@ -23,10 +23,11 @@ import org.opendaylight.yangtools.yang.binding.Notification
 import org.slf4j.LoggerFactory\r
 import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder\rimport com.google.common.collect.Multimaps\r
 import org.opendaylight.yangtools.concepts.util.ListenerRegistry\r
-import org.opendaylight.controller.sal.binding.api.NotificationProviderService.NotificationInterestListener\rimport java.util.Set
-import com.google.common.collect.ImmutableSet
-import java.util.concurrent.Future
-
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService.NotificationInterestListener\rimport java.util.Set\r
+import java.util.Set\r
+import com.google.common.collect.ImmutableSet\r
+import java.util.concurrent.Future\r
+\r
 class NotificationBrokerImpl implements NotificationProviderService, AutoCloseable {\r
     \r
     val ListenerRegistry<NotificationInterestListener> interestListeners = ListenerRegistry.create;\r
@@ -105,14 +106,14 @@ class NotificationBrokerImpl implements NotificationProviderService, AutoCloseab
         submitAll(executor,tasks);\r
     }\r
     \r
-    def submitAll(ExecutorService service, Set<NotifyTask> tasks) {
+    def submitAll(ExecutorService service, Set<NotifyTask> tasks) {\r
         val ret = ImmutableSet.<Future<Object>>builder();\r
         for(task : tasks) {\r
             ret.add(service.submit(task));\r
         }\r
-        return ret.build();
+        return ret.build();\r
     }\r
-\r
+    \r
     override <T extends Notification> registerNotificationListener(Class<T> notificationType,\r
         NotificationListener<T> listener) {\r
         val reg = new GenericNotificationRegistration<T>(notificationType, listener, this);\r
index 5292487..3ad1dab 100644 (file)
@@ -7,8 +7,7 @@
  */
 package org.opendaylight.controller.sal.binding.impl;
 
-import static com.google.common.base.Preconditions.checkState;
-
+import com.google.common.collect.ImmutableClassToInstanceMap;
 import org.opendaylight.controller.md.sal.binding.util.AbstractBindingSalProviderInstance;
 import org.opendaylight.controller.md.sal.binding.util.BindingContextUtils;
 import org.opendaylight.controller.md.sal.common.api.routing.RouteChangeListener;
@@ -33,8 +32,7 @@ import org.opendaylight.yangtools.yang.binding.RpcService;
 import org.osgi.framework.BundleContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-
-import com.google.common.collect.ImmutableClassToInstanceMap;
+import static com.google.common.base.Preconditions.checkState;
 
 public class RootBindingAwareBroker implements //
         Mutable, //
index 5630664..e48ebbc 100644 (file)
@@ -45,8 +45,6 @@ import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
 import org.opendaylight.controller.sal.binding.api.data.RuntimeDataProvider;
 import org.opendaylight.controller.sal.binding.api.rpc.RpcContextIdentifier;
 import org.opendaylight.controller.sal.binding.api.rpc.RpcRouter;
-import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
-import org.opendaylight.yangtools.yang.data.impl.codec.DeserializationException;
 import org.opendaylight.controller.sal.binding.impl.RpcProviderRegistryImpl;
 import org.opendaylight.controller.sal.binding.impl.RpcProviderRegistryImpl.GlobalRpcRegistrationListener;
 import org.opendaylight.controller.sal.binding.impl.RpcProviderRegistryImpl.RouterInstantiationListener;
@@ -79,6 +77,8 @@ import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.opendaylight.yangtools.yang.data.api.Node;
 import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode;
+import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
+import org.opendaylight.yangtools.yang.data.impl.codec.DeserializationException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -113,11 +113,11 @@ public class BindingIndependentConnector implements //
 
     private DataProviderService baDataService;
 
-    private ConcurrentMap<Object, BindingToDomTransaction> domOpenedTransactions = new ConcurrentHashMap<>();
-    private ConcurrentMap<Object, DomToBindingTransaction> bindingOpenedTransactions = new ConcurrentHashMap<>();
+    private final ConcurrentMap<Object, BindingToDomTransaction> domOpenedTransactions = new ConcurrentHashMap<>();
+    private final ConcurrentMap<Object, DomToBindingTransaction> bindingOpenedTransactions = new ConcurrentHashMap<>();
 
-    private BindingToDomCommitHandler bindingToDomCommitHandler = new BindingToDomCommitHandler();
-    private DomToBindingCommitHandler domToBindingCommitHandler = new DomToBindingCommitHandler();
+    private final BindingToDomCommitHandler bindingToDomCommitHandler = new BindingToDomCommitHandler();
+    private final DomToBindingCommitHandler domToBindingCommitHandler = new DomToBindingCommitHandler();
 
     private Registration<DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject>> baCommitHandlerRegistration;
 
@@ -130,7 +130,7 @@ public class BindingIndependentConnector implements //
     // private ListenerRegistration<BindingToDomRpcForwardingManager>
     // bindingToDomRpcManager;
 
-    private Function<InstanceIdentifier<?>, org.opendaylight.yangtools.yang.data.api.InstanceIdentifier> toDOMInstanceIdentifier = new Function<InstanceIdentifier<?>, org.opendaylight.yangtools.yang.data.api.InstanceIdentifier>() {
+    private final Function<InstanceIdentifier<?>, org.opendaylight.yangtools.yang.data.api.InstanceIdentifier> toDOMInstanceIdentifier = new Function<InstanceIdentifier<?>, org.opendaylight.yangtools.yang.data.api.InstanceIdentifier>() {
 
         @Override
         public org.opendaylight.yangtools.yang.data.api.InstanceIdentifier apply(InstanceIdentifier<?> input) {
@@ -149,8 +149,6 @@ public class BindingIndependentConnector implements //
 
     private RpcProviderRegistryImpl baRpcRegistryImpl;
 
-    private org.opendaylight.controller.sal.dom.broker.spi.RpcRouter biRouter;
-
     private NotificationProviderService baNotifyService;
 
     private NotificationPublishService domNotificationService;
@@ -319,9 +317,6 @@ public class BindingIndependentConnector implements //
                 baRpcRegistryImpl.registerRouterInstantiationListener(domToBindingRpcManager.getInstance());
                 baRpcRegistryImpl.registerGlobalRpcRegistrationListener(domToBindingRpcManager.getInstance());
             }
-            if (biRpcRegistry instanceof org.opendaylight.controller.sal.dom.broker.spi.RpcRouter) {
-                biRouter = (org.opendaylight.controller.sal.dom.broker.spi.RpcRouter) biRpcRegistry;
-            }
             rpcForwarding = true;
         }
     }
@@ -413,8 +408,8 @@ public class BindingIndependentConnector implements //
     private class BindingToDomTransaction implements
             DataCommitTransaction<InstanceIdentifier<? extends DataObject>, DataObject> {
 
-        private DataModificationTransaction backing;
-        private DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification;
+        private final DataModificationTransaction backing;
+        private final DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification;
 
         public BindingToDomTransaction(DataModificationTransaction backing,
                 DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification) {
@@ -491,6 +486,7 @@ public class BindingIndependentConnector implements //
             // FIXME: do registration based on only active commit handlers.
         }
 
+        @Override
         public org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> requestCommit(
                 DataModification<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> domTransaction) {
             Object identifier = domTransaction.getIdentifier();
@@ -587,9 +583,9 @@ public class BindingIndependentConnector implements //
 
         private final Set<QName> supportedRpcs;
         private final WeakReference<Class<? extends RpcService>> rpcServiceType;
-        private Set<org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration> registrations;
-        private Map<QName, RpcInvocationStrategy> strategiesByQName = new HashMap<>();
-        private WeakHashMap<Method, RpcInvocationStrategy> strategiesByMethod = new WeakHashMap<>();
+        private final Set<org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration> registrations;
+        private final Map<QName, RpcInvocationStrategy> strategiesByQName = new HashMap<>();
+        private final WeakHashMap<Method, RpcInvocationStrategy> strategiesByMethod = new WeakHashMap<>();
 
         public DomToBindingRpcForwarder(Class<? extends RpcService> service) {
             this.rpcServiceType = new WeakReference<Class<? extends RpcService>>(service);
@@ -771,10 +767,10 @@ public class BindingIndependentConnector implements //
     private class DefaultInvocationStrategy extends RpcInvocationStrategy {
 
         @SuppressWarnings("rawtypes")
-        private WeakReference<Class> inputClass;
+        private final WeakReference<Class> inputClass;
 
         @SuppressWarnings("rawtypes")
-        private WeakReference<Class> outputClass;
+        private final WeakReference<Class> outputClass;
 
         @SuppressWarnings({ "rawtypes", "unchecked" })
         public DefaultInvocationStrategy(QName rpc, Method targetMethod, Class<?> outputClass,
@@ -803,10 +799,10 @@ public class BindingIndependentConnector implements //
 
         @Override
         public Future<RpcResult<?>> forwardToDomBroker(DataObject input) {
-            if(biRouter != null) {
+            if(biRpcRegistry != null) {
                 CompositeNode xml = mappingService.toDataDom(input);
                 CompositeNode wrappedXml = ImmutableCompositeNode.create(rpc, ImmutableList.<Node<?>> of(xml));
-                RpcResult<CompositeNode> result = biRouter.invokeRpc(rpc, wrappedXml);
+                RpcResult<CompositeNode> result = biRpcRegistry.invokeRpc(rpc, wrappedXml);
                 Object baResultValue = null;
                 if (result.getResult() != null) {
                     baResultValue = mappingService.dataObjectFromDataDom(outputClass.get(), result.getResult());
@@ -825,6 +821,7 @@ public class BindingIndependentConnector implements //
             super(rpc, targetMethod);
         }
 
+        @Override
         public RpcResult<CompositeNode> uncheckedInvoke(RpcService rpcService, CompositeNode domInput) throws Exception {
             @SuppressWarnings("unchecked")
             Future<RpcResult<Void>> result = (Future<RpcResult<Void>>) targetMethod.invoke(rpcService);
@@ -837,21 +834,21 @@ public class BindingIndependentConnector implements //
             return Futures.immediateFuture(null);
         }
     }
-    
+
     private class NoOutputInvocationStrategy extends RpcInvocationStrategy {
 
-        
+
         @SuppressWarnings("rawtypes")
-        private WeakReference<Class> inputClass;
+        private final WeakReference<Class> inputClass;
 
         @SuppressWarnings({ "rawtypes", "unchecked" })
-        public NoOutputInvocationStrategy(QName rpc, Method targetMethod, 
+        public NoOutputInvocationStrategy(QName rpc, Method targetMethod,
                 Class<? extends DataContainer> inputClass) {
             super(rpc,targetMethod);
             this.inputClass = new WeakReference(inputClass);
         }
-        
-        
+
+
         @Override
         public RpcResult<CompositeNode> uncheckedInvoke(RpcService rpcService, CompositeNode domInput) throws Exception {
             DataContainer bindingInput = mappingService.dataObjectFromDataDom(inputClass.get(), domInput);
@@ -865,10 +862,10 @@ public class BindingIndependentConnector implements //
 
         @Override
         public Future<RpcResult<?>> forwardToDomBroker(DataObject input) {
-            if(biRouter != null) {
+            if(biRpcRegistry != null) {
                 CompositeNode xml = mappingService.toDataDom(input);
                 CompositeNode wrappedXml = ImmutableCompositeNode.create(rpc,ImmutableList.<Node<?>>of(xml));
-                RpcResult<CompositeNode> result = biRouter.invokeRpc(rpc, wrappedXml);
+                RpcResult<CompositeNode> result = biRpcRegistry.invokeRpc(rpc, wrappedXml);
                 Object baResultValue = null;
                 RpcResult<?> baResult = Rpcs.<Void>getRpcResult(result.isSuccessful(), null, result.getErrors());
                 return Futures.<RpcResult<?>>immediateFuture(baResult);
@@ -902,12 +899,12 @@ public class BindingIndependentConnector implements //
     public void setDomNotificationService(NotificationPublishService domService) {
         this.domNotificationService = domService;
     }
-    
+
     private class DomToBindingNotificationForwarder implements NotificationInterestListener, NotificationListener {
 
-        private ConcurrentMap<QName, WeakReference<Class<? extends Notification>>> notifications = new ConcurrentHashMap<>();
-        private Set<QName> supportedNotifications = new HashSet<>();
-        
+        private final ConcurrentMap<QName, WeakReference<Class<? extends Notification>>> notifications = new ConcurrentHashMap<>();
+        private final Set<QName> supportedNotifications = new HashSet<>();
+
         @Override
         public Set<QName> getSupportedNotifications() {
             return Collections.unmodifiableSet(supportedNotifications);
@@ -922,7 +919,7 @@ public class BindingIndependentConnector implements //
                 if (potentialClass != null) {
                     final DataContainer baNotification = mappingService.dataObjectFromDataDom(potentialClass,
                             notification);
-                    
+
                     if (baNotification instanceof Notification) {
                         baNotifyService.publish((Notification) baNotification);
                     }
index d87e272..cb71b4f 100644 (file)
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>config-api</artifactId>
-            <version>0.2.4-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>sal-binding-api</artifactId>
-            <version>1.1-SNAPSHOT</version>
         </dependency>
     </dependencies>
 </project>
index 8560848..82e3d97 100644 (file)
           <groupId>org.ops4j.pax.exam</groupId>
           <artifactId>pax-exam-container-native</artifactId>
           <scope>test</scope>
-          <version>${exam.version}</version>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>sal-binding-broker-impl</artifactId>
-            <version>1.1-SNAPSHOT</version>
             <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>sal-binding-broker-impl</artifactId>
-            <version>1.1-SNAPSHOT</version>
             <type>test-jar</type>
             <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.controller.model</groupId>
             <artifactId>model-flow-service</artifactId>
-            <version>1.1-SNAPSHOT</version>
             <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.controller.model</groupId>
             <artifactId>model-flow-management</artifactId>
-            <version>1.1-SNAPSHOT</version>
             <scope>test</scope>
         </dependency>
         <dependency>
index 598743a..90fa2be 100644 (file)
@@ -6,9 +6,11 @@
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
 package org.opendaylight.controller.sal.binding.test.bugfix;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
 
 import java.util.Collections;
 import java.util.Map;
@@ -52,38 +54,42 @@ public class PutAugmentationTest extends AbstractDataServiceTest implements Data
     private static final InstanceIdentifier<Nodes> NODES_INSTANCE_ID_BA = InstanceIdentifier.builder(Nodes.class) //
             .toInstance();
 
-
     private static final InstanceIdentifier<Node> NODE_INSTANCE_ID_BA = InstanceIdentifier//
             .builder(NODES_INSTANCE_ID_BA) //
             .child(Node.class, NODE_KEY).toInstance();
 
-
     private static final InstanceIdentifier<SupportedActions> SUPPORTED_ACTIONS_INSTANCE_ID_BA = InstanceIdentifier//
             .builder(NODES_INSTANCE_ID_BA) //
             .child(Node.class, NODE_KEY) //
             .augmentation(FlowCapableNode.class) //
-            .child(SupportedActions.class)
-            .toInstance();
+            .child(SupportedActions.class).toInstance();
 
+    private static final InstanceIdentifier<FlowCapableNode> ALL_FLOW_CAPABLE_NODES = InstanceIdentifier //
+            .builder(NODES_INSTANCE_ID_BA) //
+            .child(Node.class) //
+            .augmentation(FlowCapableNode.class) //
+            .build();
 
     private static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier NODE_INSTANCE_ID_BI = //
     org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.builder() //
             .node(Nodes.QNAME) //
             .nodeWithKey(Node.QNAME, NODE_KEY_BI) //
             .toInstance();
-    private static final QName SUPPORTED_ACTIONS_QNAME = QName.create(FlowCapableNode.QNAME, SupportedActions.QNAME.getLocalName());
-
+    private static final QName SUPPORTED_ACTIONS_QNAME = QName.create(FlowCapableNode.QNAME,
+            SupportedActions.QNAME.getLocalName());
 
     private static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier SUPPORTED_ACTIONS_INSTANCE_ID_BI = //
-            org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.builder() //
-                    .node(Nodes.QNAME) //
-                    .nodeWithKey(Node.QNAME, NODE_KEY_BI) //
-                    .node(SUPPORTED_ACTIONS_QNAME) //
-                    .toInstance();
-
-    private DataChangeEvent<InstanceIdentifier<?>, DataObject> receivedChangeEvent;
-
+    org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.builder() //
+            .node(Nodes.QNAME) //
+            .nodeWithKey(Node.QNAME, NODE_KEY_BI) //
+            .node(SUPPORTED_ACTIONS_QNAME) //
+            .toInstance();
+    private static final InstanceIdentifier<FlowCapableNode> FLOW_AUGMENTATION_PATH = InstanceIdentifier //
+            .builder(NODE_INSTANCE_ID_BA) //
+            .augmentation(FlowCapableNode.class) //
+            .build();
 
+    private DataChangeEvent<InstanceIdentifier<?>, DataObject> lastReceivedChangeEvent;
 
     /**
      * Test for Bug 148
@@ -93,7 +99,8 @@ public class PutAugmentationTest extends AbstractDataServiceTest implements Data
     @Test
     public void putNodeAndAugmentation() throws Exception {
 
-        baDataService.registerDataChangeListener(NODES_INSTANCE_ID_BA, this);
+        baDataService.registerDataChangeListener(ALL_FLOW_CAPABLE_NODES, this);
+
 
         NodeBuilder nodeBuilder = new NodeBuilder();
         nodeBuilder.setId(new NodeId(NODE_ID));
@@ -102,7 +109,7 @@ public class PutAugmentationTest extends AbstractDataServiceTest implements Data
         baseTransaction.putOperationalData(NODE_INSTANCE_ID_BA, nodeBuilder.build());
         RpcResult<TransactionStatus> result = baseTransaction.commit().get();
         assertEquals(TransactionStatus.COMMITED, result.getResult());
-        assertNotNull(receivedChangeEvent);
+
         Node node = (Node) baDataService.readOperationalData(NODE_INSTANCE_ID_BA);
         assertNotNull(node);
         assertEquals(NODE_KEY, node.getKey());
@@ -114,13 +121,16 @@ public class PutAugmentationTest extends AbstractDataServiceTest implements Data
         fnub.setDescription("Description Foo");
         fnub.setSoftware("JUnit emulated");
         FlowCapableNode fnu = fnub.build();
-        InstanceIdentifier<FlowCapableNode> augmentIdentifier = InstanceIdentifier.builder(NODE_INSTANCE_ID_BA).augmentation(FlowCapableNode.class).toInstance();
+        InstanceIdentifier<FlowCapableNode> augmentIdentifier = InstanceIdentifier.builder(NODE_INSTANCE_ID_BA)
+                .augmentation(FlowCapableNode.class).toInstance();
         DataModificationTransaction augmentedTransaction = baDataService.beginTransaction();
         augmentedTransaction.putOperationalData(augmentIdentifier, fnu);
 
         result = augmentedTransaction.commit().get();
         assertEquals(TransactionStatus.COMMITED, result.getResult());
 
+        assertNotNull(lastReceivedChangeEvent);
+        assertTrue(lastReceivedChangeEvent.getCreatedOperationalData().containsKey(FLOW_AUGMENTATION_PATH));
 
         Node augmentedNode = (Node) baDataService.readOperationalData(NODE_INSTANCE_ID_BA);
         assertNotNull(node);
@@ -131,11 +141,14 @@ public class PutAugmentationTest extends AbstractDataServiceTest implements Data
         assertEquals(fnu.getDescription(), readedAugmentation.getDescription());
         assertBindingIndependentVersion(NODE_INSTANCE_ID_BI);
         testNodeRemove();
+        assertTrue(lastReceivedChangeEvent.getRemovedOperationalData().contains(FLOW_AUGMENTATION_PATH));
     }
 
     @Test
     public void putNodeWithAugmentation() throws Exception {
 
+        baDataService.registerDataChangeListener(ALL_FLOW_CAPABLE_NODES, this);
+
         NodeBuilder nodeBuilder = new NodeBuilder();
         nodeBuilder.setId(new NodeId(NODE_ID));
         nodeBuilder.setKey(NODE_KEY);
@@ -151,23 +164,31 @@ public class PutAugmentationTest extends AbstractDataServiceTest implements Data
         DataModificationTransaction baseTransaction = baDataService.beginTransaction();
         baseTransaction.putOperationalData(NODE_INSTANCE_ID_BA, nodeBuilder.build());
         RpcResult<TransactionStatus> result = baseTransaction.commit().get();
+
+        assertNotNull(lastReceivedChangeEvent);
+        assertTrue(lastReceivedChangeEvent.getCreatedOperationalData().containsKey(FLOW_AUGMENTATION_PATH));
+        lastReceivedChangeEvent = null;
         assertEquals(TransactionStatus.COMMITED, result.getResult());
 
-        FlowCapableNode readedAugmentation = (FlowCapableNode) baDataService.readOperationalData(InstanceIdentifier.builder(NODE_INSTANCE_ID_BA).augmentation(FlowCapableNode.class).toInstance());
+        FlowCapableNode readedAugmentation = (FlowCapableNode) baDataService.readOperationalData(InstanceIdentifier
+                .builder(NODE_INSTANCE_ID_BA).augmentation(FlowCapableNode.class).toInstance());
         assertNotNull(readedAugmentation);
+
         assertEquals(fnu.getHardware(), readedAugmentation.getHardware());
 
         testPutNodeConnectorWithAugmentation();
+        lastReceivedChangeEvent = null;
         testNodeRemove();
-    }
 
+        assertTrue(lastReceivedChangeEvent.getRemovedOperationalData().contains(FLOW_AUGMENTATION_PATH));
+    }
 
     private void testPutNodeConnectorWithAugmentation() throws Exception {
         NodeConnectorKey ncKey = new NodeConnectorKey(new NodeConnectorId("test:0:0"));
         InstanceIdentifier<NodeConnector> ncPath = InstanceIdentifier.builder(NODE_INSTANCE_ID_BA)
-        .child(NodeConnector.class, ncKey).toInstance();
+                .child(NodeConnector.class, ncKey).toInstance();
         InstanceIdentifier<FlowCapableNodeConnector> ncAugmentPath = InstanceIdentifier.builder(ncPath)
-        .augmentation(FlowCapableNodeConnector.class).toInstance();
+                .augmentation(FlowCapableNodeConnector.class).toInstance();
 
         NodeConnectorBuilder nc = new NodeConnectorBuilder();
         nc.setKey(ncKey);
@@ -181,7 +202,8 @@ public class PutAugmentationTest extends AbstractDataServiceTest implements Data
         RpcResult<TransactionStatus> result = baseTransaction.commit().get();
         assertEquals(TransactionStatus.COMMITED, result.getResult());
 
-        FlowCapableNodeConnector readedAugmentation = (FlowCapableNodeConnector) baDataService.readOperationalData(ncAugmentPath);
+        FlowCapableNodeConnector readedAugmentation = (FlowCapableNodeConnector) baDataService
+                .readOperationalData(ncAugmentPath);
         assertNotNull(readedAugmentation);
         assertEquals(fncb.getName(), readedAugmentation.getName());
     }
@@ -196,7 +218,7 @@ public class PutAugmentationTest extends AbstractDataServiceTest implements Data
         assertNull(node);
     }
 
-    private void verifyNodes(Nodes nodes,Node original) {
+    private void verifyNodes(Nodes nodes, Node original) {
         assertNotNull(nodes);
         assertNotNull(nodes.getNode());
         assertEquals(1, nodes.getNode().size());
@@ -212,8 +234,7 @@ public class PutAugmentationTest extends AbstractDataServiceTest implements Data
 
     }
 
-    private void assertBindingIndependentVersion(
-            org.opendaylight.yangtools.yang.data.api.InstanceIdentifier nodeId) {
+    private void assertBindingIndependentVersion(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier nodeId) {
         CompositeNode node = biDataService.readOperationalData(nodeId);
         assertNotNull(node);
     }
@@ -224,7 +245,7 @@ public class PutAugmentationTest extends AbstractDataServiceTest implements Data
 
     @Override
     public void onDataChanged(DataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
-        receivedChangeEvent = change;
+        lastReceivedChangeEvent = change;
     }
 
 }
index eaf5984..9bc8a48 100644 (file)
@@ -19,9 +19,6 @@
         <!-- Sonar jacoco plugin to get integration test coverage info -->
         <sonar.jacoco.reportPath>../sal-binding-broker/target/jacoco.exec</sonar.jacoco.reportPath>
         <sonar.jacoco.itReportPath>../sal-binding-broker/target/jacoco-it.exec</sonar.jacoco.itReportPath>
-        <netconf.version>0.2.4-SNAPSHOT</netconf.version>
-        <config.version>0.2.4-SNAPSHOT</config.version>
-        <moxy.controller.version>2.5.0</moxy.controller.version>
     </properties>
 
     <build>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>sal-binding-broker-impl</artifactId>
-            <version>1.1-SNAPSHOT</version>
             <scope>provided</scope>
         </dependency>
         <dependency>
             <groupId>org.ops4j.pax.exam</groupId>
             <artifactId>pax-exam-container-native</artifactId>
-            <version>${exam.version}</version>
             <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>org.ops4j.pax.exam</groupId>
             <artifactId>pax-exam-junit4</artifactId>
-            <version>${exam.version}</version>
             <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>config-netconf-connector</artifactId>
-            <version>${netconf.version}</version>
             <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>yang-store-impl</artifactId>
-            <version>${config.version}</version>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>logback-config</artifactId>
-            <version>${config.version}</version>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>config-persister-impl</artifactId>
-            <version>${config.version}</version>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>config-persister-file-xml-adapter</artifactId>
-            <version>${config.version}</version>
         </dependency>
         <dependency>
             <groupId>org.eclipse.persistence</groupId>
             <artifactId>org.eclipse.persistence.moxy</artifactId>
-            <version>${moxy.controller.version}</version>
         </dependency>
         <dependency>
             <groupId>org.eclipse.persistence</groupId>
             <artifactId>org.eclipse.persistence.core</artifactId>
-            <version>${moxy.controller.version}</version>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>netconf-impl</artifactId>
-            <version>${netconf.version}</version>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>netconf-monitoring</artifactId>
-            <version>${netconf.version}</version>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>netconf-client</artifactId>
-            <version>${netconf.version}</version>
         </dependency>
         <dependency>
             <groupId>org.ops4j.pax.exam</groupId>
         <dependency>
             <groupId>org.ops4j.pax.exam</groupId>
             <artifactId>pax-exam-link-mvn</artifactId>
-            <version>${exam.version}</version>
             <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>equinoxSDK381</groupId>
             <artifactId>org.eclipse.osgi</artifactId>
-            <version>3.8.1.v20120830-144521</version>
             <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>org.slf4j</groupId>
             <artifactId>log4j-over-slf4j</artifactId>
-            <version>1.7.2</version>
         </dependency>
         <dependency>
             <groupId>ch.qos.logback</groupId>
             <artifactId>logback-core</artifactId>
-            <version>1.0.9</version>
         </dependency>
         <dependency>
             <groupId>ch.qos.logback</groupId>
             <artifactId>logback-classic</artifactId>
-            <version>1.0.9</version>
         </dependency>
         <dependency>
             <groupId>org.mockito</groupId>
         <dependency>
             <groupId>org.opendaylight.controller.model</groupId>
             <artifactId>model-flow-service</artifactId>
-            <version>1.1-SNAPSHOT</version>
             <scope>provided</scope>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>config-manager</artifactId>
-            <version>0.2.4-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.controller.model</groupId>
             <artifactId>model-flow-management</artifactId>
-            <version>1.1-SNAPSHOT</version>
             <scope>provided</scope>
         </dependency>
         <dependency>
index 747e420..4842d8c 100644 (file)
@@ -22,7 +22,6 @@
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>sal-binding-api</artifactId>
-            <version>1.1-SNAPSHOT</version>
         </dependency>
     </dependencies>
 </project>
index 5dd08d0..8a2571c 100644 (file)
@@ -17,7 +17,6 @@
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>sal-common</artifactId>
-            <version>1.1-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.yangtools</groupId>
@@ -30,7 +29,6 @@
         <dependency>
             <groupId>org.osgi</groupId>
             <artifactId>org.osgi.core</artifactId>
-            <version>5.0.0</version>
         </dependency>
     </dependencies>
     <packaging>bundle</packaging>
index 92ff551..a8989c4 100644 (file)
@@ -8,9 +8,26 @@
 package org.opendaylight.controller.md.sal.common.api;
 
 public enum TransactionStatus {
+    /**
+     * The transaction has been freshly allocated. The user is still accessing
+     * it and it has not been sealed.
+     */
     NEW,
+    /**
+     * The transaction has been completed by the user and sealed. It is currently
+     * awaiting execution.
+     */
     SUBMITED,
+    /**
+     * The transaction has been successfully committed to backing store.
+     */
     COMMITED,
+    /**
+     * The transaction has failed to commit due to some underlying issue.
+     */
     FAILED,
-    CANCELED
+    /**
+     * Currently unused.
+     */
+    CANCELED,
 }