Merge "Add unit tests for sal-netconf-connector"
authorTomas Cere <tcere@cisco.com>
Mon, 24 Oct 2016 10:18:14 +0000 (10:18 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Mon, 24 Oct 2016 10:18:14 +0000 (10:18 +0000)
176 files changed:
features/netconf-connector/pom.xml
features/netconf-connector/src/main/features/features.xml
features/netconf/pom.xml
features/netconf/src/main/features/features.xml
netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/InitialStateProvider.java [deleted file]
netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/NodeListener.java [deleted file]
netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/NodeManager.java [deleted file]
netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/NodeManagerCallback.java [deleted file]
netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/RemoteNodeListener.java [deleted file]
netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/RoleChangeListener.java [deleted file]
netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/RoleChangeStrategy.java [deleted file]
netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/StateAggregator.java [deleted file]
netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/TopologyManager.java [deleted file]
netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/TopologyManagerCallback.java [deleted file]
netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/example/ExampleNodeManagerCallback.java [deleted file]
netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/example/ExampleSingleStateAggregator.java [deleted file]
netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/example/ExampleTopology.java [deleted file]
netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/example/ExampleTopologyManagerCallback.java [deleted file]
netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/example/LoggingSalNodeWriter.java [deleted file]
netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/util/BaseNodeManager.java [deleted file]
netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/util/BaseTopologyManager.java [deleted file]
netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/util/NodeRoleChangeStrategy.java [deleted file]
netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/util/NodeWriter.java [deleted file]
netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/util/NoopRoleChangeStrategy.java [deleted file]
netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/util/SalNodeWriter.java [deleted file]
netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/util/TopologyRoleChangeStrategy.java [deleted file]
netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/util/messages/CustomIdentifyMessage.java [deleted file]
netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/util/messages/CustomIdentifyMessageReply.java [deleted file]
netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/util/messages/NormalizedNodeMessage.java [deleted file]
netconf/messagebus-netconf/src/main/java/org/opendaylight/netconf/messagebus/eventsources/netconf/NetconfEventSourceRegistration.java
netconf/messagebus-netconf/src/test/java/org/opendaylight/netconf/messagebus/eventsources/netconf/NetconfTestUtils.java
netconf/netconf-artifacts/pom.xml
netconf/netconf-console/src/main/java/org/opendaylight/netconf/console/impl/NetconfCommandsImpl.java
netconf/netconf-console/src/test/java/org/opendaylight/netconf/console/impl/NetconfCommandsImplTest.java
netconf/netconf-console/src/test/resources/schemas/netconf-node-topology.yang
netconf/netconf-notifications-api/src/test/java/org/opendaylight/netconf/notifications/NetconfNotificationTest.java [new file with mode: 0644]
netconf/netconf-ssh/pom.xml
netconf/netconf-ssh/src/main/java/org/opendaylight/netconf/ssh/osgi/NetconfSSHActivator.java
netconf/netconf-tcp/pom.xml
netconf/netconf-tcp/src/main/java/org/opendaylight/netconf/tcp/osgi/NetconfTCPActivator.java
netconf/netconf-topology-config/pom.xml
netconf/netconf-topology-config/src/main/resources/initial/02-clustered-netconf-topology.xml [deleted file]
netconf/netconf-topology-singleton/pom.xml [moved from netconf/abstract-topology/pom.xml with 64% similarity]
netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/api/NetconfDOMTransaction.java [new file with mode: 0644]
netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/api/NetconfTopologySingletonService.java [moved from netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/pipeline/tx/NetconfDeviceDataBrokerProxy.java with 50% similarity]
netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/api/RemoteDeviceConnector.java [new file with mode: 0644]
netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/api/RemoteOperationTxProcessor.java [new file with mode: 0644]
netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/MasterSalFacade.java [new file with mode: 0644]
netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/NetconfDOMDataBroker.java [moved from netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/pipeline/NetconfDeviceSlaveDataBroker.java with 68% similarity]
netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/NetconfNodeManager.java [new file with mode: 0644]
netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/NetconfTopologyContext.java [new file with mode: 0644]
netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/NetconfTopologyManager.java [new file with mode: 0644]
netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/ProxyDOMRpcService.java [new file with mode: 0644]
netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/ProxyYangTextSourceProvider.java [new file with mode: 0644]
netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/RemoteDeviceConnectorImpl.java [new file with mode: 0644]
netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/RemoteOperationTxProcessorImpl.java [new file with mode: 0644]
netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/SlaveSalFacade.java [new file with mode: 0644]
netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/actors/NetconfNodeActor.java [new file with mode: 0644]
netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/tx/NetconfMasterDOMTransaction.java [new file with mode: 0644]
netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/tx/NetconfProxyDOMTransaction.java [new file with mode: 0644]
netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/tx/NetconfReadOnlyTransaction.java [moved from netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/pipeline/tx/ProxyReadOnlyTransaction.java with 64% similarity]
netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/tx/NetconfWriteOnlyTransaction.java [new file with mode: 0644]
netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/utils/NetconfConnectorDTO.java [new file with mode: 0644]
netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/utils/NetconfTopologySetup.java [new file with mode: 0644]
netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/utils/NetconfTopologyUtils.java [new file with mode: 0644]
netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/messages/AskForMasterMountPoint.java [new file with mode: 0644]
netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/messages/CreateInitialMasterActorData.java [new file with mode: 0644]
netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/messages/MasterActorDataInitialized.java [new file with mode: 0644]
netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/messages/NormalizedNodeMessage.java [new file with mode: 0644]
netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/messages/RefreshSetupMasterActorData.java [new file with mode: 0644]
netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/messages/RegisterMountPoint.java [new file with mode: 0644]
netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/messages/UnregisterSlaveMountPoint.java [new file with mode: 0644]
netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/messages/YangTextSchemaSourceRequest.java [new file with mode: 0644]
netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/messages/transactions/CancelRequest.java [new file with mode: 0644]
netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/messages/transactions/DeleteRequest.java [new file with mode: 0644]
netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/messages/transactions/EmptyReadResponse.java [moved from netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/util/messages/AnnounceMasterMountPoint.java with 55% similarity]
netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/messages/transactions/ExistsRequest.java [new file with mode: 0644]
netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/messages/transactions/MergeRequest.java [new file with mode: 0644]
netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/messages/transactions/PutRequest.java [new file with mode: 0644]
netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/messages/transactions/ReadRequest.java [new file with mode: 0644]
netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/messages/transactions/SubmitFailedReply.java [new file with mode: 0644]
netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/messages/transactions/SubmitReply.java [moved from netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/util/messages/AnnounceMasterMountPointDown.java with 53% similarity]
netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/messages/transactions/SubmitRequest.java [new file with mode: 0644]
netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/messages/transactions/TransactionRequest.java [new file with mode: 0644]
netconf/netconf-topology-singleton/src/main/resources/org/opendaylight/blueprint/netconf-topology-singleton.xml [new file with mode: 0644]
netconf/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/NetconfNodeActorTest.java [new file with mode: 0644]
netconf/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/NetconfTopologyManagerTest.java [new file with mode: 0644]
netconf/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/RemoteDeviceConnectorImplTest.java [new file with mode: 0644]
netconf/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/TestingRemoteDeviceConnectorImpl.java [new file with mode: 0644]
netconf/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/tx/ReadOnlyTransactionTest.java [new file with mode: 0644]
netconf/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/tx/WriteOnlyTransactionTest.java [new file with mode: 0644]
netconf/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/utils/NetconfTopologyUtilTest.java [new file with mode: 0644]
netconf/netconf-topology/pom.xml
netconf/netconf-topology/src/main/java/org/opendaylight/controller/config/yang/clustered/netconf/topology/ClusteredNetconfTopologyModule.java [deleted file]
netconf/netconf-topology/src/main/java/org/opendaylight/controller/config/yang/clustered/netconf/topology/ClusteredNetconfTopologyModuleFactory.java [deleted file]
netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/AbstractNetconfTopology.java
netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/NetconfTopology.java
netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/impl/ClusteredNetconfTopology.java [deleted file]
netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/impl/NetconfNodeManagerCallback.java [deleted file]
netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/impl/NetconfNodeOperationalDataAggregator.java [deleted file]
netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/impl/NetconfTopologyImpl.java
netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/impl/NetconfTopologyManagerCallback.java [deleted file]
netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/impl/TopologyNodeWriter.java [deleted file]
netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/impl/TopologyUtil.java [moved from netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/util/TopologyUtil.java with 84% similarity]
netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/pipeline/ClusteredDeviceSourcesResolver.java [deleted file]
netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/pipeline/ClusteredDeviceSourcesResolverImpl.java [deleted file]
netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/pipeline/ClusteredNetconfDevice.java [deleted file]
netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/pipeline/ClusteredNetconfDeviceCommunicator.java [deleted file]
netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/pipeline/ClusteredNetconfDeviceMountInstanceProxy.java [deleted file]
netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/pipeline/MasterSourceProvider.java [deleted file]
netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/pipeline/MasterSourceProviderImpl.java [deleted file]
netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/pipeline/MasterSourceProviderOnSameNodeException.java [deleted file]
netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/pipeline/NetconfDeviceMasterDataBroker.java [deleted file]
netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/pipeline/ProxyNetconfDeviceDataBroker.java [deleted file]
netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/pipeline/TopologyMountPointFacade.java [deleted file]
netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/pipeline/messages/AnnounceClusteredDeviceSourcesResolverUp.java [deleted file]
netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/pipeline/messages/AnnounceMasterOnSameNodeUp.java [deleted file]
netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/pipeline/messages/AnnounceMasterSourceProviderUp.java [deleted file]
netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/pipeline/tx/ProxyWriteOnlyTransaction.java [deleted file]
netconf/netconf-topology/src/main/yang/clustered-netconf-topology.yang [deleted file]
netconf/netconf-topology/src/test/java/org/opendaylight/netconf/topology/AbstractNetconfTopologyTest.java [deleted file]
netconf/netconf-topology/src/test/java/org/opendaylight/netconf/topology/ActorTest.java [deleted file]
netconf/netconf-topology/src/test/java/org/opendaylight/netconf/topology/TestingEntityOwnershipService.java [deleted file]
netconf/netconf-topology/src/test/java/org/opendaylight/netconf/topology/TestingTopologyDispatcher.java [deleted file]
netconf/netconf-topology/src/test/java/org/opendaylight/netconf/topology/impl/NetconfNodeOperationalDataAggregatorTest.java [deleted file]
netconf/netconf-topology/src/test/java/org/opendaylight/netconf/topology/impl/NetconfTopologyImplTest.java
netconf/netconf-topology/src/test/java/org/opendaylight/netconf/topology/impl/TopologyNodeWriterTest.java [deleted file]
netconf/netconf-topology/src/test/java/org/opendaylight/netconf/topology/pipeline/ClusteredNetconfDeviceCommunicatorTest.java [deleted file]
netconf/netconf-topology/src/test/java/org/opendaylight/netconf/topology/pipeline/NetconfDeviceSlaveDataBrokerTest.java [deleted file]
netconf/netconf-topology/src/test/java/org/opendaylight/netconf/topology/pipeline/TopologyMountPointFacadeTest.java [deleted file]
netconf/netconf-topology/src/test/java/org/opendaylight/netconf/topology/pipeline/tx/ProxyReadOnlyTransactionTest.java [deleted file]
netconf/netconf-topology/src/test/java/org/opendaylight/netconf/topology/pipeline/tx/ProxyWriteOnlyTransactionTest.java [deleted file]
netconf/netconf-topology/src/test/resources/netconf-node1.conf [deleted file]
netconf/netconf-topology/src/test/resources/netconf-node2.conf [deleted file]
netconf/netconf-topology/src/test/resources/netconf-node3.conf [deleted file]
netconf/netconf-topology/src/test/resources/test.conf [deleted file]
netconf/netconf-util/pom.xml
netconf/netconf-util/src/main/java/org/opendaylight/netconf/util/osgi/NetconfConfigUtil.java
netconf/netconf-util/src/main/java/org/opendaylight/netconf/util/osgi/NetconfConfiguration.java [new file with mode: 0644]
netconf/netconf-util/src/main/java/org/opendaylight/netconf/util/osgi/NetconfConfigurationActivator.java [new file with mode: 0644]
netconf/netconf-util/src/main/java/org/opendaylight/netconf/util/osgi/NetconfConfigurationHolder.java [new file with mode: 0644]
netconf/netconf-util/src/main/resources/netconf.cfg [new file with mode: 0644]
netconf/netconf-util/src/test/resources/netconfMessages/copy-config.xml [new file with mode: 0644]
netconf/netconf-util/src/test/resources/netconfMessages/edit-config-test-module-running.xml [new file with mode: 0644]
netconf/netconf-util/src/test/resources/netconfMessages/edit-config-test-module.xml [new file with mode: 0644]
netconf/netconf-util/src/test/resources/netconfMessages/getConfig_candidate-filter.xml [new file with mode: 0644]
netconf/netconf-util/src/test/resources/netconfMessages/lock-running.xml [new file with mode: 0644]
netconf/netconf-util/src/test/resources/netconfMessages/rpc-reply_get.xml [new file with mode: 0644]
netconf/netconf-util/src/test/resources/netconfMessages/unlock-running.xml [new file with mode: 0644]
netconf/netconf-util/src/test/resources/netconfMessages/validate-running.xml [new file with mode: 0644]
netconf/pom.xml
netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/connector/netconf/NetconfConnectorModule.java
netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/NetconfDevice.java
netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/NetconfStateSchemas.java
netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/listener/NetconfDeviceCapabilities.java
netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/listener/NetconfSessionPreferences.java
netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceTopologyAdapter.java
netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/tx/WriteCandidateTx.java
netconf/sal-netconf-connector/src/main/yang/netconf-node-topology.yang
netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/NetconfDeviceTest.java
netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/NetconfStateSchemasTest.java
netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/listener/NetconfDeviceCommunicatorTest.java
netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/sal/MountInstanceTest.java
netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceSalProviderTest.java [new file with mode: 0644]
netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/sal/tx/ReadOnlyTxTest.java
netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/sal/tx/ReadWriteTxTest.java [new file with mode: 0644]
netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/sal/tx/TxTestUtils.java [new file with mode: 0644]
netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/sal/tx/WriteCandidateRunningTxTest.java [new file with mode: 0644]
netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/sal/tx/WriteCandidateTxTest.java [new file with mode: 0644]
netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/sal/tx/WriteRunningTxTest.java
netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/util/NetconfBaseOpsTest.java [new file with mode: 0644]
netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/util/NodeContainerProxyTest.java [new file with mode: 0644]
netconf/sal-netconf-connector/src/test/resources/schemas/netconf-node-topology.yang
restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/rest/services/impl/ModuleImpl.java
restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/restful/utils/PostDataTransactionUtil.java
restconf/sal-rest-connector/src/test/java/org/opendaylight/restconf/restful/utils/PostDataTransactionUtilTest.java

index cf4131026bb253e2e3b452019b1adb97074261c5..9600b0ba5aa50cd7c8c73458da2c8ed50c608af4 100644 (file)
       <classifier>config</classifier>
       <type>xml</type>
     </dependency>
-    <dependency>
-      <groupId>${project.groupId}</groupId>
-      <artifactId>abstract-topology</artifactId>
-    </dependency>
     <dependency>
       <groupId>${project.groupId}</groupId>
       <artifactId>netconf-topology</artifactId>
       <classifier>config</classifier>
       <type>xml</type>
     </dependency>
-    <dependency>
-       <groupId>${project.groupId}</groupId>
-       <artifactId>netconf-topology-config</artifactId>
-       <classifier>clustered-config</classifier>
-       <type>xml</type>
-    </dependency>
     <dependency>
       <groupId>${project.groupId}</groupId>
       <artifactId>netconf-tcp</artifactId>
       <groupId>org.bouncycastle</groupId>
       <artifactId>bcprov-jdk15on</artifactId>
     </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>netconf-topology-singleton</artifactId>
+    </dependency>
 
     <dependency>
       <groupId>${project.groupId}</groupId>
index fe3e66dba3ced96accabdbc0f98c5b10115d1d8a..27c883f2211198353299047f1fa5da04474a23d3 100644 (file)
@@ -38,7 +38,6 @@
         <bundle>mvn:org.opendaylight.netconf/sal-netconf-connector/{{VERSION}}</bundle>
         <bundle>mvn:org.opendaylight.controller.model/model-inventory/{{VERSION}}</bundle>
         <bundle>mvn:org.opendaylight.netconf/netconf-topology/{{VERSION}}</bundle>
-        <bundle>mvn:org.opendaylight.netconf/abstract-topology/{{VERSION}}</bundle>
         <bundle>mvn:org.opendaylight.netconf/sal-netconf-connector/{{VERSION}}</bundle>
         <bundle>mvn:org.opendaylight.netconf/netconf-config-dispatcher/{{VERSION}}</bundle>
         <configfile finalname='${config.configfile.directory}/${config.netconf.client.configfile}'>mvn:org.opendaylight.netconf/netconf-config/{{VERSION}}/xml/config</configfile>
         <configfile finalname='${config.configfile.directory}/${config.netconf.topology.configfile}'>mvn:org.opendaylight.netconf/netconf-topology-config/{{VERSION}}/xml/config</configfile>
     </feature>
 
-    <feature name='odl-netconf-clustered-topology' version='${project.version}' description="OpenDaylight :: Clustered Netconf Topology :: Netconf Connector + Netconf SSH Server + Clustered Netconf configuration via config topology datastore">
-        <feature version='${netconf.version}'>odl-netconf-ssh</feature>
+    <feature name='odl-netconf-clustered-topology' version='${project.version}' description="OpenDaylight :: Clustered Netconf Topology :: Netconf Connector + Netconf SSH Server">
+        <feature version='${project.version}'>odl-netconf-ssh</feature>
         <feature version='${project.version}'>odl-netconf-connector</feature>
-        <configfile finalname='${config.configfile.directory}/${config.netconf.topology.configfile}'>mvn:org.opendaylight.netconf/netconf-topology-config/{{VERSION}}/xml/clustered-config</configfile>
+        <bundle>mvn:org.opendaylight.netconf/netconf-topology-singleton/{{VERSION}}</bundle>
     </feature>
 
     <feature name='odl-netconf-console' version='${project.version}' description="OpenDaylight :: Netconf Console + Karaf CLI for netconf CRUD operations">
index 4862a9523ad60c767841dde63a4283fa7b4762ad..b413f6b838d807eb4f1cc2fd2eb1e545b8db83e6 100644 (file)
       <groupId>${project.groupId}</groupId>
       <artifactId>netconf-util</artifactId>
     </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>netconf-util</artifactId>
+      <type>cfg</type>
+      <classifier>config</classifier>
+    </dependency>
     <dependency>
       <groupId>${project.groupId}</groupId>
       <artifactId>netconf-impl</artifactId>
index 645f9852823bfc3e6e72f3992ecaf812f654b02a..b43653d2a05fd2c75bfdc294fe6b2d32c9dac2cf 100644 (file)
@@ -44,6 +44,7 @@
     <feature version='${project.version}'>odl-netconf-mapping-api</feature>
     <feature version='${yangtools.version}'>odl-yangtools-yang-data</feature>
     <bundle>mvn:org.opendaylight.netconf/netconf-util/{{VERSION}}</bundle>
+    <configfile finalname="etc/netconf.cfg">mvn:org.opendaylight.netconf/netconf-util/{{VERSION}}/cfg/config</configfile>
   </feature>
 
   <feature name='odl-netconf-impl' version='${project.version}' description="OpenDaylight :: Netconf :: Impl">
   </feature>
 
   <feature name='odl-netconf-ssh' version='${project.version}' description="OpenDaylight :: Netconf Connector :: SSH">
+    <feature version='${project.version}'>odl-netconf-util</feature>
     <feature version='${project.version}'>odl-netconf-tcp</feature>
     <feature version='${project.version}'>odl-aaa-netconf-plugin</feature>
     <bundle>mvn:org.opendaylight.netconf/netconf-ssh/{{VERSION}}</bundle>
   </feature>
 
   <feature name='odl-netconf-tcp' version='${project.version}' description="OpenDaylight :: Netconf Connector :: TCP">
+    <feature version='${project.version}'>odl-netconf-util</feature>
     <feature version='${project.version}'>odl-netconf-impl</feature>
     <feature version='${config.version}'>odl-config-netty</feature>
     <bundle>mvn:org.opendaylight.netconf/netconf-tcp/{{VERSION}}</bundle>
diff --git a/netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/InitialStateProvider.java b/netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/InitialStateProvider.java
deleted file mode 100644 (file)
index ae53a9d..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.netconf.topology;
-
-import com.google.common.annotations.Beta;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-
-/**
- * Provides initial and failed state for NodeManagers
- */
-@Beta
-public interface InitialStateProvider {
-    @Nonnull
-    Node getInitialState(@Nonnull final NodeId nodeId, @Nonnull final Node configNode);
-
-    @Nonnull
-    Node getFailedState(@Nonnull final NodeId nodeId, @Nullable final Node configNode);
-}
diff --git a/netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/NodeListener.java b/netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/NodeListener.java
deleted file mode 100644 (file)
index b49d3bb..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.netconf.topology;
-
-import com.google.common.annotations.Beta;
-import com.google.common.util.concurrent.ListenableFuture;
-import javax.annotation.Nonnull;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-
-/**
- * Node events that happen on a single node on cluster, for a method to notify remote nodes of these events look into RemoteNodeListener
- */
-@Beta
-public interface NodeListener extends RoleChangeListener {
-
-    @Nonnull ListenableFuture<Node> onNodeCreated(@Nonnull NodeId nodeId, @Nonnull Node configNode);
-
-    @Nonnull ListenableFuture<Node> onNodeUpdated(@Nonnull NodeId nodeId, @Nonnull Node configNode);
-
-    @Nonnull ListenableFuture<Void> onNodeDeleted(@Nonnull NodeId nodeId);
-
-    @Nonnull ListenableFuture<Node> getCurrentStatusForNode(@Nonnull NodeId nodeId);
-}
diff --git a/netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/NodeManager.java b/netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/NodeManager.java
deleted file mode 100644 (file)
index c8ca14d..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.netconf.topology;
-
-import akka.actor.TypedActor.Receiver;
-import com.google.common.annotations.Beta;
-import org.opendaylight.netconf.sal.connect.api.RemoteDeviceHandler;
-import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences;
-
-/**
- * Node manager that handles communication between node managers and delegates calls to the customizable NodeManagerCallback
- */
-@Beta
-public interface NodeManager extends InitialStateProvider, NodeListener, Receiver, RemoteNodeListener, RemoteDeviceHandler<NetconfSessionPreferences> {
-
-}
diff --git a/netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/NodeManagerCallback.java b/netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/NodeManagerCallback.java
deleted file mode 100644 (file)
index 670bb81..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.netconf.topology;
-
-import akka.actor.ActorSystem;
-import akka.actor.TypedActor.Receiver;
-import com.google.common.annotations.Beta;
-import org.opendaylight.netconf.sal.connect.api.RemoteDeviceHandler;
-import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences;
-
-/**
- * Customizable layer that handles communication with your application.
- */
-@Beta
-public interface NodeManagerCallback extends InitialStateProvider, NodeListener, Receiver, RemoteDeviceHandler<NetconfSessionPreferences> {
-
-    interface NodeManagerCallbackFactory<M> {
-        NodeManagerCallback create(String nodeId, String topologyId, ActorSystem actorSystem);
-    }
-}
diff --git a/netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/RemoteNodeListener.java b/netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/RemoteNodeListener.java
deleted file mode 100644 (file)
index 7a8dc59..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.netconf.topology;
-
-import com.google.common.annotations.Beta;
-import org.opendaylight.netconf.topology.util.messages.NormalizedNodeMessage;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
-import scala.concurrent.Future;
-
-/**
- * Interface that provides methods of calling node events on a remote actor.
- * Use these when you want to call node events asynchronously similar to akka ask()
- */
-@Beta
-public interface RemoteNodeListener {
-
-    /**
-     * This is called when a remote node is informing you that a new configuration was recieved.
-     * @param message - serializable message to send
-     * @return response from the remote node
-     */
-    Future<NormalizedNodeMessage> onRemoteNodeCreated(NormalizedNodeMessage message);
-
-    /**
-     * This is called when a remote node is informing you that a configuration was updated.
-     * @param message - serializable message to send
-     * @return response from the remote node
-     */
-    Future<NormalizedNodeMessage> onRemoteNodeUpdated(NormalizedNodeMessage message);
-
-    /**
-     * This is called when a remote node is informing you that a new configuration was deleted.
-     * @param nodeId - id of the node which was deleted
-     * @return void future success if delete succeed, failure otherwise
-     */
-    Future<Void> onRemoteNodeDeleted(NodeId nodeId);
-
-    /**
-     * Called when a remote node is requesting a node's status, after a status change notification(f.ex sessionUp, sessionDown)
-     * on lower level
-     * @param nodeId - id of the node which status we want to retrieve
-     * @return status for the node requested
-     */
-    Future<NormalizedNodeMessage> remoteGetCurrentStatusForNode(NodeId nodeId);
-}
diff --git a/netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/RoleChangeListener.java b/netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/RoleChangeListener.java
deleted file mode 100644 (file)
index 5cf4250..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.netconf.topology;
-
-import com.google.common.annotations.Beta;
-
-/**
- * A listener that recieves {@link #onRoleChanged(RoleChangeDTO)} callbacks when a role change occurs
- */
-@Beta
-public interface RoleChangeListener {
-
-    /**
-     * Called when a role change occurs
-     * @param roleChangeDTO a DTO that wraps the current ownership status
-     */
-    void onRoleChanged(RoleChangeDTO roleChangeDTO);
-
-    /**
-     * A DTO that wraps an ownership change status
-     */
-    class RoleChangeDTO {
-
-        private final boolean wasOwner;
-        private final boolean isOwner;
-        private final boolean hasOwner;
-
-        public RoleChangeDTO(boolean wasOwner, boolean isOwner, boolean hasOwner) {
-            this.wasOwner = wasOwner;
-            this.isOwner = isOwner;
-            this.hasOwner = hasOwner;
-        }
-
-        public boolean wasOwner() {
-            return wasOwner;
-        }
-
-        public boolean isOwner() {
-            return isOwner;
-        }
-
-        public boolean hasOwner() {
-            return hasOwner;
-        }
-    }
-}
diff --git a/netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/RoleChangeStrategy.java b/netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/RoleChangeStrategy.java
deleted file mode 100644 (file)
index f4f3013..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.netconf.topology;
-
-import com.google.common.annotations.Beta;
-
-/**
- * A customizable strategy that gets executed when a BaseTopologyManager|BaseNodeManager is created.
- * If the election should be executed at another moment, you need to pass the NoopRoleChangeStrategy into the Manager
- * and the role candidate registration needs to happen in your implemented Node/Topology callback
- */
-@Beta
-public interface RoleChangeStrategy extends RoleChangeListener {
-
-    /**
-     * Your pre-election and election logic goes here, e.g you should register your candidate into the ElectionService
-     * @param electionCandidate NodeListener that should receive the subsequent onRoleChanged callback
-     *                          when a role change occurs.
-     */
-    void registerRoleCandidate(NodeListener electionCandidate);
-
-    /**
-     * Invoke whenever you want to stop candidate from partaking in election.
-     */
-    void unregisterRoleCandidate();
-
-    /**
-     *
-     * @return True/False based on if this candidate is already registered into ownership service
-     */
-    boolean isCandidateRegistered();
-
-}
diff --git a/netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/StateAggregator.java b/netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/StateAggregator.java
deleted file mode 100644 (file)
index d72d280..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.netconf.topology;
-
-import com.google.common.annotations.Beta;
-import com.google.common.util.concurrent.ListenableFuture;
-import java.util.List;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-
-/**
- * Aggregate different node states into a single state
- */
-@Beta
-public interface StateAggregator {
-
-    ListenableFuture<Node> combineCreateAttempts(final List<ListenableFuture<Node>> stateFutures);
-
-    ListenableFuture<Node> combineUpdateAttempts(final List<ListenableFuture<Node>> stateFutures);
-
-    ListenableFuture<Void> combineDeleteAttempts(final List<ListenableFuture<Void>> stateFutures);
-
-}
diff --git a/netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/TopologyManager.java b/netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/TopologyManager.java
deleted file mode 100644 (file)
index 3de1677..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.netconf.topology;
-
-import akka.actor.TypedActor.PostStop;
-import akka.actor.TypedActor.PreStart;
-import akka.actor.TypedActor.Receiver;
-import com.google.common.annotations.Beta;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
-import scala.concurrent.Future;
-
-/**
- * Top level topology manager that handles comunication between nodes, aggregates results, and handles writes into the datastore
- */
-@Beta
-public interface TopologyManager extends NodeListener, Receiver, RemoteNodeListener, PreStart, PostStop{
-
-    /**
-     * ask if this manager is master
-     * @return true/false based on ownership status
-     */
-    Future<Boolean> isMaster();
-
-    /**
-     *
-     * @param nodeId - id of the node that sessionUp/Down happened on
-     */
-    void notifyNodeStatusChange(NodeId nodeId);
-
-    boolean hasAllPeersUp();
-
-}
diff --git a/netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/TopologyManagerCallback.java b/netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/TopologyManagerCallback.java
deleted file mode 100644 (file)
index 8eee06a..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.netconf.topology;
-
-import akka.actor.ActorSystem;
-import akka.actor.TypedActor.Receiver;
-import com.google.common.annotations.Beta;
-
-/**
- * Customizable extension layer between the top level TopologyManager and NodeManager
- */
-@Beta
-public interface TopologyManagerCallback extends InitialStateProvider, NodeListener, Receiver, RoleChangeListener {
-
-    interface TopologyManagerCallbackFactory {
-        TopologyManagerCallback create(ActorSystem actorSystem, String topologyId);
-    }
-}
diff --git a/netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/example/ExampleNodeManagerCallback.java b/netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/example/ExampleNodeManagerCallback.java
deleted file mode 100644 (file)
index 823c44b..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.netconf.topology.example;
-
-import akka.actor.ActorRef;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import javax.annotation.Nonnull;
-import org.opendaylight.controller.md.sal.dom.api.DOMNotification;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
-import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences;
-import org.opendaylight.netconf.topology.NodeManagerCallback;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeFields;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-
-public class ExampleNodeManagerCallback implements NodeManagerCallback {
-
-    public ExampleNodeManagerCallback() {
-    }
-
-    @Nonnull
-    @Override public Node getInitialState(@Nonnull final NodeId nodeId,
-                                          @Nonnull final Node configNode) {
-        return new NodeBuilder().addAugmentation(NetconfNode.class,
-                new NetconfNodeBuilder().setConnectionStatus(NetconfNodeFields.ConnectionStatus.Connecting).build()).build();
-    }
-
-    @Nonnull @Override public Node getFailedState(@Nonnull final NodeId nodeId,
-                                                  @Nonnull final Node configNode) {
-        return new NodeBuilder().addAugmentation(NetconfNode.class,
-                new NetconfNodeBuilder().setConnectionStatus(NetconfNodeFields.ConnectionStatus.UnableToConnect).build()).build();
-    }
-
-    @Nonnull @Override public ListenableFuture<Node> onNodeCreated(@Nonnull final NodeId nodeId,
-                                                                   @Nonnull final Node configNode) {
-        return Futures.immediateFuture(new NodeBuilder().addAugmentation(NetconfNode.class,
-                new NetconfNodeBuilder().setConnectionStatus(NetconfNodeFields.ConnectionStatus.Connected).build()).build());
-    }
-
-    @Nonnull @Override public ListenableFuture<Node> onNodeUpdated(@Nonnull final NodeId nodeId,
-                                                                   @Nonnull final Node configNode) {
-        // update magic
-        return Futures.immediateFuture(new NodeBuilder().addAugmentation(NetconfNode.class,
-                new NetconfNodeBuilder().setConnectionStatus(NetconfNodeFields.ConnectionStatus.Connected).build()).build());
-    }
-
-    @Nonnull @Override public ListenableFuture<Void> onNodeDeleted(@Nonnull final NodeId nodeId) {
-        return Futures.immediateFuture(null);
-    }
-
-    @Nonnull
-    @Override
-    public ListenableFuture<Node> getCurrentStatusForNode(@Nonnull NodeId nodeId) {
-        return null;
-    }
-
-    @Override
-    public void onReceive(Object message, ActorRef sender) {
-
-    }
-
-    @Override
-    public void onRoleChanged(RoleChangeDTO roleChangeDTO) {
-
-    }
-
-    @Override
-    public void onDeviceConnected(SchemaContext remoteSchemaContext, NetconfSessionPreferences netconfSessionPreferences, DOMRpcService deviceRpc) {
-
-    }
-
-    @Override
-    public void onDeviceDisconnected() {
-
-    }
-
-    @Override
-    public void onDeviceFailed(Throwable throwable) {
-
-    }
-
-    @Override
-    public void onNotification(DOMNotification domNotification) {
-
-    }
-
-    @Override
-    public void close() {
-
-    }
-}
diff --git a/netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/example/ExampleSingleStateAggregator.java b/netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/example/ExampleSingleStateAggregator.java
deleted file mode 100644 (file)
index 6d27c26..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.netconf.topology.example;
-
-import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.ListenableFuture;
-import java.util.List;
-import org.opendaylight.netconf.topology.StateAggregator;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-
-/**
- * Aggregator implementation expecting just a single state
- */
-public final class ExampleSingleStateAggregator implements StateAggregator {
-
-    @Override public ListenableFuture<Node> combineCreateAttempts(final List<ListenableFuture<Node>> stateFutures) {
-        return getSingleFuture(stateFutures);
-    }
-
-    private <T> ListenableFuture<T> getSingleFuture(final List<ListenableFuture<T>> stateFutures) {
-        Preconditions.checkArgument(stateFutures.size() == 1, "Recieved multiple results, Single result is enforced here");
-        return stateFutures.get(0);
-    }
-
-    @Override public ListenableFuture<Node> combineUpdateAttempts(final List<ListenableFuture<Node>> stateFutures) {
-        return getSingleFuture(stateFutures);
-    }
-
-    @Override public ListenableFuture<Void> combineDeleteAttempts(final List<ListenableFuture<Void>> stateFutures) {
-        return getSingleFuture(stateFutures);
-    }
-}
diff --git a/netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/example/ExampleTopology.java b/netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/example/ExampleTopology.java
deleted file mode 100644 (file)
index c31e18e..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.netconf.topology.example;
-
-import akka.actor.ActorSystem;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
-import org.opendaylight.netconf.topology.NodeManagerCallback;
-import org.opendaylight.netconf.topology.NodeManagerCallback.NodeManagerCallbackFactory;
-import org.opendaylight.netconf.topology.TopologyManagerCallback;
-import org.opendaylight.netconf.topology.TopologyManagerCallback.TopologyManagerCallbackFactory;
-import org.opendaylight.netconf.topology.util.BaseTopologyManager;
-
-public class ExampleTopology {
-
-    private static final String TOPOLOGY_NETCONF = "topology-netconf";
-    private BaseTopologyManager netconfNodeBaseTopologyManager;
-    private final DataBroker dataBroker;
-
-    public ExampleTopology(final EntityOwnershipService entityOwnershipService, final DataBroker dataBroker) {
-        final ActorSystem actorSystem = ActorSystem.create("netconf-cluster");
-
-        this.dataBroker = dataBroker;
-
-        final NodeManagerCallbackFactory nodeManagerCallbackFactory = new NodeManagerCallbackFactory() {
-            @Override
-            public NodeManagerCallback create(String nodeId, String topologyId, ActorSystem actorSystem) {
-                return new ExampleNodeManagerCallback();
-            }
-        };
-
-        final TopologyManagerCallbackFactory topologyManagerCallbackFactory = new TopologyManagerCallbackFactory() {
-            @Override
-            public TopologyManagerCallback create(ActorSystem actorSystem, String topologyId) {
-                return new ExampleTopologyManagerCallback(actorSystem, dataBroker, topologyId, nodeManagerCallbackFactory);
-            }
-        };
-
-//        netconfNodeBaseTopologyManager = new BaseTopologyManager<>(dataBroker, TOPOLOGY_NETCONF,
-//                topologyManagerCallbackFactory,
-//                new SingleStateAggregator(),
-//                new SalNodeWriter(dataBroker, TOPOLOGY_NETCONF),
-//                new TopologyRoleChangeStrategy(dataBroker, entityOwnershipService, "netconf", TOPOLOGY_NETCONF));
-
-    }
-
-}
diff --git a/netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/example/ExampleTopologyManagerCallback.java b/netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/example/ExampleTopologyManagerCallback.java
deleted file mode 100644 (file)
index a2eed6a..0000000
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.netconf.topology.example;
-
-import akka.actor.ActorRef;
-import akka.actor.ActorSystem;
-import akka.actor.TypedActor;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import java.util.HashMap;
-import java.util.Map;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.netconf.topology.NodeManager;
-import org.opendaylight.netconf.topology.NodeManagerCallback.NodeManagerCallbackFactory;
-import org.opendaylight.netconf.topology.TopologyManagerCallback;
-import org.opendaylight.netconf.topology.util.BaseNodeManager.BaseNodeManagerBuilder;
-import org.opendaylight.netconf.topology.util.NodeWriter;
-import org.opendaylight.netconf.topology.util.NoopRoleChangeStrategy;
-import org.opendaylight.netconf.topology.util.SalNodeWriter;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ExampleTopologyManagerCallback implements TopologyManagerCallback {
-
-    private static final Logger LOG = LoggerFactory.getLogger(ExampleTopologyManagerCallback.class);
-
-    private final DataBroker dataBroker;
-    private final ActorSystem actorSystem;
-    private boolean isMaster;
-
-    private final String topologyId;
-    private final NodeWriter naSalNodeWriter;
-    private final Map<NodeId, NodeManager> nodes = new HashMap<>();
-    private final NodeManagerCallbackFactory nodeHandlerFactory;
-
-    public ExampleTopologyManagerCallback(final ActorSystem actorSystem,
-                                          final DataBroker dataBroker,
-                                          final String topologyId,
-                                          final NodeManagerCallbackFactory nodeHandlerFactory) {
-        this(actorSystem, dataBroker, topologyId, nodeHandlerFactory, new SalNodeWriter(dataBroker, topologyId));
-    }
-
-    public ExampleTopologyManagerCallback(final ActorSystem actorSystem,
-                                          final DataBroker dataBroker,
-                                          final String topologyId,
-                                          final NodeManagerCallbackFactory nodeHandlerFactory,
-                                          final NodeWriter naSalNodeWriter) {
-        this(actorSystem, dataBroker, topologyId, nodeHandlerFactory, naSalNodeWriter, false);
-
-    }
-
-    public ExampleTopologyManagerCallback(final ActorSystem actorSystem,
-                                          final DataBroker dataBroker,
-                                          final String topologyId,
-                                          final NodeManagerCallbackFactory nodeHandlerFactory,
-                                          final NodeWriter naSalNodeWriter,
-                                          boolean isMaster) {
-        this.dataBroker = dataBroker;
-        this.actorSystem = actorSystem;
-        this.topologyId = topologyId;
-        this.nodeHandlerFactory = nodeHandlerFactory;
-        this.naSalNodeWriter = naSalNodeWriter;
-
-        this.isMaster = isMaster;
-    }
-
-    @Override
-    public ListenableFuture<Node> onNodeCreated(NodeId nodeId, Node node) {
-        // Init node admin and a writer for it
-
-        // TODO let end user code notify the baseNodeManager about state changes and handle them here on topology level
-        final NodeManager naBaseNodeManager =
-                createNodeManager(nodeId);
-
-        nodes.put(nodeId, naBaseNodeManager);
-
-        // Set initial state ? in every peer or just master ? TODO
-        if (isMaster) {
-            naSalNodeWriter.init(nodeId, naBaseNodeManager.getInitialState(nodeId, node));
-        }
-
-        // trigger connect on this node
-        return naBaseNodeManager.onNodeCreated(nodeId, node);
-    }
-
-    @Override
-    public ListenableFuture<Node> onNodeUpdated(final NodeId nodeId, final Node node) {
-        // Set initial state
-        naSalNodeWriter.init(nodeId, nodes.get(nodeId).getInitialState(nodeId, node));
-
-        // Trigger onNodeUpdated only on this node
-        return nodes.get(nodeId).onNodeUpdated(nodeId, node);
-    }
-
-    @Override
-    public ListenableFuture<Void> onNodeDeleted(final NodeId nodeId) {
-        // Trigger delete only on this node
-        final ListenableFuture<Void> future = nodes.get(nodeId).onNodeDeleted(nodeId);
-        Futures.addCallback(future, new FutureCallback<Void>() {
-            @Override
-            public void onSuccess(Void result) {
-                // remove proxy from node list and stop the actor
-                final NodeManager remove = nodes.remove(nodeId);
-                TypedActor.get(actorSystem).stop(remove);
-            }
-
-            @Override
-            public void onFailure(Throwable t) {
-                // NOOP will be handled on higher level
-            }
-        });
-        return future;
-    }
-
-    @Nonnull
-    @Override
-    public ListenableFuture<Node> getCurrentStatusForNode(@Nonnull NodeId nodeId) {
-        return nodes.get(nodeId).getCurrentStatusForNode(nodeId);
-    }
-
-    @Override
-    public void onRoleChanged(RoleChangeDTO roleChangeDTO) {
-        isMaster = roleChangeDTO.isOwner();
-        // our post-election logic
-    }
-
-    private NodeManager createNodeManager(NodeId nodeId) {
-        return new BaseNodeManagerBuilder().setNodeId(nodeId.getValue())
-                .setActorContext(TypedActor.context())
-                .setDelegateFactory(nodeHandlerFactory)
-                .setRoleChangeStrategy(new NoopRoleChangeStrategy())
-                .setTopologyId(topologyId)
-                .build();
-    }
-
-    @Override
-    public void onReceive(Object o, ActorRef actorRef) {
-
-    }
-
-    @Nonnull
-    @Override
-    public Node getInitialState(@Nonnull NodeId nodeId, @Nonnull Node configNode) {
-        return nodes.get(nodeId).getInitialState(nodeId, configNode);
-    }
-
-    @Nonnull
-    @Override
-    public Node getFailedState(@Nonnull NodeId nodeId, @Nullable Node configNode) {
-        return nodes.get(nodeId).getFailedState(nodeId, configNode);
-    }
-}
diff --git a/netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/example/LoggingSalNodeWriter.java b/netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/example/LoggingSalNodeWriter.java
deleted file mode 100644 (file)
index e4ead18..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.netconf.topology.example;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import javax.annotation.Nonnull;
-import org.opendaylight.netconf.topology.util.NodeWriter;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class LoggingSalNodeWriter implements NodeWriter{
-
-    private static final Logger LOG = LoggerFactory.getLogger(LoggingSalNodeWriter.class);
-
-    private final ArrayList<NodeWriter> delegates;
-
-    public LoggingSalNodeWriter(final NodeWriter... delegates) {
-        this.delegates = new ArrayList<>(Arrays.asList(delegates));
-    }
-
-    @Override
-    public void init(@Nonnull NodeId id, @Nonnull Node operationalDataNode) {
-        LOG.warn("Init recieved");
-        LOG.warn("NodeId: {}", id.getValue());
-        LOG.warn("Node: {}", operationalDataNode);
-        for (final NodeWriter delegate : delegates) {
-            delegate.init(id, operationalDataNode);
-        }
-    }
-
-    @Override
-    public void update(@Nonnull NodeId id, @Nonnull Node operationalDataNode) {
-        LOG.warn("Update recieved");
-        LOG.warn("NodeId: {}", id.getValue());
-        LOG.warn("Node: {}", operationalDataNode);
-        for (final NodeWriter delegate : delegates) {
-            delegate.update(id, operationalDataNode);
-        }
-    }
-
-    @Override
-    public void delete(@Nonnull NodeId id) {
-        LOG.warn("Delete recieved");
-        LOG.warn("NodeId: {}", id.getValue());
-        for (final NodeWriter delegate : delegates) {
-            delegate.delete(id);
-        }
-    }
-}
diff --git a/netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/util/BaseNodeManager.java b/netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/util/BaseNodeManager.java
deleted file mode 100644 (file)
index f48f0c4..0000000
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.netconf.topology.util;
-
-import akka.actor.ActorContext;
-import akka.actor.ActorRef;
-import akka.actor.ActorSystem;
-import akka.actor.TypedActor;
-import akka.actor.TypedProps;
-import akka.japi.Creator;
-import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.ListenableFuture;
-import javax.annotation.Nonnull;
-import org.opendaylight.controller.md.sal.dom.api.DOMNotification;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
-import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences;
-import org.opendaylight.netconf.topology.NodeManager;
-import org.opendaylight.netconf.topology.NodeManagerCallback;
-import org.opendaylight.netconf.topology.NodeManagerCallback.NodeManagerCallbackFactory;
-import org.opendaylight.netconf.topology.RoleChangeStrategy;
-import org.opendaylight.netconf.topology.util.messages.NormalizedNodeMessage;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import scala.concurrent.Future;
-
-public final class BaseNodeManager implements NodeManager {
-
-    private static final Logger LOG = LoggerFactory.getLogger(BaseNodeManager.class);
-
-    private final String nodeId;
-    private final NodeManagerCallback delegate;
-
-    private BaseNodeManager(final String nodeId,
-                            final String topologyId,
-                            final ActorSystem actorSystem,
-                            final NodeManagerCallbackFactory delegateFactory,
-                            final RoleChangeStrategy roleChangeStrategy) {
-        LOG.debug("Creating BaseNodeManager, id: {}, {}", topologyId, nodeId );
-        this.nodeId = nodeId;
-        this.delegate = delegateFactory.create(nodeId, topologyId, actorSystem);
-        // if we want to override the place election happens,
-        // we need to override this with noop election strategy and implement election in callback
-        // cannot leak "this" here! have to use TypedActor.self()
-        roleChangeStrategy.registerRoleCandidate((NodeManager) TypedActor.self());
-    }
-
-    @Nonnull @Override public Node getInitialState(@Nonnull final NodeId nodeId, @Nonnull final Node configNode) {
-        LOG.trace("Retrieving Node {} initial state", nodeId);
-        return delegate.getInitialState(nodeId, configNode);
-    }
-
-    @Nonnull @Override public Node getFailedState(@Nonnull final NodeId nodeId, @Nonnull final Node configNode) {
-        LOG.trace("Retrieving Node {} failed state", nodeId);
-        return delegate.getFailedState(nodeId, configNode);
-    }
-
-    @Nonnull @Override public ListenableFuture<Node> onNodeCreated(@Nonnull final NodeId nodeId, @Nonnull final Node configNode) {
-        LOG.debug("Creating Node {}, with configuration: {}", nodeId.getValue(), configNode);
-        return delegate.onNodeCreated(nodeId, configNode);
-    }
-
-    @Nonnull @Override public ListenableFuture<Node> onNodeUpdated(@Nonnull final NodeId nodeId, @Nonnull final Node configNode) {
-        LOG.debug("Updating Node {}, with configuration: {}", nodeId.getValue(), configNode);
-        return delegate.onNodeUpdated(nodeId, configNode);
-    }
-
-    @Nonnull @Override public ListenableFuture<Void> onNodeDeleted(@Nonnull final NodeId nodeId) {
-        LOG.debug("Deleting Node {}", nodeId.getValue());
-        return delegate.onNodeDeleted(nodeId);
-    }
-
-    @Nonnull
-    @Override
-    public ListenableFuture<Node> getCurrentStatusForNode(@Nonnull NodeId nodeId) {
-        LOG.debug("Getting current status for node: {}", nodeId.getValue());
-        return delegate.getCurrentStatusForNode(nodeId);
-    }
-
-    @Override
-    public void onRoleChanged(RoleChangeDTO roleChangeDTO) {
-        LOG.debug("Node {} role has changed from: {} to {}", nodeId,
-                (roleChangeDTO.wasOwner() ? "master" : "slave"),
-                (roleChangeDTO.isOwner() ? "master" : "slave"));
-
-        delegate.onRoleChanged(roleChangeDTO);
-    }
-
-    @Override
-    public void onReceive(Object o, ActorRef actorRef) {
-        delegate.onReceive(o, actorRef);
-    }
-
-    @Override
-    public Future<NormalizedNodeMessage> onRemoteNodeCreated(final NormalizedNodeMessage message) {
-        return null;
-    }
-
-    @Override
-    public Future<NormalizedNodeMessage> onRemoteNodeUpdated(final NormalizedNodeMessage message) {
-        return null;
-    }
-
-    @Override
-    public Future<Void> onRemoteNodeDeleted(final NodeId nodeId) {
-        return null;
-    }
-
-    @Override
-    public Future<NormalizedNodeMessage> remoteGetCurrentStatusForNode(final NodeId nodeId) {
-        return null;
-    }
-
-    @Override
-    public void onDeviceConnected(SchemaContext remoteSchemaContext, NetconfSessionPreferences netconfSessionPreferences, DOMRpcService deviceRpc) {
-        delegate.onDeviceConnected(remoteSchemaContext, netconfSessionPreferences, deviceRpc);
-    }
-
-    @Override
-    public void onDeviceDisconnected() {
-        delegate.onDeviceDisconnected();
-    }
-
-    @Override
-    public void onDeviceFailed(Throwable throwable) {
-        delegate.onDeviceFailed(throwable);
-    }
-
-    @Override
-    public void onNotification(DOMNotification domNotification) {
-        delegate.onNotification(domNotification);
-    }
-
-    @Override
-    public void close() {
-        // NOOP
-    }
-
-    /**
-     * Builder of BaseNodeManager instances that are proxied as TypedActors
-     */
-    public static class BaseNodeManagerBuilder {
-        private String nodeId;
-        private String topologyId;
-        private NodeManagerCallbackFactory delegateFactory;
-        private RoleChangeStrategy roleChangeStrategy;
-        private ActorContext actorContext;
-
-
-        public BaseNodeManagerBuilder setNodeId(final String nodeId) {
-            this.nodeId = nodeId;
-            return this;
-        }
-
-        public BaseNodeManagerBuilder setTopologyId(final String topologyId) {
-            this.topologyId = topologyId;
-            return this;
-        }
-
-        public BaseNodeManagerBuilder setDelegateFactory(final NodeManagerCallbackFactory delegateFactory) {
-            this.delegateFactory = delegateFactory;
-            return this;
-        }
-
-        public BaseNodeManagerBuilder setRoleChangeStrategy(final RoleChangeStrategy roleChangeStrategy) {
-            this.roleChangeStrategy = roleChangeStrategy;
-            return this;
-        }
-
-        public BaseNodeManagerBuilder setActorContext(final ActorContext actorContext) {
-            this.actorContext = actorContext;
-            return this;
-        }
-
-        public NodeManager build() {
-            Preconditions.checkNotNull(nodeId);
-            Preconditions.checkNotNull(topologyId);
-            Preconditions.checkNotNull(delegateFactory);
-            Preconditions.checkNotNull(roleChangeStrategy);
-            Preconditions.checkNotNull(actorContext);
-            LOG.debug("Creating typed actor with id: {}", nodeId);
-
-            return TypedActor.get(actorContext).typedActorOf(new TypedProps<>(NodeManager.class, new Creator<BaseNodeManager>() {
-                @Override
-                public BaseNodeManager create() throws Exception {
-                    return new BaseNodeManager(nodeId, topologyId, actorContext.system(), delegateFactory, roleChangeStrategy);
-                }
-            }), nodeId);
-        }
-    }
-}
diff --git a/netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/util/BaseTopologyManager.java b/netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/util/BaseTopologyManager.java
deleted file mode 100644 (file)
index 133aa46..0000000
+++ /dev/null
@@ -1,612 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.netconf.topology.util;
-
-import akka.actor.ActorContext;
-import akka.actor.ActorIdentity;
-import akka.actor.ActorRef;
-import akka.actor.ActorSystem;
-import akka.actor.Address;
-import akka.actor.Identify;
-import akka.actor.TypedActor;
-import akka.actor.TypedActorExtension;
-import akka.actor.TypedProps;
-import akka.cluster.Cluster;
-import akka.cluster.ClusterEvent;
-import akka.cluster.ClusterEvent.MemberEvent;
-import akka.cluster.ClusterEvent.MemberExited;
-import akka.cluster.ClusterEvent.MemberRemoved;
-import akka.cluster.ClusterEvent.MemberUp;
-import akka.cluster.ClusterEvent.ReachableMember;
-import akka.cluster.ClusterEvent.UnreachableMember;
-import akka.cluster.Member;
-import akka.dispatch.OnComplete;
-import com.google.common.base.Optional;
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.SettableFuture;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Random;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-import javax.annotation.Nonnull;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
-import org.opendaylight.netconf.topology.RoleChangeStrategy;
-import org.opendaylight.netconf.topology.StateAggregator;
-import org.opendaylight.netconf.topology.TopologyManager;
-import org.opendaylight.netconf.topology.TopologyManagerCallback;
-import org.opendaylight.netconf.topology.TopologyManagerCallback.TopologyManagerCallbackFactory;
-import org.opendaylight.netconf.topology.util.messages.CustomIdentifyMessage;
-import org.opendaylight.netconf.topology.util.messages.CustomIdentifyMessageReply;
-import org.opendaylight.netconf.topology.util.messages.NormalizedNodeMessage;
-import org.opendaylight.netconf.util.NetconfTopologyPathCreator;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.opendaylight.yangtools.binding.data.codec.impl.BindingNormalizedNodeCodecRegistry;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import scala.concurrent.Future;
-import scala.concurrent.duration.FiniteDuration;
-import scala.concurrent.impl.Promise.DefaultPromise;
-
-public final class BaseTopologyManager
-        implements TopologyManager {
-
-    private static final Logger LOG = LoggerFactory.getLogger(BaseTopologyManager.class);
-
-    private final KeyedInstanceIdentifier<Topology, TopologyKey> topologyListPath;
-
-    private final ActorSystem system;
-    private final TypedActorExtension typedExtension;
-    private final Cluster clusterExtension;
-
-    private final BindingNormalizedNodeCodecRegistry codecRegistry;
-
-    private static final String PATH = "/user/";
-
-    private final DataBroker dataBroker;
-    private final RoleChangeStrategy roleChangeStrategy;
-    private final StateAggregator aggregator;
-
-    private final NodeWriter naSalNodeWriter;
-    private final String topologyId;
-    private final TopologyManagerCallback delegateTopologyHandler;
-    private final Set<NodeId> created = new HashSet<>();
-
-    private final Map<Address, TopologyManager> peers = new HashMap<>();
-    private final int id = new Random().nextInt();
-
-    private boolean isMaster;
-
-    public BaseTopologyManager(final ActorSystem system,
-                               final BindingNormalizedNodeCodecRegistry codecRegistry,
-                               final DataBroker dataBroker,
-                               final String topologyId,
-                               final TopologyManagerCallbackFactory topologyManagerCallbackFactory,
-                               final StateAggregator aggregator,
-                               final NodeWriter naSalNodeWriter,
-                               final RoleChangeStrategy roleChangeStrategy) {
-        this(system, codecRegistry, dataBroker, topologyId, topologyManagerCallbackFactory, aggregator, naSalNodeWriter, roleChangeStrategy, false);
-    }
-
-    public BaseTopologyManager(final ActorSystem system,
-                               final BindingNormalizedNodeCodecRegistry codecRegistry,
-                               final DataBroker dataBroker,
-                               final String topologyId,
-                               final TopologyManagerCallbackFactory topologyManagerCallbackFactory,
-                               final StateAggregator aggregator,
-                               final NodeWriter naSalNodeWriter,
-                               final RoleChangeStrategy roleChangeStrategy,
-                               final boolean isMaster) {
-
-        this.system = system;
-        this.typedExtension = TypedActor.get(system);
-        this.clusterExtension = Cluster.get(system);
-        this.dataBroker = dataBroker;
-        this.topologyId = topologyId;
-        this.delegateTopologyHandler = topologyManagerCallbackFactory.create(system, topologyId);
-        this.aggregator = aggregator;
-        this.naSalNodeWriter = naSalNodeWriter;
-        this.roleChangeStrategy = roleChangeStrategy;
-        this.codecRegistry = codecRegistry;
-
-        // election has not yet happened
-        this.isMaster = isMaster;
-
-        this.topologyListPath = TopologyUtil.createTopologyListPath(topologyId);
-
-        LOG.debug("Base manager started ", +id);
-    }
-
-    @Override
-    public void preStart() {
-        LOG.debug("preStart called");
-        // TODO change to enum, master/slave active/standby
-        roleChangeStrategy.registerRoleCandidate(TypedActor.<BaseTopologyManager>self());
-        LOG.debug("candidate registered");
-        clusterExtension.subscribe(TypedActor.context().self(), ClusterEvent.initialStateAsEvents(), MemberEvent.class, UnreachableMember.class);
-    }
-
-    @Override
-    public void postStop() {
-        LOG.debug("postStop called");
-        clusterExtension.leave(clusterExtension.selfAddress());
-        clusterExtension.unsubscribe(TypedActor.context().self());
-    }
-
-    @Override
-    public ListenableFuture<Node> onNodeCreated(final NodeId nodeId, final Node node) {
-        LOG.debug("TopologyManager({}) onNodeCreated received, nodeid: {} , isMaster: {}", id, nodeId.getValue(), isMaster);
-
-        if (created.contains(nodeId)) {
-            LOG.warn("Node{} already exists, triggering update..", nodeId);
-            return onNodeUpdated(nodeId, node);
-        }
-        created.add(nodeId);
-        final ArrayList<ListenableFuture<Node>> futures = new ArrayList<>();
-
-        if (isMaster) {
-
-            futures.add(delegateTopologyHandler.onNodeCreated(nodeId, node));
-            // only master should call connect on peers and aggregate futures
-            for (TopologyManager topologyManager : peers.values()) {
-                // convert binding into NormalizedNode for transfer
-                final Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> normalizedNodeEntry = codecRegistry.toNormalizedNode(TopologyUtil.createTopologyNodePath(topologyId), node);
-
-                LOG.debug("YangInstanceIdentifier {}", normalizedNodeEntry.getKey());
-                LOG.debug("Value {}", normalizedNodeEntry.getValue());
-
-                // add a future into our futures that gets its completion status from the converted scala future
-                final SettableFuture<Node> settableFuture = SettableFuture.create();
-                futures.add(settableFuture);
-                final Future<NormalizedNodeMessage> scalaFuture = topologyManager.onRemoteNodeCreated(new NormalizedNodeMessage(normalizedNodeEntry.getKey(), normalizedNodeEntry.getValue()));
-                scalaFuture.onComplete(new OnComplete<NormalizedNodeMessage>() {
-                    @Override
-                    public void onComplete(Throwable failure, NormalizedNodeMessage success) throws Throwable {
-                        if (failure != null) {
-                            settableFuture.setException(failure);
-                            return;
-                        }
-                        final Entry<InstanceIdentifier<?>, DataObject> fromNormalizedNode =
-                                codecRegistry.fromNormalizedNode(success.getIdentifier(), success.getNode());
-                        final Node value = (Node) fromNormalizedNode.getValue();
-
-                        settableFuture.set(value);
-                    }
-                }, TypedActor.context().dispatcher());
-            }
-
-            final ListenableFuture<Node> aggregatedFuture = aggregator.combineCreateAttempts(futures);
-            Futures.addCallback(aggregatedFuture, new FutureCallback<Node>() {
-                @Override
-                public void onSuccess(final Node result) {
-                    LOG.debug("Futures aggregated succesfully");
-                    naSalNodeWriter.init(nodeId, result);
-                }
-
-                @Override
-                public void onFailure(final Throwable t) {
-                    // If the combined connection attempt failed, set the node to connection failed
-                    LOG.debug("Futures aggregation failed");
-                    naSalNodeWriter.update(nodeId, delegateTopologyHandler.getFailedState(nodeId, node));
-                }
-            }, TypedActor.context().dispatcher());
-
-            //combine peer futures
-            return aggregatedFuture;
-        }
-
-        // trigger create on this slave
-        return delegateTopologyHandler.onNodeCreated(nodeId, node);
-    }
-
-    @Override
-    public ListenableFuture<Node> onNodeUpdated(final NodeId nodeId, final Node node) {
-        LOG.debug("TopologyManager({}) onNodeUpdated received, nodeid: {}", id, nodeId.getValue());
-
-        // Master needs to trigger onNodeUpdated on peers and combine results
-        if (isMaster) {
-            // first cleanup old node
-            final ListenableFuture<Void> deleteFuture = onNodeDeleted(nodeId);
-            final SettableFuture<Node> createFuture = SettableFuture.create();
-            final TopologyManager selfProxy = TypedActor.self();
-            final ActorContext context = TypedActor.context();
-            Futures.addCallback(deleteFuture, new FutureCallback<Void>() {
-                @Override
-                public void onSuccess(Void result) {
-                    LOG.warn("Delete part of update succesfull, triggering create");
-                    // trigger create on all nodes
-                    Futures.addCallback(selfProxy.onNodeCreated(nodeId, node), new FutureCallback<Node>() {
-                        @Override
-                        public void onSuccess(Node result) {
-                            createFuture.set(result);
-                        }
-
-                        @Override
-                        public void onFailure(Throwable t) {
-                            createFuture.setException(t);
-                        }
-                    }, context.dispatcher());
-                }
-
-                @Override
-                public void onFailure(Throwable t) {
-                    LOG.warn("Delete part of update failed, {}", t);
-                }
-            }, context.dispatcher());
-            return createFuture;
-        }
-
-        // Trigger update on this slave
-        return delegateTopologyHandler.onNodeUpdated(nodeId, node);
-    }
-
-    @Override
-    public ListenableFuture<Void> onNodeDeleted(final NodeId nodeId) {
-        final ArrayList<ListenableFuture<Void>> futures = new ArrayList<>();
-        created.remove(nodeId);
-
-        // Master needs to trigger delete on peers and combine results
-        if (isMaster) {
-            futures.add(delegateTopologyHandler.onNodeDeleted(nodeId));
-            for (TopologyManager topologyManager : peers.values()) {
-                // add a future into our futures that gets its completion status from the converted scala future
-                final SettableFuture<Void> settableFuture = SettableFuture.create();
-                futures.add(settableFuture);
-                final Future<Void> scalaFuture = topologyManager.onRemoteNodeDeleted(nodeId);
-                scalaFuture.onComplete(new OnComplete<Void>() {
-                    @Override
-                    public void onComplete(Throwable failure, Void success) throws Throwable {
-                        if (failure != null) {
-                            settableFuture.setException(failure);
-                            return;
-                        }
-
-                        settableFuture.set(success);
-                    }
-                }, TypedActor.context().dispatcher());
-            }
-
-            final ListenableFuture<Void> aggregatedFuture = aggregator.combineDeleteAttempts(futures);
-            Futures.addCallback(aggregatedFuture, new FutureCallback<Void>() {
-                @Override
-                public void onSuccess(final Void result) {
-                    naSalNodeWriter.delete(nodeId);
-                }
-
-                @Override
-                public void onFailure(final Throwable t) {
-
-                }
-            });
-
-            return aggregatedFuture;
-        }
-
-        // Trigger delete
-        return delegateTopologyHandler.onNodeDeleted(nodeId);
-    }
-
-    @Nonnull
-    @Override
-    public ListenableFuture<Node> getCurrentStatusForNode(@Nonnull final NodeId nodeId) {
-        return delegateTopologyHandler.getCurrentStatusForNode(nodeId);
-    }
-
-    @Override
-    public void onRoleChanged(final RoleChangeDTO roleChangeDTO) {
-        isMaster = roleChangeDTO.isOwner();
-        delegateTopologyHandler.onRoleChanged(roleChangeDTO);
-        if (isMaster) {
-            LOG.debug("Node {} is master now", clusterExtension.selfAddress());
-            clusterExtension.join(clusterExtension.selfAddress());
-        }
-    }
-
-    @Override
-    public Future<Boolean> isMaster() {
-        return new DefaultPromise<Boolean>().success(isMaster).future();
-    }
-
-    @Override
-    public void notifyNodeStatusChange(final NodeId nodeId) {
-        LOG.debug("Connection status has changed on node {}", nodeId.getValue());
-        if (isMaster) {
-            // grab status from all peers and aggregate
-            final ArrayList<ListenableFuture<Node>> futures = new ArrayList<>();
-            futures.add(delegateTopologyHandler.getCurrentStatusForNode(nodeId));
-            // only master should call connect on peers and aggregate futures
-            for (TopologyManager topologyManager : peers.values()) {
-                // add a future into our futures that gets its completion status from the converted scala future
-                final SettableFuture<Node> settableFuture = SettableFuture.create();
-                futures.add(settableFuture);
-                final Future<NormalizedNodeMessage> scalaFuture = topologyManager.remoteGetCurrentStatusForNode(nodeId);
-                scalaFuture.onComplete(new OnComplete<NormalizedNodeMessage>() {
-                    @Override
-                    public void onComplete(Throwable failure, NormalizedNodeMessage success) throws Throwable {
-                        if (failure != null) {
-                            settableFuture.setException(failure);
-                            return;
-                        }
-                        final Entry<InstanceIdentifier<?>, DataObject> fromNormalizedNode =
-                                codecRegistry.fromNormalizedNode(success.getIdentifier(), success.getNode());
-                        final Node value = (Node) fromNormalizedNode.getValue();
-
-                        settableFuture.set(value);
-                    }
-                }, TypedActor.context().dispatcher());
-            }
-
-            final ListenableFuture<Node> aggregatedFuture = aggregator.combineUpdateAttempts(futures);
-            Futures.addCallback(aggregatedFuture, new FutureCallback<Node>() {
-                @Override
-                public void onSuccess(final Node result) {
-                    LOG.debug("Futures aggregated succesfully");
-                    naSalNodeWriter.update(nodeId, result);
-                }
-
-                @Override
-                public void onFailure(final Throwable t) {
-                    // If the combined connection attempt failed, set the node to connection failed
-                    LOG.debug("Futures aggregation failed");
-                    naSalNodeWriter.update(nodeId, delegateTopologyHandler.getFailedState(nodeId, null));
-                }
-            });
-            return;
-        }
-        LOG.debug("Not master, forwarding..");
-        for (final TopologyManager manager : peers.values()) {
-            // asynchronously find out which peer is master
-            final Future<Boolean> future = manager.isMaster();
-            future.onComplete(new OnComplete<Boolean>() {
-                @Override
-                public void onComplete(Throwable failure, Boolean success) throws Throwable {
-                    if (failure == null && success) {
-                        LOG.debug("Found master peer");
-                        // forward to master
-                        manager.notifyNodeStatusChange(nodeId);
-                        return;
-                    }
-                    if (failure != null) {
-                        LOG.debug("Retrieving master peer failed, {}", failure);
-                    }
-                }
-            }, TypedActor.context().dispatcher());
-        }
-    }
-
-    @Override
-    public boolean hasAllPeersUp() {
-        LOG.debug("Peers needed: {} Peers up: {}", 2, peers.size());
-        LOG.warn(clusterExtension.state().toString());
-        LOG.warn(peers.toString());
-        return peers.size() == 2;
-    }
-
-    @Override
-    public Future<NormalizedNodeMessage> onRemoteNodeCreated(final NormalizedNodeMessage message) {
-        final Entry<InstanceIdentifier<?>, DataObject> fromNormalizedNode =
-                codecRegistry.fromNormalizedNode(message.getIdentifier(), message.getNode());
-        final InstanceIdentifier<Node> iid = (InstanceIdentifier<Node>) fromNormalizedNode.getKey();
-        final Node value = (Node) fromNormalizedNode.getValue();
-
-        LOG.debug("TopologyManager({}) onRemoteNodeCreated received, nodeid: {}", value.getNodeId(), value);
-        final ListenableFuture<Node> nodeListenableFuture = onNodeCreated(value.getNodeId(), value);
-        final DefaultPromise<NormalizedNodeMessage> promise = new DefaultPromise<>();
-        Futures.addCallback(nodeListenableFuture, new FutureCallback<Node>() {
-            @Override
-            public void onSuccess(Node result) {
-                final Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> entry = codecRegistry.toNormalizedNode(iid, result);
-                promise.success(new NormalizedNodeMessage(entry.getKey(), entry.getValue()));
-            }
-
-            @Override
-            public void onFailure(Throwable t) {
-                promise.failure(t);
-            }
-        });
-
-        return promise.future();
-    }
-
-    @Override
-    public Future<NormalizedNodeMessage> onRemoteNodeUpdated(final NormalizedNodeMessage message) {
-        final Entry<InstanceIdentifier<?>, DataObject> fromNormalizedNode =
-                codecRegistry.fromNormalizedNode(message.getIdentifier(), message.getNode());
-        final InstanceIdentifier<Node> iid = (InstanceIdentifier<Node>) fromNormalizedNode.getKey();
-        final Node value = (Node) fromNormalizedNode.getValue();
-
-        LOG.debug("TopologyManager({}) onRemoteNodeUpdated received, nodeid: {}", id, value.getNodeId());
-
-        final ListenableFuture<Node> nodeListenableFuture = onNodeUpdated(value.getNodeId(), value);
-        final DefaultPromise<NormalizedNodeMessage> promise = new DefaultPromise<>();
-        Futures.addCallback(nodeListenableFuture, new FutureCallback<Node>() {
-            @Override
-            public void onSuccess(Node result) {
-                final Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> entry = codecRegistry.toNormalizedNode(iid, result);
-                promise.success(new NormalizedNodeMessage(entry.getKey(), entry.getValue()));
-            }
-
-            @Override
-            public void onFailure(Throwable t) {
-                promise.failure(t);
-            }
-        });
-        return promise.future();
-    }
-
-    @Override
-    public Future<Void> onRemoteNodeDeleted(final NodeId nodeId) {
-        LOG.debug("TopologyManager({}) onRemoteNodeDeleted received, nodeid: {}", id, nodeId.getValue());
-
-        final ListenableFuture<Void> listenableFuture = onNodeDeleted(nodeId);
-        final DefaultPromise<Void> promise = new DefaultPromise<>();
-        Futures.addCallback(listenableFuture, new FutureCallback<Void>() {
-            @Override
-            public void onSuccess(Void result) {
-                promise.success(null);
-            }
-
-            @Override
-            public void onFailure(Throwable t) {
-                promise.failure(t);
-            }
-        });
-
-        return promise.future();
-    }
-
-    public Future<NormalizedNodeMessage> remoteGetCurrentStatusForNode(final NodeId nodeId) {
-        LOG.debug("TopologyManager({}) remoteGetCurrentStatusForNode received, nodeid: {}", id, nodeId.getValue());
-
-        final ListenableFuture<Node> listenableFuture = getCurrentStatusForNode(nodeId);
-        final DefaultPromise<NormalizedNodeMessage> promise = new DefaultPromise<>();
-        Futures.addCallback(listenableFuture, new FutureCallback<Node>() {
-            @Override
-            public void onSuccess(Node result) {
-                final Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> entry = codecRegistry.toNormalizedNode(TopologyUtil.createTopologyNodePath(topologyId), result);
-                promise.success(new NormalizedNodeMessage(entry.getKey(), entry.getValue()));
-            }
-
-            @Override
-            public void onFailure(Throwable t) {
-                promise.failure(t);
-            }
-        });
-        return promise.future();
-    }
-
-    @Override
-    public void onReceive(final Object message, final ActorRef actorRef) {
-        LOG.debug("message received {}", message);
-        if (message instanceof MemberUp) {
-            final Member member = ((MemberUp) message).member();
-            LOG.info("Member is Up: {}", member);
-            if (member.address().equals(clusterExtension.selfAddress())) {
-                return;
-            }
-
-            final NetconfTopologyPathCreator pathCreator = new NetconfTopologyPathCreator(member.address().toString(), topologyId);
-            final String path = pathCreator.build();
-            LOG.debug("Actor at :{} is resolving topology actor for path {}", clusterExtension.selfAddress(), path);
-
-            // first send basic identify message in case our messages have not been loaded through osgi yet to prevent crashing akka.
-            clusterExtension.system().actorSelection(path).tell(new Identify(member.address()), TypedActor.context().self());
-        } else if (message instanceof MemberExited) {
-            // remove peer
-            final Member member = ((MemberExited) message).member();
-            LOG.info("Member exited cluster: {}", member);
-            peers.remove(member.address());
-        } else if (message instanceof MemberRemoved) {
-            // remove peer
-            final Member member = ((MemberRemoved) message).member();
-            LOG.info("Member was removed from cluster: {}", member);
-            peers.remove(member.address());
-        } else if (message instanceof UnreachableMember) {
-            // remove peer
-            final Member member = ((UnreachableMember) message).member();
-            LOG.info("Member is unreachable: {}", member);
-            peers.remove(member.address());
-        } else if (message instanceof ReachableMember) {
-            // resync peer
-            final Member member = ((ReachableMember) message).member();
-            LOG.info("Member is reachable again: {}", member);
-
-            if (member.address().equals(clusterExtension.selfAddress())) {
-                return;
-            }
-            final NetconfTopologyPathCreator pathCreator = new NetconfTopologyPathCreator(member.address().toString(), topologyId);
-            final String path = pathCreator.build();
-            LOG.debug("Actor at :{} is resolving topology actor for path {}", clusterExtension.selfAddress(), path);
-
-            clusterExtension.system().actorSelection(path).tell(new Identify(member.address()), TypedActor.context().self());
-        } else if (message instanceof ActorIdentity) {
-            LOG.debug("Received ActorIdentity message", message);
-            final NetconfTopologyPathCreator pathCreator = new NetconfTopologyPathCreator(((ActorIdentity) message).correlationId().toString(), topologyId);
-            final String path = pathCreator.build();
-            if (((ActorIdentity) message).getRef() == null) {
-                LOG.debug("ActorIdentity has null actor ref, retrying..", message);
-                final ActorRef self = TypedActor.context().self();
-                final ActorContext context = TypedActor.context();
-                system.scheduler().scheduleOnce(new FiniteDuration(5, TimeUnit.SECONDS), new Runnable() {
-                    @Override
-                    public void run() {
-                        LOG.debug("Retrying identify message from master to node {} , full path {}", ((ActorIdentity) message).correlationId(), path);
-                        context.system().actorSelection(path).tell(new Identify(((ActorIdentity) message).correlationId()), self);
-
-                    }
-                }, system.dispatcher());
-                return;
-            }
-            LOG.debug("Actor at :{} is resolving topology actor for path {}, with a custom message", clusterExtension.selfAddress(), path);
-
-            clusterExtension.system().actorSelection(path).tell(new CustomIdentifyMessage(clusterExtension.selfAddress()), TypedActor.context().self());
-        } else if (message instanceof CustomIdentifyMessageReply) {
-
-            LOG.warn("Received a custom identify reply message from: {}", ((CustomIdentifyMessageReply) message).getAddress());
-            if (!peers.containsKey(((CustomIdentifyMessage) message).getAddress())) {
-                final TopologyManager peer = typedExtension.typedActorOf(new TypedProps<>(TopologyManager.class, BaseTopologyManager.class), actorRef);
-                peers.put(((CustomIdentifyMessageReply) message).getAddress(), peer);
-                if (isMaster) {
-                    resyncPeer(peer);
-                }
-            }
-        } else if (message instanceof CustomIdentifyMessage) {
-            LOG.warn("Received a custom identify message from: {}", ((CustomIdentifyMessage) message).getAddress());
-            if (!peers.containsKey(((CustomIdentifyMessage) message).getAddress())) {
-                final TopologyManager peer = typedExtension.typedActorOf(new TypedProps<>(TopologyManager.class, BaseTopologyManager.class), actorRef);
-                peers.put(((CustomIdentifyMessage) message).getAddress(), peer);
-                if (isMaster) {
-                    resyncPeer(peer);
-                }
-            }
-            actorRef.tell(new CustomIdentifyMessageReply(clusterExtension.selfAddress()), TypedActor.context().self());
-        }
-    }
-
-    private void resyncPeer(final TopologyManager peer) {
-        final ReadOnlyTransaction rTx = dataBroker.newReadOnlyTransaction();
-        final CheckedFuture<Optional<Topology>, ReadFailedException> read = rTx.read(LogicalDatastoreType.CONFIGURATION, topologyListPath);
-
-        Futures.addCallback(read, new FutureCallback<Optional<Topology>>() {
-            @Override
-            public void onSuccess(Optional<Topology> result) {
-                if (result.isPresent() && result.get().getNode() != null) {
-                    for (final Node node : result.get().getNode()) {
-                        final Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> entry = codecRegistry.toNormalizedNode(TopologyUtil.createTopologyNodePath(topologyId), node);
-                        peer.onRemoteNodeCreated(new NormalizedNodeMessage(entry.getKey(), entry.getValue()));
-                        // we dont care about the future from now on since we will be notified by the onConnected event
-                    }
-                }
-            }
-
-            @Override
-            public void onFailure(Throwable t) {
-                LOG.error("Unable to read from datastore");
-            }
-        });
-
-    }
-}
diff --git a/netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/util/NodeRoleChangeStrategy.java b/netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/util/NodeRoleChangeStrategy.java
deleted file mode 100644 (file)
index 4783404..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.netconf.topology.util;
-
-import org.opendaylight.controller.md.sal.common.api.clustering.CandidateAlreadyRegisteredException;
-import org.opendaylight.controller.md.sal.common.api.clustering.Entity;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipCandidateRegistration;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipChange;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListener;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListenerRegistration;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
-import org.opendaylight.netconf.topology.RoleChangeStrategy;
-import org.opendaylight.netconf.topology.NodeListener;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class NodeRoleChangeStrategy implements RoleChangeStrategy, EntityOwnershipListener {
-
-    private static final Logger LOG = LoggerFactory.getLogger(NodeRoleChangeStrategy.class);
-
-    private final EntityOwnershipService entityOwnershipService;
-    private final String entityType;
-    private final String entityName;
-    private final Entity entity;
-    private NodeListener ownershipCandidate;
-
-    private EntityOwnershipCandidateRegistration candidateRegistration = null;
-    private EntityOwnershipListenerRegistration ownershipListenerRegistration = null;
-
-    public NodeRoleChangeStrategy(final EntityOwnershipService entityOwnershipService,
-                                  final String entityType,
-                                  final String entityName) {
-        this.entityOwnershipService = entityOwnershipService;
-        this.entityType = entityType + "/" + entityName;
-        this.entityName = entityName;
-        this.entity = new Entity(this.entityType, entityName);
-    }
-
-    @Override
-    public void registerRoleCandidate(NodeListener electionCandidate) {
-        LOG.debug("Registering role candidate type: {} , name: {}", entityType, entityName);
-        this.ownershipCandidate = electionCandidate;
-        try {
-            if (candidateRegistration != null) {
-                unregisterRoleCandidate();
-            }
-            candidateRegistration = entityOwnershipService.registerCandidate(entity);
-            ownershipListenerRegistration = entityOwnershipService.registerListener(entityType, this);
-        } catch (CandidateAlreadyRegisteredException e) {
-            LOG.error("Candidate already registered for election", e);
-            throw new IllegalStateException("Candidate already registered for election", e);
-        }
-    }
-
-    @Override
-    public void unregisterRoleCandidate() {
-        LOG.debug("Unregistering role candidate");
-        if (candidateRegistration != null) {
-            candidateRegistration.close();
-            candidateRegistration = null;
-        }
-        if (ownershipListenerRegistration != null) {
-            ownershipListenerRegistration.close();
-            ownershipListenerRegistration = null;
-        }
-    }
-
-    @Override
-    public boolean isCandidateRegistered() {
-        return entityOwnershipService.isCandidateRegistered(entity);
-    }
-
-    @Override
-    public void onRoleChanged(RoleChangeDTO roleChangeDTO) {
-        LOG.debug("Role was changed {}", roleChangeDTO);
-        ownershipCandidate.onRoleChanged(roleChangeDTO);
-    }
-
-    @Override
-    public void ownershipChanged(EntityOwnershipChange ownershipChange) {
-        LOG.debug("Ownership has changed {}", ownershipChange);
-        ownershipCandidate.onRoleChanged(new RoleChangeDTO(ownershipChange.wasOwner(), ownershipChange.isOwner(), ownershipChange.hasOwner()));
-    }
-}
diff --git a/netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/util/NodeWriter.java b/netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/util/NodeWriter.java
deleted file mode 100644 (file)
index 0b0d7b8..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.netconf.topology.util;
-
-import com.google.common.annotations.Beta;
-import javax.annotation.Nonnull;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-
-/**
- * Customizable code that gets executed after result aggregation, meant for custom writes
- * into the datastore, but any user code can be run here if desired.
- */
-@Beta
-public interface NodeWriter {
-
-    void init(@Nonnull final NodeId id, @Nonnull final Node operationalDataNode);
-
-    void update(@Nonnull final NodeId id, @Nonnull final Node operationalDataNode);
-
-    void delete(@Nonnull final NodeId id);
-
-}
diff --git a/netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/util/NoopRoleChangeStrategy.java b/netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/util/NoopRoleChangeStrategy.java
deleted file mode 100644 (file)
index ea6e5d5..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.netconf.topology.util;
-
-import org.opendaylight.netconf.topology.NodeListener;
-import org.opendaylight.netconf.topology.RoleChangeStrategy;
-
-/**
- * Use this strategy to override the default roleChange registration's in BaseTopologyManager|BaseNodeManager
- * If you use this, you will need to execute your own election in your implemented callbacks.
- */
-public class NoopRoleChangeStrategy implements RoleChangeStrategy {
-
-    @Override
-    public void registerRoleCandidate(NodeListener electionCandidate) {
-
-    }
-
-    @Override
-    public void unregisterRoleCandidate() {
-
-    }
-
-    @Override
-    public boolean isCandidateRegistered() {
-        return false;
-    }
-
-    @Override
-    public void onRoleChanged(RoleChangeDTO roleChangeDTO) {
-
-    }
-}
diff --git a/netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/util/SalNodeWriter.java b/netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/util/SalNodeWriter.java
deleted file mode 100644 (file)
index 4f0a53a..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.netconf.topology.util;
-
-import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import javax.annotation.Nonnull;
-import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionChain;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public final class SalNodeWriter implements NodeWriter {
-
-    private static final Logger LOG = LoggerFactory.getLogger(SalNodeWriter.class);
-
-    private final String topologyId;
-
-    private final BindingTransactionChain transactionChain;
-    public SalNodeWriter(final DataBroker dataBroker, final String topologyId) {
-        this.topologyId = topologyId;
-        this.transactionChain = Preconditions.checkNotNull(dataBroker).createTransactionChain(new TransactionChainListener() {
-            @Override
-            public void onTransactionChainFailed(TransactionChain<?, ?> transactionChain, AsyncTransaction<?, ?> transaction, Throwable cause) {
-                LOG.error("{}: TransactionChain({}) {} FAILED!", transactionChain,
-                        transaction.getIdentifier(), cause);
-                throw new IllegalStateException("Abstract topology writer TransactionChain(" + transactionChain + ") not committed correctly", cause);
-            }
-
-            @Override
-            public void onTransactionChainSuccessful(TransactionChain<?, ?> transactionChain) {
-                LOG.trace("Abstract topology writer TransactionChain({}) SUCCESSFUL", transactionChain);
-            }
-        });
-    }
-
-    @Override public void init(@Nonnull final NodeId id, @Nonnull final Node operationalDataNode) {
-        // put into Datastore
-        final WriteTransaction wTx = transactionChain.newWriteOnlyTransaction();
-        wTx.put(LogicalDatastoreType.OPERATIONAL, TopologyUtil.createTopologyNodeListPath(new NodeKey(id), topologyId), operationalDataNode);
-        commitTransaction(wTx, id, "init");
-    }
-
-    @Override public void update(@Nonnull final NodeId id, @Nonnull final Node operationalDataNode) {
-        // merge
-        final WriteTransaction wTx = transactionChain.newWriteOnlyTransaction();
-        wTx.put(LogicalDatastoreType.OPERATIONAL, TopologyUtil.createTopologyNodeListPath(new NodeKey(id), topologyId), operationalDataNode);
-        commitTransaction(wTx, id, "update");
-    }
-
-    @Override public void delete(@Nonnull final NodeId id) {
-        // delete
-        final WriteTransaction wTx = transactionChain.newWriteOnlyTransaction();
-        wTx.delete(LogicalDatastoreType.OPERATIONAL, TopologyUtil.createTopologyNodeListPath(new NodeKey(id), topologyId));
-        commitTransaction(wTx, id, "delete");
-    }
-
-    private void commitTransaction(final WriteTransaction transaction, final NodeId id, final String txType) {
-        LOG.debug("{}: Committing Transaction {}:{}", id.getValue(), txType,
-                transaction.getIdentifier());
-        final CheckedFuture<Void, TransactionCommitFailedException> result = transaction.submit();
-
-        Futures.addCallback(result, new FutureCallback<Void>() {
-            @Override
-            public void onSuccess(final Void result) {
-                LOG.debug("{}: Transaction({}) {} SUCCESSFUL", id.getValue(), txType,
-                        transaction.getIdentifier());
-            }
-
-            @Override
-            public void onFailure(final Throwable t) {
-                LOG.error("{}: Transaction({}) {} FAILED!", id.getValue(), txType,
-                        transaction.getIdentifier(), t);
-                throw new IllegalStateException(id + "  Transaction(" + txType + ") not committed correctly", t);
-            }
-        });
-    }
-}
diff --git a/netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/util/TopologyRoleChangeStrategy.java b/netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/util/TopologyRoleChangeStrategy.java
deleted file mode 100644 (file)
index a7fc412..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.netconf.topology.util;
-
-import java.util.Collection;
-import javax.annotation.Nonnull;
-import org.opendaylight.controller.md.sal.binding.api.ClusteredDataTreeChangeListener;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
-import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
-import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
-import org.opendaylight.controller.md.sal.common.api.clustering.CandidateAlreadyRegisteredException;
-import org.opendaylight.controller.md.sal.common.api.clustering.Entity;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipCandidateRegistration;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipChange;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListener;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListenerRegistration;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.netconf.topology.NodeListener;
-import org.opendaylight.netconf.topology.RoleChangeStrategy;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class TopologyRoleChangeStrategy implements RoleChangeStrategy, ClusteredDataTreeChangeListener<Node>, EntityOwnershipListener {
-
-    private static final Logger LOG = LoggerFactory.getLogger(TopologyRoleChangeStrategy.class);
-
-    private final DataBroker dataBroker;
-
-    private final EntityOwnershipService entityOwnershipService;
-    private NodeListener ownershipCandidate;
-    private final String entityType;
-    // use topologyId as entityName
-    private final Entity entity;
-
-    private EntityOwnershipCandidateRegistration candidateRegistration = null;
-    private EntityOwnershipListenerRegistration ownershipListenerRegistration = null;
-
-    private ListenerRegistration<TopologyRoleChangeStrategy> datastoreListenerRegistration;
-
-    public TopologyRoleChangeStrategy(final DataBroker dataBroker,
-                                      final EntityOwnershipService entityOwnershipService,
-                                      final String entityType,
-                                      final String entityName) {
-        this.dataBroker = dataBroker;
-        this.entityOwnershipService = entityOwnershipService;
-        this.entityType = entityType;
-        this.entity = new Entity(entityType, entityName);
-
-        datastoreListenerRegistration = null;
-    }
-
-    @Override
-    public void registerRoleCandidate(NodeListener electionCandidate) {
-        LOG.warn("Registering candidate");
-        ownershipCandidate = electionCandidate;
-        try {
-            if (candidateRegistration != null) {
-                unregisterRoleCandidate();
-            }
-            candidateRegistration = entityOwnershipService.registerCandidate(entity);
-            ownershipListenerRegistration = entityOwnershipService.registerListener(entityType, this);
-        } catch (CandidateAlreadyRegisteredException e) {
-            LOG.error("Candidate already registered for election", e);
-            throw new IllegalStateException("Candidate already registered for election", e);
-        }
-    }
-
-    @Override
-    public void unregisterRoleCandidate() {
-        candidateRegistration.close();
-        candidateRegistration = null;
-        ownershipListenerRegistration.close();
-        ownershipListenerRegistration = null;
-    }
-
-    @Override
-    public boolean isCandidateRegistered() {
-        return entityOwnershipService.isCandidateRegistered(entity);
-    }
-
-    @Override
-    public void onRoleChanged(RoleChangeDTO roleChangeDTO) {
-        if (roleChangeDTO.isOwner()) {
-            LOG.warn("Gained ownership of entity, registering datastore listener");
-
-            if (datastoreListenerRegistration == null) {
-                LOG.debug("Listener on path {}", TopologyUtil.createTopologyListPath(entityType).child(Node.class).getPathArguments());
-                datastoreListenerRegistration = dataBroker.registerDataTreeChangeListener(
-                        new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION, TopologyUtil.createTopologyListPath(entityType).child(Node.class)), this);
-            }
-        } else if (datastoreListenerRegistration != null) {
-            LOG.warn("No longer owner of entity, unregistering datastore listener");
-            datastoreListenerRegistration.close();
-            datastoreListenerRegistration = null;
-        }
-        ownershipCandidate.onRoleChanged(roleChangeDTO);
-    }
-
-    @Override
-    public void ownershipChanged(final EntityOwnershipChange ownershipChange) {
-        onRoleChanged(new RoleChangeDTO(ownershipChange.wasOwner(), ownershipChange.isOwner(), ownershipChange.hasOwner()));
-    }
-
-    @Override
-    public void onDataTreeChanged(@Nonnull Collection<DataTreeModification<Node>> changes) {
-        for (DataTreeModification<Node> change : changes) {
-            final DataObjectModification<Node> rootNode = change.getRootNode();
-            switch (rootNode.getModificationType()) {
-                case WRITE:
-                    LOG.debug("Data was Created {}, {}", rootNode.getIdentifier(), rootNode.getDataAfter());
-                    ownershipCandidate.onNodeCreated(TopologyUtil.getNodeId(rootNode.getIdentifier()), rootNode.getDataAfter());
-                    break;
-                case SUBTREE_MODIFIED:
-                    LOG.debug("Data was Updated {}, {}", rootNode.getIdentifier(), rootNode.getDataAfter());
-                    ownershipCandidate.onNodeUpdated(TopologyUtil.getNodeId(rootNode.getIdentifier()), rootNode.getDataAfter());
-                    break;
-                case DELETE:
-                    LOG.debug("Data was Deleted {}", rootNode.getIdentifier());
-                    ownershipCandidate.onNodeDeleted(TopologyUtil.getNodeId(rootNode.getIdentifier()));
-            }
-        }
-    }
-}
diff --git a/netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/util/messages/CustomIdentifyMessage.java b/netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/util/messages/CustomIdentifyMessage.java
deleted file mode 100644 (file)
index 721dcf6..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.netconf.topology.util.messages;
-
-import akka.actor.Address;
-import java.io.Serializable;
-
-public class CustomIdentifyMessage implements Serializable {
-    private static final long serialVersionUID = 1L;
-
-    private final Address address;
-
-    public CustomIdentifyMessage(final Address addressFrom) {
-        address = addressFrom;
-    }
-
-    public Address getAddress() {
-        return address;
-    }
-}
diff --git a/netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/util/messages/CustomIdentifyMessageReply.java b/netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/util/messages/CustomIdentifyMessageReply.java
deleted file mode 100644 (file)
index 62a5b43..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.netconf.topology.util.messages;
-
-import akka.actor.Address;
-
-// Marker message, that signals that actor should not reply to this one
-public class CustomIdentifyMessageReply extends CustomIdentifyMessage {
-    private static final long serialVersionUID = 1L;
-
-    public CustomIdentifyMessageReply(final Address addressFrom) {
-        super(addressFrom);
-    }
-}
diff --git a/netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/util/messages/NormalizedNodeMessage.java b/netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/util/messages/NormalizedNodeMessage.java
deleted file mode 100644 (file)
index 9d12735..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.netconf.topology.util.messages;
-
-import java.io.Externalizable;
-import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-import org.opendaylight.controller.cluster.datastore.node.utils.stream.NormalizedNodeDataInput;
-import org.opendaylight.controller.cluster.datastore.node.utils.stream.NormalizedNodeDataOutput;
-import org.opendaylight.controller.cluster.datastore.node.utils.stream.NormalizedNodeInputOutput;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter;
-
-public class NormalizedNodeMessage implements Externalizable{
-    private static final long serialVersionUID = 1L;
-
-    private YangInstanceIdentifier identifier = null;
-    private NormalizedNode<?, ?> node = null;
-
-    public NormalizedNodeMessage() {
-
-    }
-
-    public NormalizedNodeMessage(YangInstanceIdentifier identifier, NormalizedNode<?, ?> node) {
-        this.identifier = identifier;
-        this.node = node;
-    }
-
-    public YangInstanceIdentifier getIdentifier() {
-        return identifier;
-    }
-
-    public NormalizedNode<?, ?> getNode() {
-        return node;
-    }
-
-    @Override
-    public void writeExternal(final ObjectOutput out) throws IOException {
-        final NormalizedNodeDataOutput dataOutput = NormalizedNodeInputOutput.newDataOutput(out);
-        final NormalizedNodeWriter normalizedNodeWriter = NormalizedNodeWriter.forStreamWriter((NormalizedNodeStreamWriter) dataOutput);
-
-        dataOutput.writeYangInstanceIdentifier(identifier);
-        normalizedNodeWriter.write(node);
-    }
-
-    @Override
-    public void readExternal(final ObjectInput in) throws IOException, ClassNotFoundException {
-        final NormalizedNodeDataInput dataInput = NormalizedNodeInputOutput.newDataInput(in);
-
-        identifier = dataInput.readYangInstanceIdentifier();
-        node = dataInput.readNormalizedNode();
-    }
-}
index 52b8a6a0859b0ca4cb618280912cc1472dca6125..8fcb44cfc120ff6f29fcfc4c1c5a3c6f6a809feb 100644 (file)
@@ -15,6 +15,7 @@ import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
 import org.opendaylight.controller.messagebus.spi.EventSourceRegistration;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus.ConnectionStatus;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.available.capabilities.AvailableCapability;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.network.topology.topology.topology.types.TopologyNetconf;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
@@ -66,12 +67,12 @@ public class NetconfEventSourceRegistration implements AutoCloseable {
         if (netconfNode.getAvailableCapabilities() == null) {
             return false;
         }
-        final List<String> capabilities = netconfNode.getAvailableCapabilities().getAvailableCapability();
+        final List<AvailableCapability> capabilities = netconfNode.getAvailableCapabilities().getAvailableCapability();
         if (capabilities == null || capabilities.isEmpty()) {
             return false;
         }
-        for (final String capability : netconfNode.getAvailableCapabilities().getAvailableCapability()) {
-            if (capability.startsWith(NotificationCapabilityPrefix)) {
+        for (final AvailableCapability capability : netconfNode.getAvailableCapabilities().getAvailableCapability()) {
+            if (capability.getCapability().startsWith(NotificationCapabilityPrefix)) {
                 return true;
             }
         }
index a403681b7624703483e1240f62c627af171300c1..3124d6b1f064071f0dafa3a859b8300e44f1d675 100644 (file)
@@ -24,6 +24,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev15
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus.ConnectionStatus;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.AvailableCapabilities;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.AvailableCapabilitiesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.available.capabilities.AvailableCapability;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.available.capabilities.AvailableCapabilityBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.network.topology.topology.topology.types.TopologyNetconf;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
@@ -55,8 +57,8 @@ public final class NetconfTestUtils {
         DomainName dn = new DomainName(hostName);
         Host host = new Host(dn);
 
-        List<String> avCapList = new ArrayList<>();
-        avCapList.add(notificationCapabilityPrefix + "_availableCapabilityString1");
+        List<AvailableCapability> avCapList = new ArrayList<>();
+        avCapList.add(new AvailableCapabilityBuilder().setCapability(notificationCapabilityPrefix + "_availableCapabilityString1").build());
         AvailableCapabilities avCaps = new AvailableCapabilitiesBuilder().setAvailableCapability(avCapList).build();
         NetconfNode nn = new NetconfNodeBuilder().setConnectionStatus(cs).setHost(host).setAvailableCapabilities(avCaps)
             .build();
index 4a8b22096a563dbb874e7c592797bbe75d17c58c..7102db1cb25db4a9b25fc1c357d57b50a4153631 100644 (file)
                 <artifactId>aaa-authn-odl-plugin</artifactId>
                 <version>${project.version}</version>
             </dependency>
-            <dependency>
-                <groupId>${project.groupId}</groupId>
-                <artifactId>abstract-topology</artifactId>
-                <version>${project.version}</version>
-            </dependency>
             <dependency>
                 <groupId>${project.groupId}</groupId>
                 <artifactId>netconf-config-dispatcher</artifactId>
                 <artifactId>netconf-util</artifactId>
                 <version>${project.version}</version>
             </dependency>
+            <dependency>
+                <groupId>${project.groupId}</groupId>
+                <artifactId>netconf-util</artifactId>
+                <version>${project.version}</version>
+                <classifier>config</classifier>
+                <type>cfg</type>
+            </dependency>
             <dependency>
                 <groupId>${project.groupId}</groupId>
                 <artifactId>netconf-mdsal-config</artifactId>
                 <classifier>config</classifier>
                 <type>xml</type>
             </dependency>
-            <dependency>
-                <groupId>${project.groupId}</groupId>
-                <artifactId>netconf-topology-config</artifactId>
-                <version>${project.version}</version>
-                <classifier>clustered-config</classifier>
-                <type>xml</type>
-            </dependency>
             <dependency>
                 <groupId>${project.groupId}</groupId>
                 <artifactId>yanglib-config</artifactId>
                 <version>${project.version}</version>
                 <type>test-jar</type>
             </dependency>
+            <dependency>
+                <groupId>${project.groupId}</groupId>
+                <artifactId>netconf-topology-singleton</artifactId>
+                <version>${project.version}</version>
+            </dependency>
 
             <dependency>
                 <groupId>${project.groupId}</groupId>
index baf98f06d677705b5668998e40382eab055cb63f..d830e9d097b0f14a6a94a2ea20b7fd5a2a026ae0 100644 (file)
@@ -17,8 +17,8 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.UUID;
+import java.util.stream.Collectors;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.MountPoint;
 import org.opendaylight.controller.md.sal.binding.api.MountPointService;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
@@ -33,20 +33,15 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.available.capabilities.AvailableCapability;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.credentials.Credentials;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.credentials.credentials.LoginPasswordBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.rev130405.ModuleType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.rev130405.Modules;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.rev130405.modules.Module;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.rev130405.modules.ModuleKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.connector.netconf.rev150803.SalNetconfConnector;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -97,7 +92,8 @@ public class NetconfCommandsImpl implements NetconfCommands {
                     attributes.put(NetconfConsoleConstants.NETCONF_IP, ImmutableList.of(netconfNode.getHost().getIpAddress().getIpv4Address().getValue()));
                     attributes.put(NetconfConsoleConstants.NETCONF_PORT, ImmutableList.of(netconfNode.getPort().getValue().toString()));
                     attributes.put(NetconfConsoleConstants.STATUS, ImmutableList.of(netconfNode.getConnectionStatus().name()));
-                    attributes.put(NetconfConsoleConstants.AVAILABLE_CAPABILITIES, netconfNode.getAvailableCapabilities().getAvailableCapability());
+                    attributes.put(NetconfConsoleConstants.AVAILABLE_CAPABILITIES,
+                            netconfNode.getAvailableCapabilities().getAvailableCapability().stream().map(AvailableCapability::getCapability).collect(Collectors.toList()));
                     device.put(node.getNodeId().getValue(), attributes);
                 }
             }
@@ -117,7 +113,8 @@ public class NetconfCommandsImpl implements NetconfCommands {
                 attributes.put(NetconfConsoleConstants.NETCONF_IP, ImmutableList.of(netconfNode.getHost().getIpAddress().getIpv4Address().getValue()));
                 attributes.put(NetconfConsoleConstants.NETCONF_PORT, ImmutableList.of(netconfNode.getPort().getValue().toString()));
                 attributes.put(NetconfConsoleConstants.STATUS, ImmutableList.of(netconfNode.getConnectionStatus().name()));
-                attributes.put(NetconfConsoleConstants.AVAILABLE_CAPABILITIES, netconfNode.getAvailableCapabilities().getAvailableCapability());
+                attributes.put(NetconfConsoleConstants.AVAILABLE_CAPABILITIES,
+                        netconfNode.getAvailableCapabilities().getAvailableCapability().stream().map(AvailableCapability::getCapability).collect(Collectors.toList()));
                 device.put(node.getNodeId().getValue(), attributes);
             }
         }
index 96c5b271e1962ff0dac318acd039f9cb20408fa6..1ccd575c78096d75b938360f9e679b3256605310 100644 (file)
@@ -52,6 +52,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev15
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.AvailableCapabilities;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.AvailableCapabilitiesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.available.capabilities.AvailableCapability;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.available.capabilities.AvailableCapabilityBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.network.topology.topology.topology.types.TopologyNetconf;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
@@ -248,8 +250,10 @@ public class NetconfCommandsImplTest {
         final Host host = HostBuilder.getDefaultInstance(ip);
         final PortNumber port = new PortNumber(portNumber);
 
-        final List<String> avCapList = new ArrayList<>();
-        avCapList.add(notificationCapabilityPrefix + "_availableCapabilityString1");
+        final List<AvailableCapability> avCapList = new ArrayList<>();
+        avCapList.add(new AvailableCapabilityBuilder()
+                .setCapabilityOrigin(AvailableCapability.CapabilityOrigin.UserDefined)
+                .setCapability(notificationCapabilityPrefix + "_availableCapabilityString1").build());
         final AvailableCapabilities avCaps = new AvailableCapabilitiesBuilder().setAvailableCapability(avCapList).build();
 
         final NetconfNode nn = new NetconfNodeBuilder().setConnectionStatus(cs).setHost(host).setPort(port).
@@ -290,7 +294,9 @@ public class NetconfCommandsImplTest {
 
     private List<InputStream> getYangSchemas() {
         final List<String> schemaPaths = Arrays.asList("/schemas/network-topology@2013-10-21.yang",
-                "/schemas/ietf-inet-types@2013-07-15.yang", "/schemas/yang-ext.yang", "/schemas/netconf-node-topology.yang");
+                "/schemas/ietf-inet-types@2013-07-15.yang", "/schemas/yang-ext.yang",
+                "/schemas/netconf-node-topology.yang");
+
         final List<InputStream> schemas = new ArrayList<>();
         for (String schemaPath : schemaPaths) {
             final InputStream resourceAsStream = getClass().getResourceAsStream(schemaPath);
index 62b88b974f2091e575b6a4f70b59ad4b1b7b1e55..07461d48d75f67327cf0c6e380a4af454fa748ee 100644 (file)
@@ -162,8 +162,16 @@ module netconf-node-topology {
 
         container available-capabilities {
             config false;
-            leaf-list available-capability {
-                type string;
+            list available-capability {
+                leaf capability {
+                    type string;
+                }
+                leaf capability-origin {
+                    type enumeration {
+                        enum user-defined;
+                        enum device-advertised;
+                    }
+                }
             }
         }
 
diff --git a/netconf/netconf-notifications-api/src/test/java/org/opendaylight/netconf/notifications/NetconfNotificationTest.java b/netconf/netconf-notifications-api/src/test/java/org/opendaylight/netconf/notifications/NetconfNotificationTest.java
new file mode 100644 (file)
index 0000000..345b37a
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.notifications;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import javax.xml.datatype.DatatypeConfigurationException;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import org.junit.Test;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+public class NetconfNotificationTest {
+
+    @Test
+    public void testWrapNotification() throws Exception {
+        final DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
+        final DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
+
+        final Document document = docBuilder.newDocument();
+
+        final Element rootElement = document.createElement("test-root");
+        document.appendChild(rootElement);
+
+        final Date eventTime = new Date();
+        eventTime.setTime(10000000);
+
+        final NetconfNotification netconfNotification = new NetconfNotification(document, eventTime);
+        final Document resultDoc = netconfNotification.getDocument();
+        final NodeList nodeList = resultDoc.getElementsByTagNameNS(NetconfNotification.NOTIFICATION_NAMESPACE,
+                NetconfNotification.NOTIFICATION);
+
+        assertNotNull(nodeList);
+        // expected only the one NOTIFICATION tag
+        assertEquals(1, nodeList.getLength());
+
+        final Element entireNotification = (Element) nodeList.item(0);
+        final NodeList childNodes = entireNotification.getElementsByTagNameNS(
+                NetconfNotification.NOTIFICATION_NAMESPACE, NetconfNotification.EVENT_TIME);
+
+        assertNotNull(childNodes);
+        // expected only the one EVENT_TIME tag
+        assertEquals(1, childNodes.getLength());
+
+        final Element eventTimeElement = (Element) childNodes.item(0);
+
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
+        assertEquals(eventTime.getTime(), sdf.parse(eventTimeElement.getTextContent()).getTime());
+
+        assertEquals(eventTime, netconfNotification.getEventTime());
+
+    }
+}
index fe563f4883f8b96ab078415ed4c99c2f12f5b5f5..0225bdbf6f9f075ac302e473f994f2a380aade71 100644 (file)
       <artifactId>netconf-client</artifactId>
       <scope>test</scope>
     </dependency>
+    <dependency>
+        <groupId>org.osgi</groupId>
+        <artifactId>org.osgi.compendium</artifactId>
+    </dependency>
   </dependencies>
 
   <build>
           </execution>
         </executions>
       </plugin>
-        <plugin>
-            <groupId>org.opendaylight.yangtools</groupId>
-            <artifactId>yang-maven-plugin</artifactId>
-        </plugin>
+      <plugin>
+          <groupId>org.opendaylight.yangtools</groupId>
+          <artifactId>yang-maven-plugin</artifactId>
+      </plugin>
     </plugins>
   </build>
 
index 9cbfac1580a3a22a0c3285129f6cee526f300e8b..14cbae81e1891edb357717c5f0dfc88e88dcd545 100644 (file)
@@ -7,7 +7,6 @@
  */
 package org.opendaylight.netconf.ssh.osgi;
 
-import com.google.common.base.Optional;
 import io.netty.channel.local.LocalAddress;
 import io.netty.channel.nio.NioEventLoopGroup;
 import java.io.IOException;
@@ -21,7 +20,7 @@ import org.apache.sshd.server.keyprovider.PEMGeneratorHostKeyProvider;
 import org.opendaylight.netconf.ssh.SshProxyServer;
 import org.opendaylight.netconf.ssh.SshProxyServerConfigurationBuilder;
 import org.opendaylight.netconf.util.osgi.NetconfConfigUtil;
-import org.opendaylight.netconf.util.osgi.NetconfConfigUtil.InfixProp;
+import org.opendaylight.netconf.util.osgi.NetconfConfiguration;
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
 import org.slf4j.Logger;
@@ -79,25 +78,17 @@ public class NetconfSSHActivator implements BundleActivator {
     }
 
     private SshProxyServer startSSHServer(final BundleContext bundleContext) throws IOException {
-        final Optional<InetSocketAddress> maybeSshSocketAddress = NetconfConfigUtil.extractNetconfServerAddress(bundleContext, InfixProp.ssh);
-        if (!maybeSshSocketAddress.isPresent()) {
-            LOG.warn("SSH bridge not configured. Using default value {}", NetconfConfigUtil.DEFAULT_SSH_SERVER_ADRESS);
-        }
-        final InetSocketAddress sshSocketAddress = maybeSshSocketAddress
-                .or(NetconfConfigUtil.DEFAULT_SSH_SERVER_ADRESS);
-        LOG.info("Starting netconf SSH bridge at {}", sshSocketAddress);
+        final NetconfConfiguration netconfConfiguration = NetconfConfigUtil.getNetconfConfigurationService(bundleContext).
+                        orElseThrow(() -> new IllegalStateException("Configuration for SSH not found."));
 
-        final LocalAddress localAddress = NetconfConfigUtil.getNetconfLocalAddress();
+        final InetSocketAddress sshSocketAddress = netconfConfiguration.getSshServerAddress();
+        LOG.info("Starting netconf SSH server at {}", sshSocketAddress);
 
+        final LocalAddress localAddress = NetconfConfigUtil.getNetconfLocalAddress();
         authProviderTracker = new AuthProviderTracker(bundleContext);
 
-        final Optional<String> maybePath = NetconfConfigUtil.getPrivateKeyPath(bundleContext);
-        if(!maybePath.isPresent()) {
-            LOG.warn("Private key path not configured. Using default value {}",
-                    NetconfConfigUtil.DEFAULT_PRIVATE_KEY_PATH);
-        }
-        final String path = maybePath.or(NetconfConfigUtil.DEFAULT_PRIVATE_KEY_PATH);
-        LOG.trace("Starting netconf SSH bridge with path to ssh private key {}", path);
+        final String path = netconfConfiguration.getPrivateKeyPath();
+        LOG.trace("Starting netconf SSH server with path to ssh private key {}", path);
 
         final SshProxyServer sshProxyServer = new SshProxyServer(minaTimerExecutor, clientGroup, nioExecutor);
         sshProxyServer.bind(
@@ -110,5 +101,4 @@ public class NetconfSSHActivator implements BundleActivator {
                         .createSshProxyServerConfiguration());
         return sshProxyServer;
     }
-
 }
index f6c8c05f0539260883847f988c463b6b87b301ed..0e45504a588c639ff716e6810064cd9eb74d736e 100644 (file)
       <artifactId>mockito-configuration</artifactId>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>org.osgi</groupId>
+      <artifactId>org.osgi.compendium</artifactId>
+    </dependency>
   </dependencies>
 
   <build>
index 1f4188d827103fbbd5a2562d615ace2536de7e38..d972a32ba70c9ede29a146cdc572bd610f979862 100644 (file)
@@ -8,11 +8,11 @@
 
 package org.opendaylight.netconf.tcp.osgi;
 
-import com.google.common.base.Optional;
 import java.net.InetSocketAddress;
 import org.opendaylight.netconf.tcp.netty.ProxyServer;
 import org.opendaylight.netconf.util.osgi.NetconfConfigUtil;
 import org.opendaylight.netconf.util.osgi.NetconfConfigUtil.InfixProp;
+import org.opendaylight.netconf.util.osgi.NetconfConfiguration;
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
 import org.slf4j.Logger;
@@ -27,13 +27,10 @@ public class NetconfTCPActivator implements BundleActivator {
 
     @Override
     public void start(BundleContext context) {
-        final Optional<InetSocketAddress> maybeAddress = NetconfConfigUtil.extractNetconfServerAddress(context, InfixProp.tcp);
-        if (maybeAddress.isPresent() == false) {
-            LOG.warn("Netconf tcp server is not configured. Using default value {}",
-                    NetconfConfigUtil.DEFAULT_TCP_SERVER_ADRESS);
-        }
+        final NetconfConfiguration netconfConfiguration = NetconfConfigUtil.getNetconfConfigurationService(context).
+                        orElseThrow(() -> new IllegalStateException("Configuration for TCP not found."));
 
-        InetSocketAddress address = maybeAddress.or(NetconfConfigUtil.DEFAULT_TCP_SERVER_ADRESS);
+        final InetSocketAddress address = netconfConfiguration.getTcpServerAddress();
 
         if (address.getAddress().isAnyLocalAddress()) {
             LOG.warn("Unprotected netconf TCP address is configured to ANY local address. This is a security risk. Consider changing {} to 127.0.0.1",
index 65135c0f81e0a95669a7129ab1a097237489040e..75113816f39a41908befb264f29907ade9f2b074 100644 (file)
                                     <type>xml</type>
                                     <classifier>config</classifier>
                                 </artifact>
-                                <artifact>
-                                    <file>${project.build.directory}/classes/initial/02-clustered-netconf-topology.xml</file>
-                                    <type>xml</type>
-                                    <classifier>clustered-config</classifier>
-                                </artifact>
                             </artifacts>
                         </configuration>
                     </execution>
diff --git a/netconf/netconf-topology-config/src/main/resources/initial/02-clustered-netconf-topology.xml b/netconf/netconf-topology-config/src/main/resources/initial/02-clustered-netconf-topology.xml
deleted file mode 100644 (file)
index ded67f5..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- vi: set et smarttab sw=4 tabstop=4: -->
-<!--
- Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
-
- This program and the accompanying materials are made available under the
- terms of the Eclipse Public License v1.0 which accompanies this distribution,
- and is available at http://www.eclipse.org/legal/epl-v10.html
--->
-<snapshot>
-    <configuration>
-        <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
-            <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
-                <module>
-                    <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:clustered:netconf:topology">prefix:clustered-netconf-topology-impl</type>
-                    <name>clustered-netconf-topology</name>
-                    <topology-id xmlns="urn:opendaylight:params:xml:ns:yang:controller:clustered:netconf:topology">topology-netconf</topology-id>
-                    <event-executor xmlns="urn:opendaylight:params:xml:ns:yang:controller:clustered:netconf:topology">
-                        <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty">prefix:netty-event-executor</type>
-                        <name>global-event-executor</name>
-                    </event-executor>
-                    <binding-registry xmlns="urn:opendaylight:params:xml:ns:yang:controller:clustered:netconf:topology">
-                        <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">prefix:binding-broker-osgi-registry</type>
-                        <name>binding-osgi-broker</name>
-                    </binding-registry>
-                    <dom-registry xmlns="urn:opendaylight:params:xml:ns:yang:controller:clustered:netconf:topology">
-                        <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">prefix:dom-broker-osgi-registry</type>
-                        <name>dom-broker</name>
-                    </dom-registry>
-                    <client-dispatcher xmlns="urn:opendaylight:params:xml:ns:yang:controller:clustered:netconf:topology">
-                        <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:netconf">prefix:netconf-client-dispatcher</type>
-                        <name>global-netconf-dispatcher</name>
-                    </client-dispatcher>
-                    <processing-executor xmlns="urn:opendaylight:params:xml:ns:yang:controller:clustered:netconf:topology">
-                        <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool">prefix:threadpool</type>
-                        <name>global-netconf-processing-executor</name>
-                    </processing-executor>
-                    <keepalive-executor xmlns="urn:opendaylight:params:xml:ns:yang:controller:clustered:netconf:topology">
-                        <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool">prefix:scheduled-threadpool</type>
-                        <name>global-netconf-ssh-scheduled-executor</name>
-                    </keepalive-executor>
-                    <shared-schema-repository xmlns="urn:opendaylight:params:xml:ns:yang:controller:clustered:netconf:topology">
-                        <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netconf:topology:shared:schema:repository">prefix:shared-schema-repository</type>
-                        <name>default-shared-schema-repository</name>
-                    </shared-schema-repository>
-                    <entity-ownership-service xmlns="urn:opendaylight:params:xml:ns:yang:controller:clustered:netconf:topology">
-                        <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:core:spi:entity-ownership-service">prefix:entity-ownership-service</type>
-                        <name>entity-ownership-service</name>
-                    </entity-ownership-service>
-                    <actor-system-provider-service xmlns="urn:opendaylight:params:xml:ns:yang:controller:clustered:netconf:topology">
-                        <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:actor-system-provider:service">prefix:actor-system-provider-service</type>
-                        <name>actor-system-provider</name>
-                    </actor-system-provider-service>
-                </module>
-            </modules>
-
-            <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
-                <service>
-                    <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netconf:topology">prefix:netconf-topology</type>
-                    <instance>
-                        <name>clustered-netconf-topology</name>
-                        <provider>/modules/module[type='clustered-netconf-topology-impl'][name='clustered-netconf-topology']</provider>
-                    </instance>
-                </service>
-            </services>
-        </data>
-    </configuration>
-    <required-capabilities>
-        <capability>urn:opendaylight:params:xml:ns:yang:controller:netconf:topology?module=netconf-topology&amp;revision=2015-07-27</capability>
-        <capability>urn:opendaylight:params:xml:ns:yang:controller:clustered:netconf:topology?module=clustered-netconf-topology&amp;revision=2015-11-04</capability>
-        <capability>
-            urn:opendaylight:params:xml:ns:yang:controller:config:legacy-entity-ownership-service-provider?module=opendaylight-legacy-entity-ownership-service-provider&amp;revision=2016-02-26
-        </capability>
-        <capability>urn:opendaylight:params:xml:ns:yang:controller:config:actor-system-provider:service?module=actor-system-provider-service&amp;revision=2015-10-05</capability>
-    </required-capabilities>
-</snapshot>
\ No newline at end of file
similarity index 64%
rename from netconf/abstract-topology/pom.xml
rename to netconf/netconf-topology-singleton/pom.xml
index bf17207321dfecd69e25b887cf77c4a4e4750e68..e247fb5071c1a62541c62a932c60493b8990919c 100644 (file)
     <modelVersion>4.0.0</modelVersion>
 
     <parent>
-        <groupId>org.opendaylight.odlparent</groupId>
-        <artifactId>bundle-parent</artifactId>
-        <version>1.8.0-SNAPSHOT</version>
+        <groupId>org.opendaylight.controller</groupId>
+        <artifactId>config-parent</artifactId>
+        <version>0.6.0-SNAPSHOT</version>
         <relativePath/>
     </parent>
 
     <groupId>org.opendaylight.netconf</groupId>
-    <artifactId>abstract-topology</artifactId>
+    <artifactId>netconf-topology-singleton</artifactId>
     <version>1.2.0-SNAPSHOT</version>
+    <name>${project.artifactId}</name>
     <packaging>bundle</packaging>
 
     <dependencyManagement>
                 <type>pom</type>
                 <scope>import</scope>
             </dependency>
+            <dependency>
+                <groupId>org.opendaylight.controller</groupId>
+                <artifactId>mdsal-artifacts</artifactId>
+                <version>1.5.0-SNAPSHOT</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
         </dependencies>
     </dependencyManagement>
 
-    <properties>
-    </properties>
-
     <dependencies>
+        <dependency>
+            <groupId>org.opendaylight.netconf</groupId>
+            <artifactId>mdsal-netconf-notification</artifactId>
+        </dependency>
         <dependency>
             <groupId>org.opendaylight.mdsal.model</groupId>
             <artifactId>ietf-topology</artifactId>
         </dependency>
         <dependency>
-            <groupId>org.opendaylight.controller</groupId>
-            <artifactId>sal-common-api</artifactId>
+            <groupId>com.typesafe.akka</groupId>
+            <artifactId>akka-actor_2.11</artifactId>
         </dependency>
         <dependency>
-            <groupId>${project.groupId}</groupId>
+            <groupId>org.opendaylight.netconf</groupId>
             <artifactId>sal-netconf-connector</artifactId>
         </dependency>
         <dependency>
-            <groupId>org.opendaylight.controller</groupId>
-            <artifactId>sal-binding-api</artifactId>
+            <groupId>com.typesafe.akka</groupId>
+            <artifactId>akka-cluster_2.11</artifactId>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>sal-clustering-commons</artifactId>
         </dependency>
-        <dependency>
-            <groupId>org.scala-lang</groupId>
-            <artifactId>scala-library</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>com.typesafe.akka</groupId>
-            <artifactId>akka-actor_${scala.version}</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>com.typesafe.akka</groupId>
-            <artifactId>akka-remote_${scala.version}</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>com.typesafe.akka</groupId>
-            <artifactId>akka-cluster_${scala.version}</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>com.typesafe.akka</groupId>
-            <artifactId>akka-osgi_${scala.version}</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>com.typesafe</groupId>
-            <artifactId>config</artifactId>
-        </dependency>
         <dependency>
             <groupId>org.mockito</groupId>
             <artifactId>mockito-all</artifactId>
             <scope>test</scope>
         </dependency>
         <dependency>
-            <groupId>com.jayway.awaitility</groupId>
-            <artifactId>awaitility</artifactId>
-            <version>1.6.5</version>
+            <groupId>com.typesafe.akka</groupId>
+            <artifactId>akka-testkit_2.11</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>sal-distributed-datastore</artifactId>
+        </dependency>
     </dependencies>
-</project>
+
+</project>
\ No newline at end of file
diff --git a/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/api/NetconfDOMTransaction.java b/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/api/NetconfDOMTransaction.java
new file mode 100644 (file)
index 0000000..ec9c717
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.topology.singleton.api;
+
+import com.google.common.base.Optional;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.netconf.topology.singleton.messages.NormalizedNodeMessage;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import scala.concurrent.Future;
+
+/**
+ * Provides API for all operations of read and write transactions
+ */
+public interface NetconfDOMTransaction {
+
+    /**
+     * Read data from particular data-store
+     * @param store data-store type
+     * @param path unique identifier of a particular node instance in the data tree
+     * @return result as future
+     */
+    Future<Optional<NormalizedNodeMessage>> read(LogicalDatastoreType store, YangInstanceIdentifier path);
+
+    /**
+     * Test existence of node in certain data-store
+     * @param store data-store type
+     * @param path unique identifier of a particular node instance in the data tree
+     * @return result as future
+     */
+    Future<Boolean> exists(LogicalDatastoreType store, YangInstanceIdentifier path);
+
+    /**
+     * Put data to particular data-store
+     * @param store data-store type
+     * @param data data for inserting included in NormalizedNodeMessage object
+     */
+    void put(LogicalDatastoreType store, NormalizedNodeMessage data);
+
+    /**
+     * Merge data with existing node in particular data-store
+     * @param store data-store type
+     * @param data data for merging included in NormalizedNodeMessage object
+     */
+    void merge(LogicalDatastoreType store, NormalizedNodeMessage data);
+
+    /**
+     * Delete node in particular data-store in path
+     * @param store data-store type
+     * @param path unique identifier of a particular node instance in the data tree
+     */
+    void delete(LogicalDatastoreType store, YangInstanceIdentifier path);
+
+    /**
+     * Cancel operation
+     * @return success or not
+     */
+    boolean cancel();
+
+    /**
+     * Commit opened transaction.
+     * @return void or raised exception
+     */
+    Future<Void> submit();
+}
@@ -1,12 +1,15 @@
 /*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
 
-package org.opendaylight.netconf.topology.pipeline.tx;
+package org.opendaylight.netconf.topology.singleton.api;
 
-public interface NetconfDeviceDataBrokerProxy {
+/**
+ * Provides API for advertising services for blue print service
+ */
+public interface NetconfTopologySingletonService {
 }
diff --git a/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/api/RemoteDeviceConnector.java b/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/api/RemoteDeviceConnector.java
new file mode 100644 (file)
index 0000000..bb74b75
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.topology.singleton.api;
+
+import akka.actor.ActorRef;
+
+/**
+ * Provides API for connection odl (master) with device
+ */
+public interface RemoteDeviceConnector {
+
+    /**
+     * Create device communicator and open device connection
+     * @param masterActorRef master actor reference
+     */
+    void startRemoteDeviceConnection(ActorRef masterActorRef);
+
+    /**
+     * Stop device communicator
+     */
+    void stopRemoteDeviceConnection();
+}
diff --git a/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/api/RemoteOperationTxProcessor.java b/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/api/RemoteOperationTxProcessor.java
new file mode 100644 (file)
index 0000000..9023847
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.topology.singleton.api;
+
+import akka.actor.ActorRef;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.netconf.topology.singleton.messages.NormalizedNodeMessage;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+
+/**
+ * Provides API for remote calling operations of transactions. Slave sends message of particular
+ * operation to master and master performs it.
+ */
+public interface RemoteOperationTxProcessor {
+
+    /**
+     * Delete node in particular data-store in path
+     * @param store data-store type
+     * @param path unique identifier of a particular node instance in the data tree
+     */
+    void doDelete(LogicalDatastoreType store, YangInstanceIdentifier path);
+
+    /**
+     * Commit opened transaction.
+     * @param recipient recipient of submit result
+     * @param sender sender of submit result
+     */
+    void doSubmit(ActorRef recipient, ActorRef sender);
+
+    /**
+     * Cancel operation
+     * @param recipient recipient of cancel result
+     * @param sender sender of cancel result
+     */
+    void doCancel(ActorRef recipient, ActorRef sender);
+
+    /**
+     * Put data to particular data-store
+     * @param store data-store type
+     * @param data data for inserting included in NormalizedNodeMessage object
+     */
+    void doPut(LogicalDatastoreType store, NormalizedNodeMessage data);
+
+    /**
+     * Merge data with existing node in particular data-store
+     * @param store data-store type
+     * @param data data for merging included in NormalizedNodeMessage object
+     */
+    void doMerge(LogicalDatastoreType store, NormalizedNodeMessage data);
+
+    /**
+     * Read data from particular data-store
+     * @param store data-store type
+     * @param path unique identifier of a particular node instance in the data tree
+     * @param recipient recipient of read result
+     * @param sender sender of read result
+     */
+    void doRead(LogicalDatastoreType store, YangInstanceIdentifier path, ActorRef recipient, ActorRef sender);
+
+    /**
+     * Test existence of node in certain data-store
+     * @param store data-store type
+     * @param path unique identifier of a particular node instance in the data tree
+     * @param recipient recipient of exists result
+     * @param sender sender of exists result
+     */
+    void doExists(LogicalDatastoreType store, YangInstanceIdentifier path, ActorRef recipient, ActorRef sender);
+
+}
diff --git a/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/MasterSalFacade.java b/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/MasterSalFacade.java
new file mode 100644 (file)
index 0000000..8e45cbc
--- /dev/null
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.topology.singleton.impl;
+
+import akka.actor.ActorRef;
+import akka.actor.ActorSystem;
+import akka.cluster.Cluster;
+import akka.dispatch.OnComplete;
+import akka.pattern.Patterns;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import java.util.List;
+import java.util.stream.Collectors;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+import org.opendaylight.controller.md.sal.dom.api.DOMNotification;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
+import org.opendaylight.controller.sal.core.api.Broker;
+import org.opendaylight.netconf.sal.connect.api.RemoteDeviceHandler;
+import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfDeviceCapabilities;
+import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences;
+import org.opendaylight.netconf.sal.connect.netconf.sal.NetconfDeviceNotificationService;
+import org.opendaylight.netconf.sal.connect.netconf.sal.NetconfDeviceSalProvider;
+import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
+import org.opendaylight.netconf.topology.singleton.api.NetconfDOMTransaction;
+import org.opendaylight.netconf.topology.singleton.impl.tx.NetconfMasterDOMTransaction;
+import org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologyUtils;
+import org.opendaylight.netconf.topology.singleton.messages.CreateInitialMasterActorData;
+import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.repo.api.RevisionSourceIdentifier;
+import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import scala.concurrent.Future;
+
+class MasterSalFacade implements AutoCloseable, RemoteDeviceHandler<NetconfSessionPreferences> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(MasterSalFacade.class);
+
+    private final RemoteDeviceId id;
+
+    private SchemaContext remoteSchemaContext = null;
+    private NetconfSessionPreferences netconfSessionPreferences = null;
+    private DOMRpcService deviceRpc = null;
+    private final NetconfDeviceSalProvider salProvider;
+
+    private final ActorRef masterActorRef;
+    private final ActorSystem actorSystem;
+    private DOMDataBroker deviceDataBroker = null;
+
+    MasterSalFacade(final RemoteDeviceId id,
+                           final Broker domBroker,
+                           final BindingAwareBroker bindingBroker,
+                           final ActorSystem actorSystem,
+                           final ActorRef masterActorRef) {
+        this.id = id;
+        this.salProvider = new NetconfDeviceSalProvider(id);
+        this.actorSystem = actorSystem;
+        this.masterActorRef = masterActorRef;
+
+        registerToSal(domBroker, bindingBroker);
+    }
+
+    private void registerToSal(final Broker domRegistryDependency, final BindingAwareBroker bindingBroker) {
+        // TODO: remove use of provider, there is possible directly create mount instance and
+        // TODO: NetconfDeviceTopologyAdapter in constructor = less complexity
+
+        domRegistryDependency.registerProvider(salProvider);
+        bindingBroker.registerProvider(salProvider);
+    }
+
+    @Override
+    public void onDeviceConnected(final SchemaContext remoteSchemaContext,
+                                  final NetconfSessionPreferences netconfSessionPreferences,
+                                  final DOMRpcService deviceRpc) {
+        this.remoteSchemaContext = remoteSchemaContext;
+        this.netconfSessionPreferences = netconfSessionPreferences;
+        this.deviceRpc = deviceRpc;
+
+        registerMasterMountPoint();
+
+        sendInitialDataToActor().onComplete(new OnComplete<Object>() {
+            @Override
+            public void onComplete(final Throwable failure, final Object success) throws Throwable {
+                if (failure == null) {
+                    updateDeviceData();
+                    return;
+                }
+                throw failure;
+            }
+        }, actorSystem.dispatcher());
+
+    }
+
+    @Override
+    public void onDeviceDisconnected() {
+        salProvider.getTopologyDatastoreAdapter().updateDeviceData(false, new NetconfDeviceCapabilities());
+        unregisterMasterMountPoint();
+    }
+
+    @Override
+    public void onDeviceFailed(final Throwable throwable) {
+        salProvider.getTopologyDatastoreAdapter().setDeviceAsFailed(throwable);
+        unregisterMasterMountPoint();
+    }
+
+    @Override
+    public void onNotification(final DOMNotification domNotification) {
+        salProvider.getMountInstance().publish(domNotification);
+    }
+
+    @Override
+    public void close() {
+        unregisterMasterMountPoint();
+        closeGracefully(salProvider);
+    }
+
+    private void registerMasterMountPoint() {
+        Preconditions.checkNotNull(id);
+        Preconditions.checkNotNull(remoteSchemaContext,
+                "Device has no remote schema context yet. Probably not fully connected.");
+        Preconditions.checkNotNull(netconfSessionPreferences,
+                "Device has no capabilities yet. Probably not fully connected.");
+
+        final NetconfDeviceNotificationService notificationService = new NetconfDeviceNotificationService();
+
+        LOG.info("{}: Creating master data broker for device", id);
+
+        final NetconfDOMTransaction masterDOMTransactions =
+                new NetconfMasterDOMTransaction(id, remoteSchemaContext, deviceRpc, netconfSessionPreferences);
+        deviceDataBroker =
+                new NetconfDOMDataBroker(actorSystem, id, masterDOMTransactions);
+        salProvider.getMountInstance()
+                .onTopologyDeviceConnected(remoteSchemaContext, deviceDataBroker, deviceRpc, notificationService);
+    }
+
+    private Future<Object> sendInitialDataToActor() {
+        final List<SourceIdentifier> sourceIdentifiers =
+                remoteSchemaContext.getAllModuleIdentifiers().stream().map(mi ->
+                        RevisionSourceIdentifier.create(mi.getName(),
+                            (SimpleDateFormatUtil.DEFAULT_DATE_REV == mi.getRevision() ? Optional.<String>absent() :
+                                    Optional.of(SimpleDateFormatUtil.getRevisionFormat().format(mi.getRevision())))))
+                        .collect(Collectors.toList());
+
+        // send initial data to master actor and create actor for providing it
+        return Patterns.ask(masterActorRef, new CreateInitialMasterActorData(deviceDataBroker, sourceIdentifiers),
+                NetconfTopologyUtils.TIMEOUT);
+    }
+
+    private void updateDeviceData() {
+        Cluster cluster = Cluster.get(actorSystem);
+        salProvider.getTopologyDatastoreAdapter().updateClusteredDeviceData(true, cluster.selfAddress().toString(),
+                netconfSessionPreferences.getNetconfDeviceCapabilities());
+    }
+
+    private void unregisterMasterMountPoint() {
+        salProvider.getMountInstance().onTopologyDeviceDisconnected();
+    }
+
+    private void closeGracefully(final AutoCloseable resource) {
+        if (resource != null) {
+            try {
+                resource.close();
+            } catch (final Exception e) {
+                LOG.error("{}: Ignoring exception while closing {}", id, resource, e);
+            }
+        }
+    }
+
+}
@@ -6,7 +6,7 @@
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
 
-package org.opendaylight.netconf.topology.pipeline;
+package org.opendaylight.netconf.topology.singleton.impl;
 
 import akka.actor.ActorSystem;
 import java.util.Collections;
@@ -23,18 +23,20 @@ import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
 import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
 import org.opendaylight.netconf.sal.connect.netconf.sal.tx.ReadWriteTx;
 import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
-import org.opendaylight.netconf.topology.pipeline.tx.ProxyReadOnlyTransaction;
-import org.opendaylight.netconf.topology.pipeline.tx.ProxyWriteOnlyTransaction;
+import org.opendaylight.netconf.topology.singleton.api.NetconfDOMTransaction;
+import org.opendaylight.netconf.topology.singleton.impl.tx.NetconfReadOnlyTransaction;
+import org.opendaylight.netconf.topology.singleton.impl.tx.NetconfWriteOnlyTransaction;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 
-public class NetconfDeviceSlaveDataBroker implements DOMDataBroker{
+public class NetconfDOMDataBroker implements DOMDataBroker {
 
     private final RemoteDeviceId id;
-    private final ProxyNetconfDeviceDataBroker masterDataBroker;
+    private final NetconfDOMTransaction masterDataBroker;
     private final ActorSystem actorSystem;
 
-    public NetconfDeviceSlaveDataBroker(final ActorSystem actorSystem, final RemoteDeviceId id, final ProxyNetconfDeviceDataBroker masterDataBroker) {
+    public NetconfDOMDataBroker(final ActorSystem actorSystem, final RemoteDeviceId id,
+                         final NetconfDOMTransaction masterDataBroker) {
         this.id = id;
         this.masterDataBroker = masterDataBroker;
         this.actorSystem = actorSystem;
@@ -42,21 +44,24 @@ public class NetconfDeviceSlaveDataBroker implements DOMDataBroker{
 
     @Override
     public DOMDataReadOnlyTransaction newReadOnlyTransaction() {
-        return new ProxyReadOnlyTransaction(actorSystem, id, masterDataBroker);
+        return new NetconfReadOnlyTransaction(id, actorSystem, masterDataBroker);
     }
 
     @Override
     public DOMDataReadWriteTransaction newReadWriteTransaction() {
-        return new ReadWriteTx(new ProxyReadOnlyTransaction(actorSystem, id, masterDataBroker), new ProxyWriteOnlyTransaction(actorSystem, masterDataBroker));
+        return new ReadWriteTx(new NetconfReadOnlyTransaction(id, actorSystem, masterDataBroker),
+                new NetconfWriteOnlyTransaction(id, actorSystem, masterDataBroker));
     }
 
     @Override
     public DOMDataWriteTransaction newWriteOnlyTransaction() {
-        return new ProxyWriteOnlyTransaction(actorSystem, masterDataBroker);
+        return new NetconfWriteOnlyTransaction(id, actorSystem, masterDataBroker);
     }
 
     @Override
-    public ListenerRegistration<DOMDataChangeListener> registerDataChangeListener(LogicalDatastoreType store, YangInstanceIdentifier path, DOMDataChangeListener listener, DataChangeScope triggeringScope) {
+    public ListenerRegistration<DOMDataChangeListener> registerDataChangeListener(
+            LogicalDatastoreType store, YangInstanceIdentifier path, DOMDataChangeListener listener,
+            DataChangeScope triggeringScope) {
         throw new UnsupportedOperationException(id + ": Data change listeners not supported for netconf mount point");
     }
 
diff --git a/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/NetconfNodeManager.java b/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/NetconfNodeManager.java
new file mode 100644 (file)
index 0000000..7cc3d29
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.topology.singleton.impl;
+
+import akka.actor.ActorRef;
+import akka.actor.PoisonPill;
+import java.util.Collection;
+import javax.annotation.Nonnull;
+import org.opendaylight.controller.md.sal.binding.api.ClusteredDataTreeChangeListener;
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
+import org.opendaylight.netconf.topology.singleton.api.NetconfTopologySingletonService;
+import org.opendaylight.netconf.topology.singleton.impl.actors.NetconfNodeActor;
+import org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologySetup;
+import org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologyUtils;
+import org.opendaylight.netconf.topology.singleton.messages.AskForMasterMountPoint;
+import org.opendaylight.netconf.topology.singleton.messages.UnregisterSlaveMountPoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.model.repo.api.SchemaRepository;
+import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceRegistry;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Managing and reacting on data tree changes in specific netconf node when master writes status to the operational
+ * data store (e.g. handling lifecycle of slave mount point).
+ */
+class NetconfNodeManager
+        implements ClusteredDataTreeChangeListener<Node>, NetconfTopologySingletonService, AutoCloseable {
+
+    private static final Logger LOG = LoggerFactory.getLogger(NetconfNodeManager.class);
+
+    private NetconfTopologySetup setup;
+    private ListenerRegistration<NetconfNodeManager> dataChangeListenerRegistration;
+    private RemoteDeviceId id;
+    private final SchemaSourceRegistry schemaRegistry;
+    private final SchemaRepository schemaRepository;
+    private ActorRef slaveActorRef;
+
+    NetconfNodeManager(final NetconfTopologySetup setup,
+                       final RemoteDeviceId id, final SchemaSourceRegistry schemaRegistry,
+                       final SchemaRepository schemaRepository) {
+        this.setup = setup;
+        this.id = id;
+        this.schemaRegistry = schemaRegistry;
+        this.schemaRepository = schemaRepository;
+    }
+
+    @Override
+    public void onDataTreeChanged(@Nonnull final Collection<DataTreeModification<Node>> changes) {
+        for (final DataTreeModification<Node> change : changes) {
+            final DataObjectModification<Node> rootNode = change.getRootNode();
+            final NodeId nodeId = NetconfTopologyUtils.getNodeId(rootNode.getIdentifier());
+            switch (rootNode.getModificationType()) {
+                case SUBTREE_MODIFIED:
+                    LOG.debug("{}: Operational for node {} updated. Trying to register slave mount point", id, nodeId);
+                    handleSlaveMountPoint(rootNode);
+                    break;
+                case WRITE:
+                    if (rootNode.getDataBefore() != null) {
+                        LOG.debug("{}: Operational for node {} rewrited. Trying to register slave mount point", id, nodeId);
+                    } else {
+                        LOG.debug("{}: Operational for node {} created. Trying to register slave mount point", id, nodeId);
+                    }
+                    handleSlaveMountPoint(rootNode);
+                    break;
+                case DELETE:
+                    LOG.debug("{}: Operational for node {} deleted. Trying to remove slave mount point", id, nodeId);
+                    closeActor();
+                    break;
+                default:
+                    LOG.debug("{}: Uknown operation for node: {}", id, nodeId);
+            }
+        }
+    }
+
+    @Override
+    public void close() {
+        closeActor();
+
+        if (dataChangeListenerRegistration != null) {
+            dataChangeListenerRegistration.close();
+            dataChangeListenerRegistration = null;
+        }
+    }
+
+    private void closeActor() {
+        if (slaveActorRef != null) {
+            slaveActorRef.tell(new UnregisterSlaveMountPoint(), ActorRef.noSender());
+            slaveActorRef.tell(PoisonPill.getInstance(), ActorRef.noSender());
+            slaveActorRef = null;
+        }
+    }
+
+    void registerDataTreeChangeListener(final String topologyId, final NodeKey key) {
+        LOG.debug("{}: Registering data tree change listener on node {}", id, key);
+        dataChangeListenerRegistration = setup.getDataBroker().registerDataTreeChangeListener(
+                new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL,
+                        NetconfTopologyUtils.createTopologyNodeListPath(key, topologyId)), this);
+    }
+
+    private void handleSlaveMountPoint(final DataObjectModification<Node> rootNode) {
+        @SuppressWarnings("ConstantConditions")
+        final NetconfNode netconfNodeAfter = rootNode.getDataAfter().getAugmentation(NetconfNode.class);
+
+        if (NetconfNodeConnectionStatus.ConnectionStatus.Connected.equals(netconfNodeAfter.getConnectionStatus())) {
+            createActorRef();
+            final String masterAddress = netconfNodeAfter.getClusteredConnectionStatus().getNetconfMasterNode();
+            final String path = NetconfTopologyUtils.createActorPath(masterAddress,
+                    NetconfTopologyUtils.createMasterActorName(id.getName(),
+                            netconfNodeAfter.getClusteredConnectionStatus().getNetconfMasterNode()));
+            setup.getActorSystem().actorSelection(path).tell(new AskForMasterMountPoint(), slaveActorRef);
+        } else {            ;
+            closeActor();
+        }
+    }
+
+    private void createActorRef() {
+        if (slaveActorRef == null) {
+            slaveActorRef = setup.getActorSystem().actorOf(NetconfNodeActor.props(setup, id, schemaRegistry,
+                    schemaRepository), id.getName());
+        }
+    }
+
+    void refreshDevice(final NetconfTopologySetup netconfTopologyDeviceSetup, final RemoteDeviceId remoteDeviceId) {
+        setup = netconfTopologyDeviceSetup;
+        id = remoteDeviceId;
+    }
+}
diff --git a/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/NetconfTopologyContext.java b/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/NetconfTopologyContext.java
new file mode 100644 (file)
index 0000000..0f8255c
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.topology.singleton.impl;
+
+import static org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologyUtils.DEFAULT_SCHEMA_REPOSITORY;
+
+import akka.actor.ActorRef;
+import akka.cluster.Cluster;
+import akka.dispatch.OnComplete;
+import akka.pattern.Patterns;
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import javax.annotation.Nonnull;
+import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService;
+import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier;
+import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
+import org.opendaylight.netconf.topology.singleton.api.RemoteDeviceConnector;
+import org.opendaylight.netconf.topology.singleton.impl.actors.NetconfNodeActor;
+import org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologySetup;
+import org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologyUtils;
+import org.opendaylight.netconf.topology.singleton.messages.RefreshSetupMasterActorData;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import scala.concurrent.Future;
+
+class NetconfTopologyContext implements ClusterSingletonService {
+
+    private static final Logger LOG = LoggerFactory.getLogger(NetconfTopologyContext.class);
+
+    private final ServiceGroupIdentifier serviceGroupIdent;
+    private NetconfTopologySetup netconfTopologyDeviceSetup;
+    private RemoteDeviceId remoteDeviceId;
+    private RemoteDeviceConnector remoteDeviceConnector;
+    private NetconfNodeManager netconfNodeManager;
+    private boolean finalClose = false;
+    private boolean isMaster;
+
+    private ActorRef masterActorRef;
+
+    NetconfTopologyContext(final NetconfTopologySetup netconfTopologyDeviceSetup,
+                           final ServiceGroupIdentifier serviceGroupIdent) {
+        this.netconfTopologyDeviceSetup = Preconditions.checkNotNull(netconfTopologyDeviceSetup);
+        this.serviceGroupIdent = serviceGroupIdent;
+
+        remoteDeviceId = NetconfTopologyUtils.createRemoteDeviceId(netconfTopologyDeviceSetup.getNode().getNodeId(),
+                netconfTopologyDeviceSetup.getNode().getAugmentation(NetconfNode.class));
+
+        remoteDeviceConnector = new RemoteDeviceConnectorImpl(netconfTopologyDeviceSetup, remoteDeviceId);
+
+        netconfNodeManager = createNodeDeviceManager();
+
+    }
+
+    @Override
+    public void instantiateServiceInstance() {
+        LOG.info("Master was selected: {}", remoteDeviceId.getHost().getIpAddress());
+
+        isMaster = true;
+
+        // master should not listen on netconf-node operational datastore
+        if (netconfNodeManager != null) {
+            netconfNodeManager.close();
+            netconfNodeManager = null;
+        }
+
+        if (!finalClose) {
+            final String masterAddress = Cluster.get(netconfTopologyDeviceSetup.getActorSystem()).selfAddress().toString();
+            masterActorRef = netconfTopologyDeviceSetup.getActorSystem().actorOf(NetconfNodeActor.props(
+                    netconfTopologyDeviceSetup, remoteDeviceId, DEFAULT_SCHEMA_REPOSITORY, DEFAULT_SCHEMA_REPOSITORY),
+                    NetconfTopologyUtils.createMasterActorName(remoteDeviceId.getName(), masterAddress));
+
+            remoteDeviceConnector.startRemoteDeviceConnection(masterActorRef);
+        }
+
+    }
+
+    // called when master is down/changed to slave
+    @Override
+    public ListenableFuture<Void> closeServiceInstance() {
+
+        if (!finalClose) {
+            // in case that master changes role to slave, new NodeDeviceManager must be created and listener registered
+            netconfNodeManager = createNodeDeviceManager();
+        }
+        if (masterActorRef != null) {
+            netconfTopologyDeviceSetup.getActorSystem().stop(masterActorRef);
+            masterActorRef = null;
+        }
+        if (remoteDeviceConnector != null) {
+            remoteDeviceConnector.stopRemoteDeviceConnection();
+        }
+
+        return Futures.immediateCheckedFuture(null);
+    }
+
+    @Override
+    public ServiceGroupIdentifier getIdentifier() {
+        return serviceGroupIdent;
+    }
+
+    private NetconfNodeManager createNodeDeviceManager() {
+        final NetconfNodeManager ndm =
+                new NetconfNodeManager(netconfTopologyDeviceSetup, remoteDeviceId, DEFAULT_SCHEMA_REPOSITORY,
+                        DEFAULT_SCHEMA_REPOSITORY);
+        ndm.registerDataTreeChangeListener(netconfTopologyDeviceSetup.getTopologyId(),
+                netconfTopologyDeviceSetup.getNode().getKey());
+
+        return ndm;
+    }
+
+    void closeFinal() throws Exception {
+        finalClose = true;
+
+        if (netconfNodeManager != null) {
+            netconfNodeManager.close();
+        }
+
+        if (remoteDeviceConnector != null) {
+            remoteDeviceConnector.stopRemoteDeviceConnection();
+        }
+
+        if (masterActorRef != null) {
+            netconfTopologyDeviceSetup.getActorSystem().stop(masterActorRef);
+            masterActorRef = null;
+        }
+    }
+
+    /**
+     * If configuration data was changed
+     * @param setup new setup
+     */
+    void refresh(@Nonnull final NetconfTopologySetup setup) {
+        netconfTopologyDeviceSetup = Preconditions.checkNotNull(setup);
+        remoteDeviceId = NetconfTopologyUtils.createRemoteDeviceId(netconfTopologyDeviceSetup.getNode().getNodeId(),
+                netconfTopologyDeviceSetup.getNode().getAugmentation(NetconfNode.class));
+
+        if (isMaster) {
+            remoteDeviceConnector.stopRemoteDeviceConnection();
+        }
+        if (!isMaster) {
+            netconfNodeManager.refreshDevice(netconfTopologyDeviceSetup, remoteDeviceId);
+        }
+        remoteDeviceConnector = new RemoteDeviceConnectorImpl(netconfTopologyDeviceSetup, remoteDeviceId);
+
+        if (isMaster) {
+            final Future<Object> future = Patterns.ask(masterActorRef, new RefreshSetupMasterActorData(
+                    netconfTopologyDeviceSetup, remoteDeviceId), NetconfTopologyUtils.TIMEOUT);
+
+            future.onComplete(new OnComplete<Object>() {
+                @Override
+                public void onComplete(final Throwable failure, final Object success) throws Throwable {
+                    if (failure != null) {
+                        LOG.error("Failed to refresh master actor data: {}", failure);
+                        return;
+                    }
+                    remoteDeviceConnector.startRemoteDeviceConnection(masterActorRef);
+                }
+            }, netconfTopologyDeviceSetup.getActorSystem().dispatcher());
+        }
+    }
+}
diff --git a/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/NetconfTopologyManager.java b/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/NetconfTopologyManager.java
new file mode 100644 (file)
index 0000000..cfd9dd8
--- /dev/null
@@ -0,0 +1,243 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.topology.singleton.impl;
+
+import akka.actor.ActorSystem;
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import io.netty.util.concurrent.EventExecutor;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import javax.annotation.Nonnull;
+import org.opendaylight.controller.cluster.ActorSystemProvider;
+import org.opendaylight.controller.config.threadpool.ScheduledThreadPool;
+import org.opendaylight.controller.config.threadpool.ThreadPool;
+import org.opendaylight.controller.md.sal.binding.api.ClusteredDataTreeChangeListener;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.controller.sal.core.api.Broker;
+import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
+import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration;
+import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier;
+import org.opendaylight.netconf.client.NetconfClientDispatcher;
+import org.opendaylight.netconf.topology.singleton.api.NetconfTopologySingletonService;
+import org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologySetup;
+import org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologySetup.NetconfTopologySetupBuilder;
+import org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologyUtils;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopologyBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NetconfTopologyManager
+        implements ClusteredDataTreeChangeListener<Node>, NetconfTopologySingletonService, AutoCloseable {
+
+    private static final Logger LOG = LoggerFactory.getLogger(NetconfTopologyManager.class);
+
+    private final Map<InstanceIdentifier<Node>, NetconfTopologyContext> contexts = new HashMap<>();
+    private final Map<InstanceIdentifier<Node>, ClusterSingletonServiceRegistration>
+            clusterRegistrations = new HashMap<>();
+
+    private ListenerRegistration<NetconfTopologyManager> dataChangeListenerRegistration;
+
+    private final DataBroker dataBroker;
+    private final RpcProviderRegistry rpcProviderRegistry;
+    private final ClusterSingletonServiceProvider clusterSingletonServiceProvider;
+    private final BindingAwareBroker bindingAwareBroker;
+    private final ScheduledThreadPool keepaliveExecutor;
+    private final ThreadPool processingExecutor;
+    private final Broker domBroker;
+    private final ActorSystem actorSystem;
+    private final EventExecutor eventExecutor;
+    private final NetconfClientDispatcher clientDispatcher;
+    private final String topologyId;
+
+    public NetconfTopologyManager(final DataBroker dataBroker, final RpcProviderRegistry rpcProviderRegistry,
+                           final ClusterSingletonServiceProvider clusterSingletonServiceProvider,
+                           final BindingAwareBroker bindingAwareBroker,
+                           final ScheduledThreadPool keepaliveExecutor, final ThreadPool processingExecutor,
+                           final Broker domBroker, final ActorSystemProvider actorSystemProvider, final EventExecutor eventExecutor,
+                           final NetconfClientDispatcher clientDispatcher, final String topologyId) {
+        this.dataBroker = Preconditions.checkNotNull(dataBroker);
+        this.rpcProviderRegistry = Preconditions.checkNotNull(rpcProviderRegistry);
+        this.clusterSingletonServiceProvider = Preconditions.checkNotNull(clusterSingletonServiceProvider);
+        this.bindingAwareBroker = Preconditions.checkNotNull(bindingAwareBroker);
+        this.keepaliveExecutor = Preconditions.checkNotNull(keepaliveExecutor);
+        this.processingExecutor = Preconditions.checkNotNull(processingExecutor);
+        this.domBroker = Preconditions.checkNotNull(domBroker);
+        this.actorSystem = Preconditions.checkNotNull(actorSystemProvider).getActorSystem();
+        this.eventExecutor = Preconditions.checkNotNull(eventExecutor);
+        this.clientDispatcher = Preconditions.checkNotNull(clientDispatcher);
+        this.topologyId = Preconditions.checkNotNull(topologyId);
+    }
+
+    // Blueprint init method
+    public void init() {
+        dataChangeListenerRegistration = registerDataTreeChangeListener(topologyId);
+    }
+
+    @Override
+    public void onDataTreeChanged(@Nonnull final Collection<DataTreeModification<Node>> changes) {
+        for (DataTreeModification<Node> change : changes) {
+            final DataObjectModification<Node> rootNode = change.getRootNode();
+            final InstanceIdentifier<Node> dataModifIdent = change.getRootPath().getRootIdentifier();
+            final NodeId nodeId = NetconfTopologyUtils.getNodeId(rootNode.getIdentifier());
+            switch (rootNode.getModificationType()) {
+                case SUBTREE_MODIFIED:
+                    LOG.debug("Config for node {} updated", nodeId);
+                    refreshNetconfDeviceContext(dataModifIdent, rootNode.getDataAfter());
+                    break;
+                case WRITE:
+                    if (contexts.containsKey(dataModifIdent)) {
+                        LOG.debug("RemoteDevice{{}} was already configured, reconfiguring node...", nodeId);
+                        refreshNetconfDeviceContext(dataModifIdent, rootNode.getDataAfter());
+                    } else {
+                        LOG.debug("Config for node {} created", nodeId);
+                        startNetconfDeviceContext(dataModifIdent, rootNode.getDataAfter());
+                    }
+                    break;
+                case DELETE:
+                    LOG.debug("Config for node {} deleted", nodeId);
+                    stopNetconfDeviceContext(dataModifIdent);
+                    break;
+                default:
+                    LOG.warn("Unknown operation for {}.", nodeId);
+            }
+        }
+    }
+
+    private void refreshNetconfDeviceContext(InstanceIdentifier<Node> instanceIdentifier, Node node) {
+        final NetconfTopologyContext context = contexts.get(instanceIdentifier);
+        context.refresh(createSetup(instanceIdentifier, node));
+    }
+
+    private void startNetconfDeviceContext(final InstanceIdentifier<Node> instanceIdentifier, final Node node) {
+        final NetconfNode netconfNode = node.getAugmentation(NetconfNode.class);
+        Preconditions.checkNotNull(netconfNode);
+        Preconditions.checkNotNull(netconfNode.getHost());
+        Preconditions.checkNotNull(netconfNode.getHost().getIpAddress());
+
+        final ServiceGroupIdentifier serviceGroupIdent =
+                ServiceGroupIdentifier.create(instanceIdentifier.toString());
+
+        final NetconfTopologyContext newNetconfTopologyContext =
+                new NetconfTopologyContext(createSetup(instanceIdentifier, node), serviceGroupIdent);
+
+        final ClusterSingletonServiceRegistration clusterSingletonServiceRegistration  =
+                clusterSingletonServiceProvider.registerClusterSingletonService(newNetconfTopologyContext);
+
+        clusterRegistrations.put(instanceIdentifier, clusterSingletonServiceRegistration);
+        contexts.put(instanceIdentifier, newNetconfTopologyContext);
+    }
+
+    private void stopNetconfDeviceContext(final InstanceIdentifier<Node> instanceIdentifier) {
+        if (contexts.containsKey(instanceIdentifier)) {
+            try {
+                clusterRegistrations.get(instanceIdentifier).close();
+                contexts.get(instanceIdentifier).closeFinal();
+            } catch (Exception e) {
+                LOG.warn("Error at closing topology context. InstanceIdentifier: " + instanceIdentifier);
+            }
+            contexts.remove(instanceIdentifier);
+            clusterRegistrations.remove(instanceIdentifier);
+        }
+    }
+
+    @Override
+    public void close() {
+        if (dataChangeListenerRegistration != null) {
+            dataChangeListenerRegistration.close();
+            dataChangeListenerRegistration = null;
+        }
+        contexts.forEach((instanceIdentifier, netconfTopologyContext) -> {
+            try {
+                netconfTopologyContext.closeFinal();
+            } catch (Exception e) {
+                LOG.error("Error at closing topology context. InstanceIdentifier: " + instanceIdentifier, e);
+            }
+        });
+        clusterRegistrations.forEach((instanceIdentifier, clusterSingletonServiceRegistration) -> {
+            try {
+                clusterSingletonServiceRegistration.close();
+            } catch (Exception e) {
+                LOG.error("Error at unregistering from cluster. InstanceIdentifier: " + instanceIdentifier, e);
+            }
+        });
+        contexts.clear();
+        clusterRegistrations.clear();
+    }
+
+    private ListenerRegistration<NetconfTopologyManager> registerDataTreeChangeListener(String topologyId) {
+        final WriteTransaction wtx = dataBroker.newWriteOnlyTransaction();
+        initTopology(wtx, LogicalDatastoreType.CONFIGURATION, topologyId);
+        initTopology(wtx, LogicalDatastoreType.OPERATIONAL, topologyId);
+        Futures.addCallback(wtx.submit(), new FutureCallback<Void>() {
+            @Override
+            public void onSuccess(Void result) {
+                LOG.debug("topology initialization successful");
+            }
+
+            @Override
+            public void onFailure(@Nonnull Throwable throwable) {
+                LOG.error("Unable to initialize netconf-topology, {}", throwable);
+            }
+        });
+
+        LOG.debug("Registering datastore listener");
+        return dataBroker.registerDataTreeChangeListener(
+                        new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION,
+                                NetconfTopologyUtils.createTopologyListPath(topologyId).child(Node.class)), this);
+    }
+
+    private void initTopology(final WriteTransaction wtx, final LogicalDatastoreType datastoreType, String topologyId) {
+        final NetworkTopology networkTopology = new NetworkTopologyBuilder().build();
+        final InstanceIdentifier<NetworkTopology> networkTopologyId =
+                InstanceIdentifier.builder(NetworkTopology.class).build();
+        wtx.merge(datastoreType, networkTopologyId, networkTopology);
+        final Topology topology = new TopologyBuilder().setTopologyId(new TopologyId(topologyId)).build();
+        wtx.merge(datastoreType, networkTopologyId.child(Topology.class,
+                new TopologyKey(new TopologyId(topologyId))), topology);
+    }
+
+    private NetconfTopologySetup createSetup(final InstanceIdentifier<Node> instanceIdentifier, final Node node) {
+        final NetconfTopologySetupBuilder builder = NetconfTopologySetupBuilder.create()
+                .setClusterSingletonServiceProvider(clusterSingletonServiceProvider)
+                .setDataBroker(dataBroker)
+                .setInstanceIdentifier(instanceIdentifier)
+                .setRpcProviderRegistry(rpcProviderRegistry)
+                .setNode(node)
+                .setBindingAwareBroker(bindingAwareBroker)
+                .setActorSystem(actorSystem)
+                .setEventExecutor(eventExecutor)
+                .setDomBroker(domBroker)
+                .setKeepaliveExecutor(keepaliveExecutor)
+                .setProcessingExecutor(processingExecutor)
+                .setTopologyId(topologyId)
+                .setNetconfClientDispatcher(clientDispatcher);
+
+        return builder.build();
+    }
+}
diff --git a/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/ProxyDOMRpcService.java b/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/ProxyDOMRpcService.java
new file mode 100644 (file)
index 0000000..c1c8430
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.topology.singleton.impl;
+
+import com.google.common.util.concurrent.CheckedFuture;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcAvailabilityListener;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcException;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+
+public class ProxyDOMRpcService implements DOMRpcService {
+
+    @Nonnull
+    @Override
+    public CheckedFuture<DOMRpcResult, DOMRpcException> invokeRpc(@Nonnull final SchemaPath type,
+                                                                  @Nullable final NormalizedNode<?, ?> input) {
+        throw new UnsupportedOperationException("InvokeRpc: DOMRpc service not working in cluster.");
+    }
+
+    @Nonnull
+    @Override
+    public <T extends DOMRpcAvailabilityListener> ListenerRegistration<T> registerRpcListener(
+            @Nonnull final T listener) {
+        throw new UnsupportedOperationException("RegisterRpcListener: DOMRpc service not working in cluster.");
+    }
+}
diff --git a/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/ProxyYangTextSourceProvider.java b/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/ProxyYangTextSourceProvider.java
new file mode 100644 (file)
index 0000000..27514c7
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.topology.singleton.impl;
+
+import akka.actor.ActorContext;
+import akka.actor.ActorRef;
+import akka.dispatch.Futures;
+import akka.dispatch.OnComplete;
+import akka.pattern.Patterns;
+import com.google.common.collect.Sets;
+import java.util.Set;
+import javax.annotation.Nonnull;
+import org.opendaylight.controller.cluster.schema.provider.RemoteYangTextSourceProvider;
+import org.opendaylight.controller.cluster.schema.provider.impl.YangTextSchemaSourceSerializationProxy;
+import org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologyUtils;
+import org.opendaylight.netconf.topology.singleton.messages.YangTextSchemaSourceRequest;
+import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
+import scala.concurrent.Future;
+import scala.concurrent.impl.Promise;
+
+public class ProxyYangTextSourceProvider implements RemoteYangTextSourceProvider {
+
+    private final ActorRef masterRef;
+    private final ActorContext actorContext;
+
+    public ProxyYangTextSourceProvider(final ActorRef masterRef, final ActorContext actorContext) {
+        this.masterRef = masterRef;
+        this.actorContext = actorContext;
+    }
+
+    @Override
+    public Future<Set<SourceIdentifier>> getProvidedSources() {
+        // NOOP
+        return Futures.successful(Sets.newHashSet());
+    }
+
+    @Override
+    public Future<YangTextSchemaSourceSerializationProxy> getYangTextSchemaSource(
+            @Nonnull final SourceIdentifier sourceIdentifier) {
+
+        final Future<Object> scalaFuture = Patterns.ask(masterRef,
+                new YangTextSchemaSourceRequest(sourceIdentifier), NetconfTopologyUtils.TIMEOUT);
+
+        final Promise.DefaultPromise<YangTextSchemaSourceSerializationProxy> promise = new Promise.DefaultPromise<>();
+
+        scalaFuture.onComplete(new OnComplete<Object>() {
+            @Override
+            public void onComplete(final Throwable failure, final Object success) throws Throwable {
+                if (failure != null) {
+                    promise.failure(failure);
+                    return;
+                }
+                if (success instanceof Throwable) {
+                    promise.failure((Throwable) success);
+                    return;
+                }
+                promise.success((YangTextSchemaSourceSerializationProxy) success);
+            }
+        }, actorContext.dispatcher());
+
+        return promise.future();
+
+    }
+}
diff --git a/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/RemoteDeviceConnectorImpl.java b/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/RemoteDeviceConnectorImpl.java
new file mode 100644 (file)
index 0000000..0525789
--- /dev/null
@@ -0,0 +1,425 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.topology.singleton.impl;
+
+import akka.actor.ActorRef;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
+import com.google.common.collect.Lists;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import io.netty.util.concurrent.EventExecutor;
+import java.io.File;
+import java.math.BigDecimal;
+import java.net.InetSocketAddress;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import javax.annotation.Nullable;
+import org.opendaylight.netconf.api.NetconfMessage;
+import org.opendaylight.netconf.client.NetconfClientSessionListener;
+import org.opendaylight.netconf.client.conf.NetconfClientConfiguration;
+import org.opendaylight.netconf.client.conf.NetconfReconnectingClientConfiguration;
+import org.opendaylight.netconf.client.conf.NetconfReconnectingClientConfigurationBuilder;
+import org.opendaylight.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
+import org.opendaylight.netconf.nettyutil.handler.ssh.authentication.LoginPassword;
+import org.opendaylight.netconf.sal.connect.api.RemoteDevice;
+import org.opendaylight.netconf.sal.connect.api.RemoteDeviceHandler;
+import org.opendaylight.netconf.sal.connect.netconf.LibraryModulesSchemas;
+import org.opendaylight.netconf.sal.connect.netconf.NetconfDevice;
+import org.opendaylight.netconf.sal.connect.netconf.NetconfDeviceBuilder;
+import org.opendaylight.netconf.sal.connect.netconf.NetconfStateSchemasResolverImpl;
+import org.opendaylight.netconf.sal.connect.netconf.SchemalessNetconfDevice;
+import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfDeviceCapabilities;
+import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfDeviceCommunicator;
+import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences;
+import org.opendaylight.netconf.sal.connect.netconf.listener.UserPreferences;
+import org.opendaylight.netconf.sal.connect.netconf.sal.KeepaliveSalFacade;
+import org.opendaylight.netconf.sal.connect.netconf.schema.YangLibrarySchemaYangSourceProvider;
+import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
+import org.opendaylight.netconf.topology.singleton.api.RemoteDeviceConnector;
+import org.opendaylight.netconf.topology.singleton.impl.utils.NetconfConnectorDTO;
+import org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologySetup;
+import org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologyUtils;
+import org.opendaylight.protocol.framework.ReconnectStrategy;
+import org.opendaylight.protocol.framework.ReconnectStrategyFactory;
+import org.opendaylight.protocol.framework.TimedReconnectStrategy;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Host;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.credentials.Credentials;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
+import org.opendaylight.yangtools.yang.model.repo.api.SchemaContextFactory;
+import org.opendaylight.yangtools.yang.model.repo.api.SchemaRepository;
+import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceFilter;
+import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
+import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
+import org.opendaylight.yangtools.yang.model.repo.spi.PotentialSchemaSource;
+import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceRegistration;
+import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceRegistry;
+import org.opendaylight.yangtools.yang.model.repo.util.FilesystemSchemaSourceCache;
+import org.opendaylight.yangtools.yang.parser.repo.SharedSchemaRepository;
+import org.opendaylight.yangtools.yang.parser.util.TextToASTTransformer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class RemoteDeviceConnectorImpl implements RemoteDeviceConnector {
+
+    private static final Logger LOG = LoggerFactory.getLogger(RemoteDeviceConnectorImpl.class);
+
+    /**
+     * Keeps track of initialized Schema resources.  A Map is maintained in which the key represents the name
+     * of the schema cache directory, and the value is a corresponding <code>SchemaResourcesDTO</code>.  The
+     * <code>SchemaResourcesDTO</code> is essentially a container that allows for the extraction of the
+     * <code>SchemaRegistry</code> and <code>SchemaContextFactory</code> which should be used for a particular
+     * Netconf mount.  Access to <code>schemaResourcesDTOs</code> should be surrounded by appropriate
+     * synchronization locks.
+     */
+    private static final Map<String, NetconfDevice.SchemaResourcesDTO> schemaResourcesDTOs = new HashMap<>();
+
+    private SchemaSourceRegistry schemaRegistry = NetconfTopologyUtils.DEFAULT_SCHEMA_REPOSITORY;
+    private SchemaRepository schemaRepository = NetconfTopologyUtils.DEFAULT_SCHEMA_REPOSITORY;
+
+    private final NetconfTopologySetup netconfTopologyDeviceSetup;
+    private final RemoteDeviceId remoteDeviceId;
+
+    private SchemaContextFactory schemaContextFactory = NetconfTopologyUtils.DEFAULT_SCHEMA_CONTEXT_FACTORY;
+    private NetconfConnectorDTO deviceCommunicatorDTO;
+
+    // Initializes default constant instances for the case when the default schema repository
+    // directory cache/schema is used.
+    static {
+        schemaResourcesDTOs.put(NetconfTopologyUtils.DEFAULT_CACHE_DIRECTORY,
+                new NetconfDevice.SchemaResourcesDTO(NetconfTopologyUtils.DEFAULT_SCHEMA_REPOSITORY,
+                        NetconfTopologyUtils.DEFAULT_SCHEMA_REPOSITORY,
+                        NetconfTopologyUtils.DEFAULT_SCHEMA_CONTEXT_FACTORY,
+                        new NetconfStateSchemasResolverImpl()));
+        NetconfTopologyUtils.DEFAULT_SCHEMA_REPOSITORY.registerSchemaSourceListener(NetconfTopologyUtils.DEFAULT_CACHE);
+        NetconfTopologyUtils.DEFAULT_SCHEMA_REPOSITORY.registerSchemaSourceListener(
+                TextToASTTransformer.create(NetconfTopologyUtils.DEFAULT_SCHEMA_REPOSITORY,
+                        NetconfTopologyUtils.DEFAULT_SCHEMA_REPOSITORY));
+    }
+
+    public RemoteDeviceConnectorImpl(final NetconfTopologySetup netconfTopologyDeviceSetup,
+                                     final RemoteDeviceId remoteDeviceId) {
+
+        this.netconfTopologyDeviceSetup = Preconditions.checkNotNull(netconfTopologyDeviceSetup);
+        this.remoteDeviceId = remoteDeviceId;
+    }
+
+    @Override
+    public void startRemoteDeviceConnection(final ActorRef deviceContextActorRef) {
+
+        final NetconfNode netconfNode = netconfTopologyDeviceSetup.getNode().getAugmentation(NetconfNode.class);
+        final NodeId nodeId = netconfTopologyDeviceSetup.getNode().getNodeId();
+        Preconditions.checkNotNull(netconfNode.getHost());
+        Preconditions.checkNotNull(netconfNode.getPort());
+        Preconditions.checkNotNull(netconfNode.isTcpOnly());
+
+        this.deviceCommunicatorDTO = createDeviceCommunicator(nodeId, netconfNode, deviceContextActorRef);
+        final NetconfDeviceCommunicator deviceCommunicator = deviceCommunicatorDTO.getCommunicator();
+        final NetconfClientSessionListener netconfClientSessionListener = deviceCommunicatorDTO.getSessionListener();
+        final NetconfReconnectingClientConfiguration clientConfig =
+                getClientConfig(netconfClientSessionListener, netconfNode);
+        final ListenableFuture<NetconfDeviceCapabilities> future = deviceCommunicator
+                .initializeRemoteConnection(netconfTopologyDeviceSetup.getNetconfClientDispatcher(), clientConfig);
+
+        Futures.addCallback(future, new FutureCallback<NetconfDeviceCapabilities>() {
+            @Override
+            public void onSuccess(NetconfDeviceCapabilities result) {
+                LOG.debug("{}: Connector started successfully", remoteDeviceId);
+            }
+
+            @Override
+            public void onFailure(@Nullable Throwable throwable) {
+                LOG.error("{}: Connector failed, {}", remoteDeviceId, throwable);
+            }
+        });
+    }
+
+    @Override
+    public void stopRemoteDeviceConnection() {
+        Preconditions.checkNotNull(deviceCommunicatorDTO, remoteDeviceId + ": Device communicator was not created.");
+        try {
+            deviceCommunicatorDTO.close();
+        } catch (Exception e) {
+            LOG.error("{}: Error at closing device communicator.", remoteDeviceId, e);
+        }
+    }
+
+    @VisibleForTesting
+    NetconfConnectorDTO createDeviceCommunicator(final NodeId nodeId, final NetconfNode node,
+                                                         final ActorRef deviceContextActorRef) {
+        //setup default values since default value is not supported in mdsal
+        final Long defaultRequestTimeoutMillis = node.getDefaultRequestTimeoutMillis() == null
+                ? NetconfTopologyUtils.DEFAULT_REQUEST_TIMEOUT_MILLIS : node.getDefaultRequestTimeoutMillis();
+        final Long keepaliveDelay = node.getKeepaliveDelay() == null
+                ? NetconfTopologyUtils.DEFAULT_KEEPALIVE_DELAY : node.getKeepaliveDelay();
+        final Boolean reconnectOnChangedSchema = node.isReconnectOnChangedSchema() == null
+                ? NetconfTopologyUtils.DEFAULT_RECONNECT_ON_CHANGED_SCHEMA : node.isReconnectOnChangedSchema();
+
+        RemoteDeviceHandler<NetconfSessionPreferences> salFacade =  new MasterSalFacade(remoteDeviceId,
+                netconfTopologyDeviceSetup.getDomBroker(), netconfTopologyDeviceSetup.getBindingAwareBroker(),
+                netconfTopologyDeviceSetup.getActorSystem(), deviceContextActorRef);
+        if (keepaliveDelay > 0) {
+            LOG.info("{}: Adding keepalive facade.", remoteDeviceId);
+            salFacade = new KeepaliveSalFacade(remoteDeviceId, salFacade,
+                    netconfTopologyDeviceSetup.getKeepaliveExecutor().getExecutor(), keepaliveDelay,
+                    defaultRequestTimeoutMillis);
+        }
+
+        // pre register yang library sources as fallback schemas to schema registry
+        List<SchemaSourceRegistration<YangTextSchemaSource>> registeredYangLibSources = Lists.newArrayList();
+        if (node.getYangLibrary() != null) {
+            final String yangLibURL = node.getYangLibrary().getYangLibraryUrl().getValue();
+            final String yangLibUsername = node.getYangLibrary().getUsername();
+            final String yangLigPassword = node.getYangLibrary().getPassword();
+
+            LibraryModulesSchemas libraryModulesSchemas;
+            if (yangLibURL != null) {
+                if (yangLibUsername != null && yangLigPassword != null) {
+                    libraryModulesSchemas = LibraryModulesSchemas.create(yangLibURL, yangLibUsername, yangLigPassword);
+                } else {
+                    libraryModulesSchemas = LibraryModulesSchemas.create(yangLibURL);
+                }
+
+                for (Map.Entry<SourceIdentifier, URL> sourceIdentifierURLEntry :
+                        libraryModulesSchemas.getAvailableModels().entrySet()) {
+                    registeredYangLibSources
+                            .add(schemaRegistry.registerSchemaSource(
+                                    new YangLibrarySchemaYangSourceProvider(remoteDeviceId,
+                                            libraryModulesSchemas.getAvailableModels()),
+                                    PotentialSchemaSource
+                                            .create(sourceIdentifierURLEntry.getKey(), YangTextSchemaSource.class,
+                                                    PotentialSchemaSource.Costs.REMOTE_IO.getValue())));
+                }
+            }
+        }
+
+        final NetconfDevice.SchemaResourcesDTO schemaResourcesDTO = setupSchemaCacheDTO(nodeId, node);
+        final RemoteDevice<NetconfSessionPreferences, NetconfMessage, NetconfDeviceCommunicator> device;
+        if (node.isSchemaless()) {
+            device = new SchemalessNetconfDevice(remoteDeviceId, salFacade);
+        } else {
+            device = new NetconfDeviceBuilder()
+                    .setReconnectOnSchemasChange(reconnectOnChangedSchema)
+                    .setSchemaResourcesDTO(schemaResourcesDTO)
+                    .setGlobalProcessingExecutor(netconfTopologyDeviceSetup.getProcessingExecutor().getExecutor())
+                    .setId(remoteDeviceId)
+                    .setSalFacade(salFacade)
+                    .build();
+        }
+
+        final Optional<NetconfSessionPreferences> userCapabilities = getUserCapabilities(node);
+        final int rpcMessageLimit =
+                node.getConcurrentRpcLimit() == null
+                        ? NetconfTopologyUtils.DEFAULT_CONCURRENT_RPC_LIMIT : node.getConcurrentRpcLimit();
+
+        if (rpcMessageLimit < 1) {
+            LOG.info("{}: Concurrent rpc limit is smaller than 1, no limit will be enforced.", remoteDeviceId);
+        }
+
+        return new NetconfConnectorDTO(
+                userCapabilities.isPresent()
+                        ? new NetconfDeviceCommunicator(
+                                remoteDeviceId, device, new UserPreferences(userCapabilities.get(),
+                                node.getYangModuleCapabilities().isOverride()), rpcMessageLimit) :
+                        new NetconfDeviceCommunicator(remoteDeviceId, device, rpcMessageLimit), salFacade);
+    }
+
+    private Optional<NetconfSessionPreferences> getUserCapabilities(final NetconfNode node) {
+        if (node.getYangModuleCapabilities() == null) {
+            return Optional.empty();
+        }
+
+        final List<String> capabilities = node.getYangModuleCapabilities().getCapability();
+        if (capabilities == null || capabilities.isEmpty()) {
+            return Optional.empty();
+        }
+
+        final NetconfSessionPreferences parsedOverrideCapabilities =
+                NetconfSessionPreferences.fromStrings(capabilities);
+        Preconditions.checkState(parsedOverrideCapabilities.getNonModuleCaps().isEmpty(), remoteDeviceId +
+                ": Capabilities to override can only contain module based capabilities, non-module capabilities "
+                        + "will be retrieved from the device, configured non-module capabilities: "
+                        + parsedOverrideCapabilities.getNonModuleCaps());
+
+        return Optional.of(parsedOverrideCapabilities);
+    }
+
+    private NetconfDevice.SchemaResourcesDTO setupSchemaCacheDTO(final NodeId nodeId, final NetconfNode node) {
+        // Setup information related to the SchemaRegistry, SchemaResourceFactory, etc.
+        NetconfDevice.SchemaResourcesDTO schemaResourcesDTO = null;
+        final String moduleSchemaCacheDirectory = node.getSchemaCacheDirectory();
+        // Only checks to ensure the String is not empty or null;  further checks related to directory accessibility
+        // and file permissions are handled during the FilesystemSchemaSourceCache initialization.
+        if (!Strings.isNullOrEmpty(moduleSchemaCacheDirectory)) {
+            // If a custom schema cache directory is specified, create the backing DTO; otherwise, the SchemaRegistry
+            // and SchemaContextFactory remain the default values.
+            if (!moduleSchemaCacheDirectory.equals(NetconfTopologyUtils.DEFAULT_CACHE_DIRECTORY)) {
+                // Multiple modules may be created at once;  synchronize to avoid issues with data consistency among
+                // threads.
+                synchronized (schemaResourcesDTOs) {
+                    // Look for the cached DTO to reuse SchemaRegistry and SchemaContextFactory variables if
+                    // they already exist
+                    schemaResourcesDTO = schemaResourcesDTOs.get(moduleSchemaCacheDirectory);
+                    if (schemaResourcesDTO == null) {
+                        schemaResourcesDTO = createSchemaResourcesDTO(moduleSchemaCacheDirectory);
+                        schemaResourcesDTO.getSchemaRegistry().registerSchemaSourceListener(
+                                TextToASTTransformer.create((SchemaRepository) schemaResourcesDTO.getSchemaRegistry(),
+                                        schemaResourcesDTO.getSchemaRegistry())
+                        );
+                        schemaResourcesDTOs.put(moduleSchemaCacheDirectory, schemaResourcesDTO);
+                    }
+                }
+                LOG.info("{} : netconf connector will use schema cache directory {} instead of {}",
+                        remoteDeviceId, moduleSchemaCacheDirectory, NetconfTopologyUtils.DEFAULT_CACHE_DIRECTORY);
+            }
+        } else {
+            LOG.info("{} : using the default directory {}",
+                    remoteDeviceId, NetconfTopologyUtils.QUALIFIED_DEFAULT_CACHE_DIRECTORY);
+        }
+
+        if (schemaResourcesDTO == null) {
+            schemaResourcesDTO =
+                    new NetconfDevice.SchemaResourcesDTO(schemaRegistry, schemaRepository, schemaContextFactory,
+                            new NetconfStateSchemasResolverImpl());
+        }
+
+        return schemaResourcesDTO;
+    }
+
+    /**
+     * Creates the backing Schema classes for a particular directory.
+     *
+     * @param moduleSchemaCacheDirectory The string directory relative to "cache"
+     * @return A DTO containing the Schema classes for the Netconf mount.
+     */
+    private NetconfDevice.SchemaResourcesDTO createSchemaResourcesDTO(final String moduleSchemaCacheDirectory) {
+        final SharedSchemaRepository repository = new SharedSchemaRepository(moduleSchemaCacheDirectory);
+        final SchemaContextFactory schemaContextFactory
+                = repository.createSchemaContextFactory(SchemaSourceFilter.ALWAYS_ACCEPT);
+        this.schemaRegistry = repository;
+        this.schemaContextFactory = schemaContextFactory;
+
+        final FilesystemSchemaSourceCache<YangTextSchemaSource> deviceCache =
+                createDeviceFilesystemCache(moduleSchemaCacheDirectory);
+        repository.registerSchemaSourceListener(deviceCache);
+        return new NetconfDevice.SchemaResourcesDTO(repository, repository, schemaContextFactory,
+                new NetconfStateSchemasResolverImpl());
+    }
+
+    /**
+     * Creates a <code>FilesystemSchemaSourceCache</code> for the custom schema cache directory.
+     *
+     * @param schemaCacheDirectory The custom cache directory relative to "cache"
+     * @return A <code>FilesystemSchemaSourceCache</code> for the custom schema cache directory
+     */
+    private FilesystemSchemaSourceCache<YangTextSchemaSource> createDeviceFilesystemCache(
+            final String schemaCacheDirectory) {
+        final String relativeSchemaCacheDirectory =
+                NetconfTopologyUtils.CACHE_DIRECTORY + File.separator + schemaCacheDirectory;
+        return new FilesystemSchemaSourceCache<>(schemaRegistry, YangTextSchemaSource.class,
+                new File(relativeSchemaCacheDirectory));
+    }
+
+    //TODO: duplicate code
+    private InetSocketAddress getSocketAddress(final Host host, int port) {
+        if (host.getDomainName() != null) {
+            return new InetSocketAddress(host.getDomainName().getValue(), port);
+        } else {
+            final IpAddress ipAddress = host.getIpAddress();
+            final String ip = ipAddress.getIpv4Address() != null ? ipAddress.getIpv4Address().getValue() :
+                    ipAddress.getIpv6Address().getValue();
+            return new InetSocketAddress(ip, port);
+        }
+    }
+
+    private static final class TimedReconnectStrategyFactory implements ReconnectStrategyFactory {
+        private final Long connectionAttempts;
+        private final EventExecutor executor;
+        private final double sleepFactor;
+        private final int minSleep;
+
+        TimedReconnectStrategyFactory(final EventExecutor executor, final Long maxConnectionAttempts,
+                                      final int minSleep, final BigDecimal sleepFactor) {
+            if (maxConnectionAttempts != null && maxConnectionAttempts > 0) {
+                connectionAttempts = maxConnectionAttempts;
+            } else {
+                connectionAttempts = null;
+            }
+
+            this.sleepFactor = sleepFactor.doubleValue();
+            this.executor = executor;
+            this.minSleep = minSleep;
+        }
+
+        @Override
+        public ReconnectStrategy createReconnectStrategy() {
+            final Long maxSleep = null;
+            final Long deadline = null;
+
+            return new TimedReconnectStrategy(executor, minSleep,
+                    minSleep, sleepFactor, maxSleep, connectionAttempts, deadline);
+        }
+    }
+
+    @VisibleForTesting
+    NetconfReconnectingClientConfiguration getClientConfig(final NetconfClientSessionListener listener,
+                                                                   final NetconfNode node) {
+
+        //setup default values since default value is not supported in mdsal
+        final long clientConnectionTimeoutMillis = node.getConnectionTimeoutMillis() == null
+                ? NetconfTopologyUtils.DEFAULT_CONNECTION_TIMEOUT_MILLIS : node.getConnectionTimeoutMillis();
+        final long maxConnectionAttempts = node.getMaxConnectionAttempts() == null
+                ? NetconfTopologyUtils.DEFAULT_MAX_CONNECTION_ATTEMPTS : node.getMaxConnectionAttempts();
+        final int betweenAttemptsTimeoutMillis = node.getBetweenAttemptsTimeoutMillis() == null
+                ? NetconfTopologyUtils.DEFAULT_BETWEEN_ATTEMPTS_TIMEOUT_MILLIS : node.getBetweenAttemptsTimeoutMillis();
+        final BigDecimal sleepFactor = node.getSleepFactor() == null
+                ? NetconfTopologyUtils.DEFAULT_SLEEP_FACTOR : node.getSleepFactor();
+
+        final InetSocketAddress socketAddress = getSocketAddress(node.getHost(), node.getPort().getValue());
+
+        final ReconnectStrategyFactory sf =
+                new TimedReconnectStrategyFactory(netconfTopologyDeviceSetup.getEventExecutor(), maxConnectionAttempts,
+                        betweenAttemptsTimeoutMillis, sleepFactor);
+        final ReconnectStrategy strategy = sf.createReconnectStrategy();
+
+        final AuthenticationHandler authHandler;
+        final Credentials credentials = node.getCredentials();
+        if (credentials instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.credentials.credentials.LoginPassword) {
+            authHandler = new LoginPassword(
+                    ((org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.credentials.credentials.LoginPassword) credentials).getUsername(),
+                    ((org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.credentials.credentials.LoginPassword) credentials).getPassword());
+        } else {
+            throw new IllegalStateException(remoteDeviceId + ": Only login/password authentication is supported");
+        }
+
+        return NetconfReconnectingClientConfigurationBuilder.create()
+                .withAddress(socketAddress)
+                .withConnectionTimeoutMillis(clientConnectionTimeoutMillis)
+                .withReconnectStrategy(strategy)
+                .withAuthHandler(authHandler)
+                .withProtocol(node.isTcpOnly()
+                        ? NetconfClientConfiguration.NetconfClientProtocol.TCP
+                        : NetconfClientConfiguration.NetconfClientProtocol.SSH)
+                .withConnectStrategyFactory(sf)
+                .withSessionListener(listener)
+                .build();
+    }
+
+    @VisibleForTesting
+    Map<String, NetconfDevice.SchemaResourcesDTO> getSchemaResourcesDTOs() {
+        return schemaResourcesDTOs;
+    }
+}
diff --git a/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/RemoteOperationTxProcessorImpl.java b/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/RemoteOperationTxProcessorImpl.java
new file mode 100644 (file)
index 0000000..f107966
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.topology.singleton.impl;
+
+import akka.actor.ActorRef;
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import javax.annotation.Nonnull;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
+import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
+import org.opendaylight.netconf.topology.singleton.api.RemoteOperationTxProcessor;
+import org.opendaylight.netconf.topology.singleton.messages.NormalizedNodeMessage;
+import org.opendaylight.netconf.topology.singleton.messages.transactions.SubmitFailedReply;
+import org.opendaylight.netconf.topology.singleton.messages.transactions.EmptyReadResponse;
+import org.opendaylight.netconf.topology.singleton.messages.transactions.SubmitReply;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class RemoteOperationTxProcessorImpl implements RemoteOperationTxProcessor, AutoCloseable {
+
+    private static final Logger LOG = LoggerFactory.getLogger(RemoteOperationTxProcessorImpl.class);
+
+    private final DOMDataBroker dataBroker;
+    private final RemoteDeviceId id;
+    private DOMDataWriteTransaction writeTx;
+    private DOMDataReadOnlyTransaction readTx;
+
+    public RemoteOperationTxProcessorImpl(final DOMDataBroker dataBroker, final RemoteDeviceId id) {
+        this.dataBroker = dataBroker;
+        this.id = id;
+        this.readTx = dataBroker.newReadOnlyTransaction();
+    }
+
+    @Override
+    public void doDelete(final LogicalDatastoreType store, final YangInstanceIdentifier path) {
+        if (writeTx == null) {
+            writeTx = dataBroker.newWriteOnlyTransaction();
+        }
+        writeTx.delete(store, path);
+    }
+
+    @Override
+    public void doSubmit(final ActorRef recipient, final ActorRef sender) {
+        if (writeTx != null) {
+            CheckedFuture<Void, TransactionCommitFailedException> submitFuture = writeTx.submit();
+            Futures.addCallback(submitFuture, new FutureCallback<Void>() {
+                @Override
+                public void onSuccess(Void result) {
+                    recipient.tell(new SubmitReply(), sender);
+                }
+
+                @Override
+                public void onFailure(@Nonnull Throwable throwable) {
+                    recipient.tell(throwable, sender);
+                }
+            });
+        } else {
+            recipient.tell(new SubmitFailedReply(), sender);
+            LOG.warn("{}: Couldn't submit transaction because it was already closed.", id);
+        }
+    }
+
+    @Override
+    public void doCancel(final ActorRef recipient, final ActorRef sender) {
+        boolean cancel = false;
+        if (writeTx != null) {
+            cancel = writeTx.cancel();
+        }
+        recipient.tell(cancel, sender);
+    }
+
+    @Override
+    public void doPut(final LogicalDatastoreType store, final NormalizedNodeMessage data) {
+        if (writeTx == null) {
+            writeTx = dataBroker.newWriteOnlyTransaction();
+        }
+        writeTx.put(store, data.getIdentifier(), data.getNode());
+    }
+
+    @Override
+    public void doMerge(final LogicalDatastoreType store, final NormalizedNodeMessage data) {
+        if (writeTx == null) {
+            writeTx = dataBroker.newWriteOnlyTransaction();
+        }
+        writeTx.merge(store, data.getIdentifier(), data.getNode());
+    }
+
+    @Override
+    public void doRead(final LogicalDatastoreType store, final YangInstanceIdentifier path, final ActorRef recipient,
+                       final ActorRef sender) {
+        final CheckedFuture<Optional<NormalizedNode<?,?>>, ReadFailedException> readFuture =
+                readTx.read(store, path);
+
+        Futures.addCallback(readFuture, new FutureCallback<Optional<NormalizedNode<?, ?>>>() {
+
+            @Override
+            public void onSuccess(final Optional<NormalizedNode<?, ?>> result) {
+                if (!result.isPresent()) {
+                    recipient.tell(new EmptyReadResponse(), sender);
+                    return;
+                }
+                recipient.tell(new NormalizedNodeMessage(path, result.get()), sender);
+            }
+
+            @Override
+            public void onFailure(@Nonnull final Throwable throwable) {
+                recipient.tell(throwable, sender);
+            }
+        });
+    }
+
+    @Override
+    public void doExists(final LogicalDatastoreType store, final YangInstanceIdentifier path, final ActorRef recipient,
+                         final ActorRef sender) {
+        final CheckedFuture<Boolean, ReadFailedException> readFuture =
+                readTx.exists(store, path);
+        Futures.addCallback(readFuture, new FutureCallback<Boolean>() {
+            @Override
+            public void onSuccess(final Boolean result) {
+                if (result == null) {
+                    recipient.tell(false, sender);
+                } else {
+                    recipient.tell(result, sender);
+                }
+            }
+
+            @Override
+            public void onFailure(@Nonnull final Throwable throwable) {
+                recipient.tell(throwable, sender);
+            }
+        });
+    }
+
+    @Override
+    public void close() throws Exception {
+        if (readTx != null) {
+            readTx.close();
+        }
+    }
+}
diff --git a/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/SlaveSalFacade.java b/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/SlaveSalFacade.java
new file mode 100644 (file)
index 0000000..877436d
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.topology.singleton.impl;
+
+import akka.actor.ActorRef;
+import akka.actor.ActorSystem;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
+import org.opendaylight.controller.sal.core.api.Broker;
+import org.opendaylight.netconf.sal.connect.netconf.sal.NetconfDeviceNotificationService;
+import org.opendaylight.netconf.sal.connect.netconf.sal.NetconfDeviceSalProvider;
+import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
+import org.opendaylight.netconf.topology.singleton.api.NetconfDOMTransaction;
+import org.opendaylight.netconf.topology.singleton.impl.tx.NetconfProxyDOMTransaction;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SlaveSalFacade {
+
+    private static final Logger LOG = LoggerFactory.getLogger(SlaveSalFacade.class);
+
+    private final RemoteDeviceId id;
+    private final NetconfDeviceSalProvider salProvider;
+
+    private final ActorSystem actorSystem;
+
+    public SlaveSalFacade(final RemoteDeviceId id,
+                          final Broker domBroker,
+                          final ActorSystem actorSystem) {
+        this.id = id;
+        this.salProvider = new NetconfDeviceSalProvider(id);
+        this.actorSystem = actorSystem;
+
+        registerToSal(domBroker);
+    }
+
+    private void registerToSal(final Broker domRegistryDependency) {
+        domRegistryDependency.registerProvider(salProvider);
+
+    }
+
+    public void registerSlaveMountPoint(final SchemaContext remoteSchemaContext, final DOMRpcService deviceRpc,
+                                        final ActorRef masterActorRef) {
+        final NetconfDeviceNotificationService notificationService = new NetconfDeviceNotificationService();
+
+        final NetconfDOMTransaction proxyDOMTransactions =
+                new NetconfProxyDOMTransaction(id, actorSystem, masterActorRef);
+
+        final NetconfDOMDataBroker netconfDeviceDataBroker =
+                new NetconfDOMDataBroker(actorSystem, id, proxyDOMTransactions);
+
+        salProvider.getMountInstance().onTopologyDeviceConnected(remoteSchemaContext, netconfDeviceDataBroker,
+                deviceRpc, notificationService);
+
+        LOG.info("{}: Slave mount point registered.", id);
+    }
+
+    public void unregisterSlaveMountPoint() {
+        salProvider.getMountInstance().onTopologyDeviceDisconnected();
+    }
+
+    public void close() {
+        unregisterSlaveMountPoint();
+        try {
+            salProvider.getMountInstance().close();
+        } catch (Exception exception) {
+            LOG.warn("{}: Exception in closing slave sal facade: {}", id, exception);
+        }
+
+    }
+
+
+}
diff --git a/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/actors/NetconfNodeActor.java b/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/actors/NetconfNodeActor.java
new file mode 100644 (file)
index 0000000..75c7e62
--- /dev/null
@@ -0,0 +1,235 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.topology.singleton.impl.actors;
+
+import akka.actor.ActorRef;
+import akka.actor.Props;
+import akka.actor.UntypedActor;
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import java.io.IOException;
+import java.util.List;
+import javax.annotation.Nonnull;
+import org.opendaylight.controller.cluster.schema.provider.RemoteYangTextSourceProvider;
+import org.opendaylight.controller.cluster.schema.provider.impl.RemoteSchemaProvider;
+import org.opendaylight.controller.cluster.schema.provider.impl.YangTextSchemaSourceSerializationProxy;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
+import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
+import org.opendaylight.netconf.topology.singleton.api.RemoteOperationTxProcessor;
+import org.opendaylight.netconf.topology.singleton.impl.ProxyDOMRpcService;
+import org.opendaylight.netconf.topology.singleton.impl.ProxyYangTextSourceProvider;
+import org.opendaylight.netconf.topology.singleton.impl.RemoteOperationTxProcessorImpl;
+import org.opendaylight.netconf.topology.singleton.impl.SlaveSalFacade;
+import org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologySetup;
+import org.opendaylight.netconf.topology.singleton.messages.AskForMasterMountPoint;
+import org.opendaylight.netconf.topology.singleton.messages.CreateInitialMasterActorData;
+import org.opendaylight.netconf.topology.singleton.messages.MasterActorDataInitialized;
+import org.opendaylight.netconf.topology.singleton.messages.RefreshSetupMasterActorData;
+import org.opendaylight.netconf.topology.singleton.messages.RegisterMountPoint;
+import org.opendaylight.netconf.topology.singleton.messages.UnregisterSlaveMountPoint;
+import org.opendaylight.netconf.topology.singleton.messages.YangTextSchemaSourceRequest;
+import org.opendaylight.netconf.topology.singleton.messages.transactions.CancelRequest;
+import org.opendaylight.netconf.topology.singleton.messages.transactions.DeleteRequest;
+import org.opendaylight.netconf.topology.singleton.messages.transactions.ExistsRequest;
+import org.opendaylight.netconf.topology.singleton.messages.transactions.MergeRequest;
+import org.opendaylight.netconf.topology.singleton.messages.transactions.PutRequest;
+import org.opendaylight.netconf.topology.singleton.messages.transactions.ReadRequest;
+import org.opendaylight.netconf.topology.singleton.messages.transactions.SubmitRequest;
+import org.opendaylight.netconf.topology.singleton.messages.transactions.TransactionRequest;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.repo.api.SchemaContextFactory;
+import org.opendaylight.yangtools.yang.model.repo.api.SchemaRepository;
+import org.opendaylight.yangtools.yang.model.repo.api.SchemaResolutionException;
+import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceException;
+import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceFilter;
+import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
+import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
+import org.opendaylight.yangtools.yang.model.repo.spi.PotentialSchemaSource;
+import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceRegistry;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NetconfNodeActor extends UntypedActor {
+
+    private static final Logger LOG = LoggerFactory.getLogger(NetconfNodeActor.class);
+
+    private NetconfTopologySetup setup;
+    private RemoteDeviceId id;
+    private final SchemaSourceRegistry schemaRegistry;
+    private final SchemaRepository schemaRepository;
+
+    private RemoteOperationTxProcessor operationsProcessor;
+    private List<SourceIdentifier> sourceIdentifiers;
+    private SlaveSalFacade slaveSalManager;
+
+    public static Props props(final NetconfTopologySetup setup,
+                              final RemoteDeviceId id, final SchemaSourceRegistry schemaRegistry,
+                              final SchemaRepository schemaRepository) {
+        return Props.create(NetconfNodeActor.class, () ->
+                new NetconfNodeActor(setup, id, schemaRegistry, schemaRepository));
+    }
+
+    private NetconfNodeActor(final NetconfTopologySetup setup,
+                             final RemoteDeviceId id, SchemaSourceRegistry schemaRegistry,
+                             final SchemaRepository schemaRepository) {
+        this.setup = setup;
+        this.id = id;
+        this.schemaRegistry = schemaRegistry;
+        this.schemaRepository = schemaRepository;
+    }
+
+    @Override
+    public void onReceive(final Object message) throws Exception {
+        if (message instanceof CreateInitialMasterActorData) { // master
+
+            sourceIdentifiers = ((CreateInitialMasterActorData) message).getSourceIndentifiers();
+            operationsProcessor =
+                    new RemoteOperationTxProcessorImpl(((CreateInitialMasterActorData) message).getDeviceDataBroker(),
+                            id);
+            sender().tell(new MasterActorDataInitialized(), self());
+
+            LOG.debug("{}: Master is ready.", id);
+
+        } else if (message instanceof  RefreshSetupMasterActorData) {
+            setup = ((RefreshSetupMasterActorData) message).getNetconfTopologyDeviceSetup();
+            id = ((RefreshSetupMasterActorData) message).getRemoteDeviceId();
+            sender().tell(new MasterActorDataInitialized(), self());
+        } else if (message instanceof AskForMasterMountPoint) { // master
+            // only master contains reference to operations processor
+            if (operationsProcessor != null) {
+                getSender().tell(new RegisterMountPoint(sourceIdentifiers), getSelf());
+            }
+
+        } else if (message instanceof TransactionRequest) { // master
+
+            resolveProxyCalls(message, sender(), getSelf());
+
+        } else if (message instanceof YangTextSchemaSourceRequest) { // master
+
+            final YangTextSchemaSourceRequest yangTextSchemaSourceRequest = (YangTextSchemaSourceRequest) message;
+            sendYangTextSchemaSourceProxy(yangTextSchemaSourceRequest.getSourceIdentifier(), sender());
+
+        } else if (message instanceof RegisterMountPoint) { //slaves
+
+            sourceIdentifiers = ((RegisterMountPoint) message).getSourceIndentifiers();
+            registerSlaveMountPoint(getSender());
+
+        } else if (message instanceof UnregisterSlaveMountPoint) { //slaves
+            if (slaveSalManager != null) {
+                slaveSalManager.close();
+                slaveSalManager = null;
+            }
+
+        }
+    }
+
+    private void resolveProxyCalls(final Object message, final ActorRef recipient, final ActorRef futureSender) {
+        if (message instanceof ReadRequest) {
+
+            final ReadRequest readRequest = (ReadRequest) message;
+            operationsProcessor.doRead(readRequest.getStore(), readRequest.getPath(), recipient, futureSender);
+
+        } else if (message instanceof ExistsRequest) {
+
+            final ExistsRequest readRequest = (ExistsRequest) message;
+            operationsProcessor.doExists(readRequest.getStore(), readRequest.getPath(), recipient, futureSender);
+
+        } else if (message instanceof MergeRequest) {
+
+            final MergeRequest mergeRequest = (MergeRequest) message;
+            operationsProcessor.doMerge(mergeRequest.getStore(), mergeRequest.getNormalizedNodeMessage());
+
+        } else if (message instanceof PutRequest) {
+
+            final PutRequest putRequest = (PutRequest) message;
+            operationsProcessor.doPut(putRequest.getStore(), putRequest.getNormalizedNodeMessage());
+
+        } else if (message instanceof DeleteRequest) {
+
+            final DeleteRequest deleteRequest = (DeleteRequest) message;
+            operationsProcessor.doDelete(deleteRequest.getStore(), deleteRequest.getPath());
+
+        } else if (message instanceof CancelRequest) {
+
+            operationsProcessor.doCancel(recipient, futureSender);
+
+        } else if (message instanceof SubmitRequest) {
+
+            operationsProcessor.doSubmit(recipient, futureSender);
+        }
+    }
+
+    private void sendYangTextSchemaSourceProxy(final SourceIdentifier sourceIdentifier, final ActorRef sender) {
+        final CheckedFuture<YangTextSchemaSource, SchemaSourceException> yangTextSchemaSource =
+                schemaRepository.getSchemaSource(sourceIdentifier, YangTextSchemaSource.class);
+
+        Futures.addCallback(yangTextSchemaSource, new FutureCallback<YangTextSchemaSource>() {
+            @Override
+            public void onSuccess(final YangTextSchemaSource yangTextSchemaSource) {
+                try {
+                    sender.tell(new YangTextSchemaSourceSerializationProxy(yangTextSchemaSource), getSelf());
+                } catch (IOException exception) {
+                    sender.tell(exception.getCause(), getSelf());
+                }
+            }
+
+            @Override
+            public void onFailure(@Nonnull final Throwable throwable) {
+                sender.tell(throwable, getSelf());
+            }
+        });
+    }
+
+    private void registerSlaveMountPoint(final ActorRef masterReference) {
+        if (this.slaveSalManager != null) {
+            slaveSalManager.close();
+        }
+        slaveSalManager = new SlaveSalFacade(id, setup.getDomBroker(), setup.getActorSystem());
+
+        final CheckedFuture<SchemaContext, SchemaResolutionException> remoteSchemaContext =
+                getSchemaContext(masterReference);
+        final DOMRpcService deviceRpc = getDOMRpcService();
+
+        Futures.addCallback(remoteSchemaContext, new FutureCallback<SchemaContext>() {
+            @Override
+            public void onSuccess(final SchemaContext result) {
+                LOG.info("{}: Schema context resolved: {}", id, result.getModules());
+                slaveSalManager.registerSlaveMountPoint(result, deviceRpc, masterReference);
+            }
+
+            @Override
+            public void onFailure(@Nonnull final Throwable throwable) {
+                LOG.error("{}: Failed to register mount point: {}", id, throwable);
+            }
+        });
+    }
+
+    private DOMRpcService getDOMRpcService() {
+        return new ProxyDOMRpcService();
+    }
+
+    private CheckedFuture<SchemaContext, SchemaResolutionException> getSchemaContext(ActorRef masterReference) {
+
+        final RemoteYangTextSourceProvider remoteYangTextSourceProvider =
+                new ProxyYangTextSourceProvider(masterReference, getContext());
+        final RemoteSchemaProvider remoteProvider = new RemoteSchemaProvider(remoteYangTextSourceProvider,
+                getContext().dispatcher());
+
+        sourceIdentifiers.forEach(sourceId ->
+                schemaRegistry.registerSchemaSource(remoteProvider, PotentialSchemaSource.create(sourceId,
+                        YangTextSchemaSource.class, PotentialSchemaSource.Costs.REMOTE_IO.getValue())));
+
+        final SchemaContextFactory schemaContextFactory
+                = schemaRepository.createSchemaContextFactory(SchemaSourceFilter.ALWAYS_ACCEPT);
+
+        return schemaContextFactory.createSchemaContext(sourceIdentifiers);
+    }
+
+}
diff --git a/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/tx/NetconfMasterDOMTransaction.java b/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/tx/NetconfMasterDOMTransaction.java
new file mode 100644 (file)
index 0000000..33680f2
--- /dev/null
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.topology.singleton.impl.tx;
+
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import javax.annotation.Nonnull;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
+import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences;
+import org.opendaylight.netconf.sal.connect.netconf.sal.NetconfDeviceDataBroker;
+import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
+import org.opendaylight.netconf.topology.singleton.api.NetconfDOMTransaction;
+import org.opendaylight.netconf.topology.singleton.messages.NormalizedNodeMessage;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import scala.concurrent.Future;
+import scala.concurrent.impl.Promise.DefaultPromise;
+
+public class NetconfMasterDOMTransaction implements NetconfDOMTransaction {
+
+    private static final Logger LOG = LoggerFactory.getLogger(NetconfMasterDOMTransaction.class);
+
+    private final RemoteDeviceId id;
+    private final DOMDataBroker delegateBroker;
+
+    private DOMDataReadOnlyTransaction readTx;
+    private DOMDataWriteTransaction writeTx;
+
+    public NetconfMasterDOMTransaction(final RemoteDeviceId id,
+                                       final SchemaContext schemaContext,
+                                       final DOMRpcService rpc,
+                                       final NetconfSessionPreferences netconfSessionPreferences) {
+        this(id, new NetconfDeviceDataBroker(id, schemaContext, rpc, netconfSessionPreferences));
+    }
+
+    public NetconfMasterDOMTransaction(final RemoteDeviceId id, final DOMDataBroker delegateBroker) {
+        this.id = id;
+        this.delegateBroker = delegateBroker;
+
+        // only ever need 1 readTx since it doesnt need to be closed
+        readTx = delegateBroker.newReadOnlyTransaction();
+    }
+
+    @Override
+    public Future<Optional<NormalizedNodeMessage>> read(final LogicalDatastoreType store,
+                                                        final YangInstanceIdentifier path) {
+        LOG.trace("{}: Read[{}] {} via NETCONF: {}", id, readTx.getIdentifier(), store, path);
+
+        final CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> readFuture = readTx.read(store, path);
+
+        final DefaultPromise<Optional<NormalizedNodeMessage>> promise = new DefaultPromise<>();
+        Futures.addCallback(readFuture, new FutureCallback<Optional<NormalizedNode<?, ?>>>() {
+            @Override
+            public void onSuccess(final Optional<NormalizedNode<?, ?>> result) {
+                if (!result.isPresent()) {
+                    promise.success(Optional.absent());
+                } else {
+                    promise.success(Optional.of(new NormalizedNodeMessage(path, result.get())));
+                }
+            }
+
+            @Override
+            public void onFailure(@Nonnull final Throwable throwable) {
+                promise.failure(throwable);
+            }
+        });
+        return promise.future();
+    }
+
+    @Override
+    public Future<Boolean> exists(final LogicalDatastoreType store, final YangInstanceIdentifier path) {
+        LOG.trace("{}: Exists[{}] {} via NETCONF: {}", id, readTx.getIdentifier(), store, path);
+
+        final CheckedFuture<Boolean, ReadFailedException> existsFuture = readTx.exists(store, path);
+
+        final DefaultPromise<Boolean> promise = new DefaultPromise<>();
+        Futures.addCallback(existsFuture, new FutureCallback<Boolean>() {
+            @Override
+            public void onSuccess(final Boolean result) {
+                promise.success(result);
+            }
+
+            @Override
+            public void onFailure(@Nonnull final Throwable throwable) {
+                promise.failure(throwable);
+            }
+        });
+        return promise.future();
+    }
+
+    @Override
+    public void put(final LogicalDatastoreType store, final NormalizedNodeMessage data) {
+        if (writeTx == null) {
+            writeTx = delegateBroker.newWriteOnlyTransaction();
+        }
+
+        LOG.trace("{}: Write[{}] {} via NETCONF: {} with payload {}", id, writeTx.getIdentifier(), store,
+                data.getIdentifier(), data.getNode());
+
+        writeTx.put(store, data.getIdentifier(), data.getNode());
+    }
+
+    @Override
+    public void merge(final LogicalDatastoreType store, final NormalizedNodeMessage data) {
+        if (writeTx == null) {
+            writeTx = delegateBroker.newWriteOnlyTransaction();
+        }
+
+        LOG.trace("{}: Merge[{}] {} via NETCONF: {} with payload {}", id, writeTx.getIdentifier(),store,
+                data.getIdentifier(), data.getNode());
+
+        writeTx.merge(store, data.getIdentifier(), data.getNode());
+    }
+
+    @Override
+    public void delete(final LogicalDatastoreType store, final YangInstanceIdentifier path) {
+        if (writeTx == null) {
+            writeTx = delegateBroker.newWriteOnlyTransaction();
+        }
+
+        LOG.trace("{}: Delete[{}} {} via NETCONF: {}", id, writeTx.getIdentifier(), store, path);
+
+        writeTx.delete(store, path);
+    }
+
+    @Override
+    public boolean cancel() {
+        LOG.trace("{}: Cancel[{}} via NETCONF", id, writeTx.getIdentifier());
+
+        return writeTx.cancel();
+    }
+
+    @Override
+    public Future<Void> submit() {
+        LOG.trace("{}: Submit[{}} via NETCONF", id, writeTx.getIdentifier());
+
+        final CheckedFuture<Void, TransactionCommitFailedException> submitFuture = writeTx.submit();
+        final DefaultPromise<Void> promise = new DefaultPromise<>();
+        Futures.addCallback(submitFuture, new FutureCallback<Void>() {
+            @Override
+            public void onSuccess(final Void result) {
+                promise.success(result);
+                writeTx = null;
+            }
+
+            @Override
+            public void onFailure(@Nonnull final Throwable throwable) {
+                promise.failure(throwable);
+                writeTx = null;
+            }
+        });
+        return promise.future();
+    }
+
+}
diff --git a/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/tx/NetconfProxyDOMTransaction.java b/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/tx/NetconfProxyDOMTransaction.java
new file mode 100644 (file)
index 0000000..9a23a71
--- /dev/null
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.topology.singleton.impl.tx;
+
+import akka.actor.ActorRef;
+import akka.actor.ActorSystem;
+import akka.dispatch.OnComplete;
+import akka.pattern.Patterns;
+import com.google.common.base.Optional;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
+import org.opendaylight.netconf.topology.singleton.api.NetconfDOMTransaction;
+import org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologyUtils;
+import org.opendaylight.netconf.topology.singleton.messages.NormalizedNodeMessage;
+import org.opendaylight.netconf.topology.singleton.messages.transactions.SubmitFailedReply;
+import org.opendaylight.netconf.topology.singleton.messages.transactions.CancelRequest;
+import org.opendaylight.netconf.topology.singleton.messages.transactions.DeleteRequest;
+import org.opendaylight.netconf.topology.singleton.messages.transactions.EmptyReadResponse;
+import org.opendaylight.netconf.topology.singleton.messages.transactions.ExistsRequest;
+import org.opendaylight.netconf.topology.singleton.messages.transactions.MergeRequest;
+import org.opendaylight.netconf.topology.singleton.messages.transactions.PutRequest;
+import org.opendaylight.netconf.topology.singleton.messages.transactions.ReadRequest;
+import org.opendaylight.netconf.topology.singleton.messages.transactions.SubmitRequest;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import scala.concurrent.Await;
+import scala.concurrent.Future;
+import scala.concurrent.impl.Promise.DefaultPromise;
+
+
+public class NetconfProxyDOMTransaction implements NetconfDOMTransaction {
+
+    private static final Logger LOG = LoggerFactory.getLogger(NetconfProxyDOMTransaction.class);
+
+    private final RemoteDeviceId id;
+    private final ActorSystem actorSystem;
+    private final ActorRef masterContextRef;
+
+    public NetconfProxyDOMTransaction(final RemoteDeviceId id,
+                                      final ActorSystem actorSystem,
+                                      final ActorRef masterContextRef) {
+        this.id = id;
+        this.actorSystem = actorSystem;
+        this.masterContextRef = masterContextRef;
+    }
+
+    @Override
+    public Future<Optional<NormalizedNodeMessage>> read(final LogicalDatastoreType store,
+                                                        final YangInstanceIdentifier path) {
+
+        final Future<Object> readScalaFuture =
+                Patterns.ask(masterContextRef, new ReadRequest(store, path), NetconfTopologyUtils.TIMEOUT);
+
+        LOG.trace("{}: Read {} via NETCONF: {}", id, store, path);
+
+        final DefaultPromise<Optional<NormalizedNodeMessage>> promise = new DefaultPromise<>();
+
+        readScalaFuture.onComplete(new OnComplete<Object>() {
+            @Override
+            public void onComplete(final Throwable failure, final Object success) throws Throwable {
+                if (failure != null) { // ask timeout
+                    Exception exception = new DocumentedException(id + ":Master is down. Please try again.",
+                            DocumentedException.ErrorType.APPLICATION, DocumentedException.ErrorTag.OPERATION_FAILED,
+                            DocumentedException.ErrorSeverity.WARNING);
+                    promise.failure(exception);
+                    return;
+                }
+                if (success instanceof Throwable) { // Error sended by master
+                    promise.failure((Throwable) success);
+                    return;
+                }
+                if (success instanceof EmptyReadResponse) {
+                    promise.success(Optional.absent());
+                    return;
+                }
+
+                promise.success(Optional.of((NormalizedNodeMessage) success));
+            }
+        }, actorSystem.dispatcher());
+
+        return promise.future();
+    }
+
+    @Override
+    public Future<Boolean> exists(final LogicalDatastoreType store, final YangInstanceIdentifier path) {
+        final Future<Object> existsScalaFuture =
+                Patterns.ask(masterContextRef, new ExistsRequest(store, path), NetconfTopologyUtils.TIMEOUT);
+
+        LOG.trace("{}: Exists {} via NETCONF: {}", id, store, path);
+
+        final DefaultPromise<Boolean> promise = new DefaultPromise<>();
+        existsScalaFuture.onComplete(new OnComplete<Object>() {
+            @Override
+            public void onComplete(final Throwable failure, final Object success) throws Throwable {
+                if (failure != null) { // ask timeout
+                    Exception exception = new DocumentedException(id + ":Master is down. Please try again.",
+                            DocumentedException.ErrorType.APPLICATION, DocumentedException.ErrorTag.OPERATION_FAILED,
+                            DocumentedException.ErrorSeverity.WARNING);
+                    promise.failure(exception);
+                    return;
+                }
+                if (success instanceof Throwable) {
+                    promise.failure((Throwable) success);
+                    return;
+                }
+                promise.success((Boolean) success);
+            }
+        }, actorSystem.dispatcher());
+        return promise.future();
+    }
+
+    @Override
+    public void put(final LogicalDatastoreType store, final NormalizedNodeMessage data) {
+        LOG.trace("{}: Write {} via NETCONF: {} with payload {}", id, store, data.getIdentifier(), data.getNode());
+
+        masterContextRef.tell(new PutRequest(store, data), ActorRef.noSender());
+
+    }
+
+    @Override
+    public void merge(final LogicalDatastoreType store, final NormalizedNodeMessage data) {
+        LOG.trace("{}: Merge {} via NETCONF: {} with payload {}", id, store, data.getIdentifier(), data.getNode());
+
+        masterContextRef.tell(new MergeRequest(store, data), ActorRef.noSender());
+    }
+
+    @Override
+    public void delete(final LogicalDatastoreType store, final YangInstanceIdentifier path) {
+        LOG.trace("{}: Delete {} via NETCONF: {}", id, store, path);
+
+        masterContextRef.tell(new DeleteRequest(store, path), ActorRef.noSender());
+    }
+
+    @Override
+    public boolean cancel() {
+        final Future<Object> cancelScalaFuture =
+                Patterns.ask(masterContextRef, new CancelRequest(), NetconfTopologyUtils.TIMEOUT);
+
+        LOG.trace("{}: Cancel {} via NETCONF", id);
+
+        try {
+            // here must be Await because AsyncWriteTransaction do not return future
+            return (boolean) Await.result(cancelScalaFuture, NetconfTopologyUtils.TIMEOUT.duration());
+        } catch (Exception e) {
+            return false;
+        }
+    }
+
+    @Override
+    public Future<Void> submit() {
+        final Future<Object> submitScalaFuture =
+                Patterns.ask(masterContextRef, new SubmitRequest(), NetconfTopologyUtils.TIMEOUT);
+
+        LOG.trace("{}: Submit {} via NETCONF", id);
+
+        final DefaultPromise<Void> promise = new DefaultPromise<>();
+
+        submitScalaFuture.onComplete(new OnComplete<Object>() {
+            @Override
+            public void onComplete(final Throwable failure, final Object success) throws Throwable {
+                if (failure != null) { // ask timeout
+                    Exception exception = new DocumentedException(id + ":Master is down. Please try again.",
+                            DocumentedException.ErrorType.APPLICATION, DocumentedException.ErrorTag.OPERATION_FAILED,
+                            DocumentedException.ErrorSeverity.WARNING);
+                    promise.failure(exception);
+                    return;
+                }
+                if (success instanceof Throwable) {
+                    promise.failure((Throwable) success);
+                } else {
+                    if (success instanceof SubmitFailedReply) {
+                        LOG.error("{}: Transaction was not submitted because already closed.", id);
+                    }
+                    promise.success(null);
+                }
+            }
+        }, actorSystem.dispatcher());
+
+        return promise.future();
+    }
+
+}
@@ -1,12 +1,12 @@
 /*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
 
-package org.opendaylight.netconf.topology.pipeline.tx;
+package org.opendaylight.netconf.topology.singleton.impl.tx;
 
 import akka.actor.ActorSystem;
 import akka.dispatch.OnComplete;
@@ -20,19 +20,25 @@ import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
 import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
-import org.opendaylight.netconf.topology.pipeline.ProxyNetconfDeviceDataBroker;
-import org.opendaylight.netconf.topology.util.messages.NormalizedNodeMessage;
+import org.opendaylight.netconf.topology.singleton.api.NetconfDOMTransaction;
+import org.opendaylight.netconf.topology.singleton.messages.NormalizedNodeMessage;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import scala.concurrent.Future;
 
-public class ProxyReadOnlyTransaction implements DOMDataReadOnlyTransaction{
+public class NetconfReadOnlyTransaction implements DOMDataReadOnlyTransaction {
+
+    private static final Logger LOG = LoggerFactory.getLogger(NetconfReadOnlyTransaction.class);
 
     private final RemoteDeviceId id;
-    private final ProxyNetconfDeviceDataBroker delegate;
+    private final NetconfDOMTransaction delegate;
     private final ActorSystem actorSystem;
 
-    public ProxyReadOnlyTransaction(final ActorSystem actorSystem, final RemoteDeviceId id, final ProxyNetconfDeviceDataBroker delegate) {
+    public NetconfReadOnlyTransaction(final RemoteDeviceId id,
+                                      final ActorSystem actorSystem,
+                                      final NetconfDOMTransaction delegate) {
         this.id = id;
         this.delegate = delegate;
         this.actorSystem = actorSystem;
@@ -44,10 +50,15 @@ public class ProxyReadOnlyTransaction implements DOMDataReadOnlyTransaction{
     }
 
     @Override
-    public CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> read(final LogicalDatastoreType store, final YangInstanceIdentifier path) {
+    public CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> read(final LogicalDatastoreType store,
+                                                                                   final YangInstanceIdentifier path) {
+
+        LOG.trace("{}: Read {} via NETCONF: {}", id, store, path);
+
         final Future<Optional<NormalizedNodeMessage>> future = delegate.read(store, path);
         final SettableFuture<Optional<NormalizedNode<?, ?>>> settableFuture = SettableFuture.create();
-        final CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> checkedFuture = Futures.makeChecked(settableFuture, new Function<Exception, ReadFailedException>() {
+        final CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> checkedFuture;
+        checkedFuture = Futures.makeChecked(settableFuture, new Function<Exception, ReadFailedException>() {
             @Nullable
             @Override
             public ReadFailedException apply(Exception cause) {
@@ -56,13 +67,16 @@ public class ProxyReadOnlyTransaction implements DOMDataReadOnlyTransaction{
         });
         future.onComplete(new OnComplete<Optional<NormalizedNodeMessage>>() {
             @Override
-            public void onComplete(Throwable throwable, Optional<NormalizedNodeMessage> normalizedNodeMessage) throws Throwable {
+            public void onComplete(final Throwable throwable,
+                                   final Optional<NormalizedNodeMessage> normalizedNodeMessage) throws Throwable {
                 if (throwable == null) {
                     if (normalizedNodeMessage.isPresent()) {
-                        settableFuture.set(normalizedNodeMessage.transform(new Function<NormalizedNodeMessage, NormalizedNode<?, ?>>() {
+                        settableFuture.set(normalizedNodeMessage.transform(new Function<NormalizedNodeMessage,
+                                NormalizedNode<?, ?>>() {
+
                             @Nullable
                             @Override
-                            public NormalizedNode<?, ?> apply(NormalizedNodeMessage input) {
+                            public NormalizedNode<?, ?> apply(final NormalizedNodeMessage input) {
                                 return input.getNode();
                             }
                         }));
@@ -78,10 +92,15 @@ public class ProxyReadOnlyTransaction implements DOMDataReadOnlyTransaction{
     }
 
     @Override
-    public CheckedFuture<Boolean, ReadFailedException> exists(final LogicalDatastoreType store, final YangInstanceIdentifier path) {
+    public CheckedFuture<Boolean, ReadFailedException> exists(final LogicalDatastoreType store,
+                                                              final YangInstanceIdentifier path) {
+
+        LOG.trace("{}: Exists {} via NETCONF: {}", id, store, path);
+
         final Future<Boolean> existsFuture = delegate.exists(store, path);
         final SettableFuture<Boolean> settableFuture = SettableFuture.create();
-        final CheckedFuture<Boolean, ReadFailedException> checkedFuture = Futures.makeChecked(settableFuture, new Function<Exception, ReadFailedException>() {
+        final CheckedFuture<Boolean, ReadFailedException> checkedFuture;
+        checkedFuture = Futures.makeChecked(settableFuture, new Function<Exception, ReadFailedException>() {
             @Nullable
             @Override
             public ReadFailedException apply(Exception cause) {
@@ -90,7 +109,7 @@ public class ProxyReadOnlyTransaction implements DOMDataReadOnlyTransaction{
         });
         existsFuture.onComplete(new OnComplete<Boolean>() {
             @Override
-            public void onComplete(Throwable throwable, Boolean result) throws Throwable {
+            public void onComplete(final Throwable throwable, final Boolean result) throws Throwable {
                 if (throwable == null) {
                     settableFuture.set(result);
                 } else {
diff --git a/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/tx/NetconfWriteOnlyTransaction.java b/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/tx/NetconfWriteOnlyTransaction.java
new file mode 100644 (file)
index 0000000..f938748
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.topology.singleton.impl.tx;
+
+import akka.actor.ActorSystem;
+import akka.dispatch.OnComplete;
+import com.google.common.base.Function;
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.SettableFuture;
+import javax.annotation.Nullable;
+import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
+import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
+import org.opendaylight.netconf.topology.singleton.api.NetconfDOMTransaction;
+import org.opendaylight.netconf.topology.singleton.messages.NormalizedNodeMessage;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import scala.concurrent.Future;
+
+public class NetconfWriteOnlyTransaction implements DOMDataWriteTransaction {
+
+    private static final Logger LOG = LoggerFactory.getLogger(NetconfWriteOnlyTransaction.class);
+
+    private final RemoteDeviceId id;
+    private final NetconfDOMTransaction delegate;
+    private final ActorSystem actorSystem;
+
+    public NetconfWriteOnlyTransaction(final RemoteDeviceId id,
+                                       final ActorSystem actorSystem,
+                                       final NetconfDOMTransaction delegate) {
+        this.id = id;
+        this.delegate = delegate;
+        this.actorSystem = actorSystem;
+    }
+
+    @Override
+    public void put(final LogicalDatastoreType store, final YangInstanceIdentifier path,
+                    final NormalizedNode<?,?> data) {
+        LOG.trace("{}: Write {} via NETCONF: {} with payload {}", id, store, path, data);
+
+        delegate.put(store, new NormalizedNodeMessage(path, data));
+    }
+
+    @Override
+    public void merge(final LogicalDatastoreType store, final YangInstanceIdentifier path,
+                      final NormalizedNode<?,?> data) {
+        LOG.trace("{}: Merge {} via NETCONF: {} with payload {}", id, store, path, data);
+
+        delegate.merge(store, new NormalizedNodeMessage(path, data));
+    }
+
+    @Override
+    public boolean cancel() {
+        LOG.trace("{}: Cancel", id);
+
+        return delegate.cancel();
+    }
+
+    @Override
+    public void delete(final LogicalDatastoreType store, final YangInstanceIdentifier path) {
+        LOG.trace("{}: Delete {} via NETCONF: {}", id, store, path);
+
+        delegate.delete(store, path);
+    }
+
+    @Override
+    public CheckedFuture<Void, TransactionCommitFailedException> submit() {
+        LOG.trace("{}: Submit", id);
+
+        final Future<Void> submit = delegate.submit();
+        final SettableFuture<Void> settFuture = SettableFuture.create();
+        final CheckedFuture<Void, TransactionCommitFailedException> checkedFuture;
+        checkedFuture = Futures.makeChecked(settFuture, new Function<Exception, TransactionCommitFailedException>() {
+            @Nullable
+            @Override
+            public TransactionCommitFailedException apply(Exception input) {
+                return new TransactionCommitFailedException("Transaction commit failed", input);
+            }
+        });
+        submit.onComplete(new OnComplete<Void>() {
+            @Override
+            public void onComplete(Throwable throwable, Void object) throws Throwable {
+                if (throwable == null) {
+                    settFuture.set(object);
+                } else {
+                    settFuture.setException(throwable);
+                }
+            }
+        }, actorSystem.dispatcher());
+        return checkedFuture;
+    }
+
+    @Override
+    public ListenableFuture<RpcResult<TransactionStatus>> commit() {
+        LOG.trace("{}: Commit", id);
+
+        final Future<Void> commit = delegate.submit();
+        final SettableFuture<RpcResult<TransactionStatus>> settFuture = SettableFuture.create();
+        commit.onComplete(new OnComplete<Void>() {
+            @Override
+            public void onComplete(final Throwable throwable, final Void result) throws Throwable {
+                if (throwable == null) {
+                    TransactionStatus status = TransactionStatus.SUBMITED;
+                    RpcResult<TransactionStatus> rpcResult = RpcResultBuilder.success(status).build();
+                    settFuture.set(rpcResult);
+                } else {
+                    settFuture.setException(throwable);
+                }
+            }
+        }, actorSystem.dispatcher());
+        return settFuture;
+    }
+
+    @Override
+    public Object getIdentifier() {
+        return this;
+    }
+}
diff --git a/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/utils/NetconfConnectorDTO.java b/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/utils/NetconfConnectorDTO.java
new file mode 100644 (file)
index 0000000..0657878
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.topology.singleton.impl.utils;
+
+import org.opendaylight.netconf.client.NetconfClientSessionListener;
+import org.opendaylight.netconf.sal.connect.api.RemoteDeviceHandler;
+import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfDeviceCommunicator;
+import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences;
+
+public class NetconfConnectorDTO implements AutoCloseable {
+
+    private final NetconfDeviceCommunicator communicator;
+    private final RemoteDeviceHandler<NetconfSessionPreferences> facade;
+
+    public NetconfConnectorDTO(final NetconfDeviceCommunicator communicator,
+                               final RemoteDeviceHandler<NetconfSessionPreferences> facade) {
+        this.communicator = communicator;
+        this.facade = facade;
+    }
+
+    public NetconfDeviceCommunicator getCommunicator() {
+        return communicator;
+    }
+
+    public RemoteDeviceHandler<NetconfSessionPreferences> getFacade() {
+        return facade;
+    }
+
+    public NetconfClientSessionListener getSessionListener() {
+        return communicator;
+    }
+
+    @Override
+    public void close() throws Exception {
+        if (communicator != null) {
+            communicator.close();
+        }
+        if (facade != null) {
+            facade.close();
+        }
+    }
+}
\ No newline at end of file
diff --git a/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/utils/NetconfTopologySetup.java b/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/utils/NetconfTopologySetup.java
new file mode 100644 (file)
index 0000000..d607f33
--- /dev/null
@@ -0,0 +1,254 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.topology.singleton.impl.utils;
+
+import akka.actor.ActorSystem;
+import io.netty.util.concurrent.EventExecutor;
+import org.opendaylight.controller.config.threadpool.ScheduledThreadPool;
+import org.opendaylight.controller.config.threadpool.ThreadPool;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.controller.sal.core.api.Broker;
+import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
+import org.opendaylight.netconf.client.NetconfClientDispatcher;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class NetconfTopologySetup {
+
+    private final ClusterSingletonServiceProvider clusterSingletonServiceProvider;
+    private final RpcProviderRegistry rpcProviderRegistry;
+    private final DataBroker dataBroker;
+    private final InstanceIdentifier<Node> instanceIdentifier;
+    private final Node node;
+    private final BindingAwareBroker bindingAwareBroker;
+    private final ScheduledThreadPool keepaliveExecutor;
+    private final ThreadPool processingExecutor;
+    private final Broker domBroker;
+    private final ActorSystem actorSystem;
+    private final EventExecutor eventExecutor;
+    private final NetconfClientDispatcher netconfClientDispatcher;
+    private final String topologyId;
+    private NetconfTopologySetup(final NetconfTopologySetupBuilder builder) {
+        this.clusterSingletonServiceProvider = builder.getClusterSingletonServiceProvider();
+        this.rpcProviderRegistry = builder.getRpcProviderRegistry();
+        this.dataBroker = builder.getDataBroker();
+        this.instanceIdentifier = builder.getInstanceIdentifier();
+        this.node = builder.getNode();
+        this.bindingAwareBroker = builder.getBindingAwareBroker();
+        this.keepaliveExecutor = builder.getKeepaliveExecutor();
+        this.processingExecutor = builder.getProcessingExecutor();
+        this.domBroker = builder.getDomBroker();
+        this.actorSystem = builder.getActorSystem();
+        this.eventExecutor = builder.getEventExecutor();
+        this.netconfClientDispatcher = builder.getNetconfClientDispatcher();
+        this.topologyId = builder.getTopologyId();
+    }
+
+    public ClusterSingletonServiceProvider getClusterSingletonServiceProvider() {
+        return clusterSingletonServiceProvider;
+    }
+
+    public RpcProviderRegistry getRpcProviderRegistry() {
+        return rpcProviderRegistry;
+    }
+
+    public DataBroker getDataBroker() {
+        return dataBroker;
+    }
+
+    public InstanceIdentifier<Node> getInstanceIdentifier() {
+        return instanceIdentifier;
+    }
+
+    public Node getNode() {
+        return node;
+    }
+
+    public BindingAwareBroker getBindingAwareBroker() {
+        return bindingAwareBroker;
+    }
+
+    public ThreadPool getProcessingExecutor() {
+        return processingExecutor;
+    }
+
+    public ScheduledThreadPool getKeepaliveExecutor() {
+        return keepaliveExecutor;
+    }
+
+    public Broker getDomBroker() {
+        return domBroker;
+    }
+
+    public ActorSystem getActorSystem() {
+        return actorSystem;
+    }
+
+    public EventExecutor getEventExecutor() {
+        return eventExecutor;
+    }
+
+    public String getTopologyId() {
+        return topologyId;
+    }
+
+    public NetconfClientDispatcher getNetconfClientDispatcher() {
+        return netconfClientDispatcher;
+    }
+
+    public static class NetconfTopologySetupBuilder {
+
+        private ClusterSingletonServiceProvider clusterSingletonServiceProvider;
+        private RpcProviderRegistry rpcProviderRegistry;
+        private DataBroker dataBroker;
+        private InstanceIdentifier<Node> instanceIdentifier;
+        private Node node;
+        private BindingAwareBroker bindingAwareBroker;
+        private ScheduledThreadPool keepaliveExecutor;
+        private ThreadPool processingExecutor;
+        private Broker domBroker;
+        private ActorSystem actorSystem;
+        private EventExecutor eventExecutor;
+        private String topologyId;
+        private NetconfClientDispatcher netconfClientDispatcher;
+
+        public NetconfTopologySetupBuilder(){
+        }
+
+        private ClusterSingletonServiceProvider getClusterSingletonServiceProvider() {
+            return clusterSingletonServiceProvider;
+        }
+
+        public NetconfTopologySetupBuilder setClusterSingletonServiceProvider(
+                final ClusterSingletonServiceProvider clusterSingletonServiceProvider) {
+            this.clusterSingletonServiceProvider = clusterSingletonServiceProvider;
+            return this;
+        }
+
+        private RpcProviderRegistry getRpcProviderRegistry() {
+            return rpcProviderRegistry;
+        }
+
+        public NetconfTopologySetupBuilder setRpcProviderRegistry(final RpcProviderRegistry rpcProviderRegistry) {
+            this.rpcProviderRegistry = rpcProviderRegistry;
+            return this;
+        }
+
+        private DataBroker getDataBroker() {
+            return dataBroker;
+        }
+
+        public NetconfTopologySetupBuilder setDataBroker(final DataBroker dataBroker) {
+            this.dataBroker = dataBroker;
+            return this;
+        }
+
+        private InstanceIdentifier<Node> getInstanceIdentifier() {
+            return instanceIdentifier;
+        }
+
+        public NetconfTopologySetupBuilder setInstanceIdentifier(final InstanceIdentifier<Node> instanceIdentifier) {
+            this.instanceIdentifier = instanceIdentifier;
+            return this;
+        }
+
+        public Node getNode() {
+            return node;
+        }
+
+        public NetconfTopologySetupBuilder setNode(final Node node) {
+            this.node = node;
+            return this;
+        }
+
+        public NetconfTopologySetup build() {
+            return new NetconfTopologySetup(this);
+        }
+
+        private BindingAwareBroker getBindingAwareBroker() {
+            return bindingAwareBroker;
+        }
+
+        public NetconfTopologySetupBuilder setBindingAwareBroker(BindingAwareBroker bindingAwareBroker) {
+            this.bindingAwareBroker = bindingAwareBroker;
+            return this;
+        }
+
+        private ScheduledThreadPool getKeepaliveExecutor() {
+            return keepaliveExecutor;
+        }
+
+        public NetconfTopologySetupBuilder setKeepaliveExecutor(ScheduledThreadPool keepaliveExecutor) {
+            this.keepaliveExecutor = keepaliveExecutor;
+            return this;
+        }
+
+        private ThreadPool getProcessingExecutor() {
+            return processingExecutor;
+        }
+
+        public NetconfTopologySetupBuilder setProcessingExecutor(ThreadPool processingExecutor) {
+            this.processingExecutor = processingExecutor;
+            return this;
+        }
+
+        private Broker getDomBroker() {
+            return domBroker;
+        }
+
+        public NetconfTopologySetupBuilder setDomBroker(Broker domBroker) {
+            this.domBroker = domBroker;
+            return this;
+        }
+
+        private ActorSystem getActorSystem() {
+            return actorSystem;
+        }
+
+        public NetconfTopologySetupBuilder setActorSystem(ActorSystem actorSystem) {
+            this.actorSystem = actorSystem;
+            return this;
+        }
+
+        private EventExecutor getEventExecutor() {
+            return eventExecutor;
+        }
+
+        public NetconfTopologySetupBuilder setEventExecutor(EventExecutor eventExecutor) {
+            this.eventExecutor = eventExecutor;
+            return this;
+        }
+
+        private String getTopologyId() {
+            return topologyId;
+        }
+
+        public NetconfTopologySetupBuilder setTopologyId(String topologyId) {
+            this.topologyId = topologyId;
+            return this;
+        }
+
+        private NetconfClientDispatcher getNetconfClientDispatcher() {
+            return netconfClientDispatcher;
+        }
+
+        public NetconfTopologySetupBuilder setNetconfClientDispatcher(NetconfClientDispatcher clientDispatcher) {
+            this.netconfClientDispatcher = clientDispatcher;
+            return this;
+        }
+
+        public static NetconfTopologySetupBuilder create() {
+            return new NetconfTopologySetupBuilder();
+        }
+    }
+
+
+}
diff --git a/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/utils/NetconfTopologyUtils.java b/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/utils/NetconfTopologyUtils.java
new file mode 100644 (file)
index 0000000..5114fae
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.topology.singleton.impl.utils;
+
+import akka.cluster.Member;
+import akka.util.Timeout;
+import java.io.File;
+import java.math.BigDecimal;
+import java.net.InetSocketAddress;
+import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
+import org.opendaylight.yangtools.yang.binding.Identifier;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
+import org.opendaylight.yangtools.yang.model.repo.api.SchemaContextFactory;
+import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceFilter;
+import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
+import org.opendaylight.yangtools.yang.model.repo.util.FilesystemSchemaSourceCache;
+import org.opendaylight.yangtools.yang.parser.repo.SharedSchemaRepository;
+import scala.concurrent.duration.Duration;
+
+public class NetconfTopologyUtils {
+
+    private static final String DEFAULT_SCHEMA_REPOSITORY_NAME = "sal-netconf-connector";
+
+    public static final Timeout TIMEOUT = new Timeout(Duration.create(10, "seconds"));
+
+    public static final long DEFAULT_REQUEST_TIMEOUT_MILLIS = 60000L;
+    public static final int DEFAULT_KEEPALIVE_DELAY = 0;
+    public static final boolean DEFAULT_RECONNECT_ON_CHANGED_SCHEMA = false;
+    public static final int DEFAULT_CONCURRENT_RPC_LIMIT = 0;
+    public static final int DEFAULT_MAX_CONNECTION_ATTEMPTS = 0;
+    public static final int DEFAULT_BETWEEN_ATTEMPTS_TIMEOUT_MILLIS = 2000;
+    public static final long DEFAULT_CONNECTION_TIMEOUT_MILLIS = 20000L;
+    public static final BigDecimal DEFAULT_SLEEP_FACTOR = new BigDecimal(1.5);
+
+
+    // The default cache directory relative to <code>CACHE_DIRECTORY</code>
+
+    public static final String DEFAULT_CACHE_DIRECTORY = "schema";
+
+    // Filesystem based caches are stored relative to the cache directory.
+    public static final String CACHE_DIRECTORY = "cache";
+
+    // The qualified schema cache directory <code>cache/schema</code>
+    public static final String QUALIFIED_DEFAULT_CACHE_DIRECTORY =
+            CACHE_DIRECTORY + File.separator + DEFAULT_CACHE_DIRECTORY;
+
+    // The default schema repository in the case that one is not specified.
+    public static final SharedSchemaRepository DEFAULT_SCHEMA_REPOSITORY =
+            new SharedSchemaRepository(DEFAULT_SCHEMA_REPOSITORY_NAME);
+
+
+     // The default <code>FilesystemSchemaSourceCache</code>, which stores cached files in <code>cache/schema</code>.
+    public static final FilesystemSchemaSourceCache<YangTextSchemaSource> DEFAULT_CACHE =
+            new FilesystemSchemaSourceCache<>(DEFAULT_SCHEMA_REPOSITORY, YangTextSchemaSource.class,
+                    new File(QUALIFIED_DEFAULT_CACHE_DIRECTORY));
+
+    // The default factory for creating <code>SchemaContext</code> instances.
+    public static final SchemaContextFactory DEFAULT_SCHEMA_CONTEXT_FACTORY =
+            DEFAULT_SCHEMA_REPOSITORY.createSchemaContextFactory(SchemaSourceFilter.ALWAYS_ACCEPT);
+
+    public static RemoteDeviceId createRemoteDeviceId(final NodeId nodeId, final NetconfNode node) {
+        IpAddress ipAddress = node.getHost().getIpAddress();
+        InetSocketAddress address = new InetSocketAddress(ipAddress.getIpv4Address() != null
+                ? ipAddress.getIpv4Address().getValue() : ipAddress.getIpv6Address().getValue(),
+                node.getPort().getValue());
+        return new RemoteDeviceId(nodeId.getValue(), address);
+    }
+
+    public static String createActorPath(String masterMember, String name) {
+        return  masterMember + "/user/" + name;
+    }
+
+    public static String createMasterActorName(String name, String masterAddress) {
+        return masterAddress.replaceAll("//", "") + "_" + name;
+    }
+
+    public static NodeId getNodeId(final InstanceIdentifier.PathArgument pathArgument) {
+        if (pathArgument instanceof InstanceIdentifier.IdentifiableItem<?, ?>) {
+
+            final Identifier key = ((InstanceIdentifier.IdentifiableItem) pathArgument).getKey();
+            if (key instanceof NodeKey) {
+                return ((NodeKey) key).getNodeId();
+            }
+        }
+        throw new IllegalStateException("Unable to create NodeId from: " + pathArgument);
+    }
+
+    public static KeyedInstanceIdentifier<Topology, TopologyKey> createTopologyListPath(final String topologyId) {
+        final InstanceIdentifier<NetworkTopology> networkTopology = InstanceIdentifier.create(NetworkTopology.class);
+        return networkTopology.child(Topology.class, new TopologyKey(new TopologyId(topologyId)));
+    }
+
+    public static InstanceIdentifier<Node> createTopologyNodeListPath(final NodeKey key, final String topologyId) {
+        return createTopologyListPath(topologyId)
+                .child(Node.class, new NodeKey(new NodeId(key.getNodeId().getValue())));
+    }
+
+    public static InstanceIdentifier<Node> createTopologyNodePath(final String topologyId) {
+        return createTopologyListPath(topologyId).child(Node.class);
+    }
+}
diff --git a/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/messages/AskForMasterMountPoint.java b/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/messages/AskForMasterMountPoint.java
new file mode 100644 (file)
index 0000000..4d56e1f
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.topology.singleton.messages;
+
+import java.io.Serializable;
+
+/**
+ * After master is connected, slaves send the message to master and master triggers registering slave mount point
+ * with reply 'RegisterMountPoint' which includes needed parameters.
+ */
+public class AskForMasterMountPoint implements Serializable {
+    private static final long serialVersionUID = 1L;
+}
diff --git a/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/messages/CreateInitialMasterActorData.java b/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/messages/CreateInitialMasterActorData.java
new file mode 100644 (file)
index 0000000..bab9056
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.topology.singleton.messages;
+
+import java.io.Serializable;
+import java.util.List;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
+
+/**
+ * Master sends this message to the own actor to set necessary parameters.
+ */
+public class CreateInitialMasterActorData implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    private final DOMDataBroker deviceDataBroker;
+    private final List<SourceIdentifier> allSourceIdentifiers;
+
+    public CreateInitialMasterActorData(final DOMDataBroker deviceDataBroker,
+                                        final List<SourceIdentifier> allSourceIdentifiers) {
+        this.deviceDataBroker = deviceDataBroker;
+        this.allSourceIdentifiers = allSourceIdentifiers;
+    }
+
+    public DOMDataBroker getDeviceDataBroker() {
+        return deviceDataBroker;
+    }
+
+    public List<SourceIdentifier> getSourceIndentifiers() {
+        return allSourceIdentifiers;
+    }
+}
diff --git a/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/messages/MasterActorDataInitialized.java b/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/messages/MasterActorDataInitialized.java
new file mode 100644 (file)
index 0000000..fa5482b
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.topology.singleton.messages;
+
+import java.io.Serializable;
+
+/**
+ * Due to possibility of race condition (when data-store is updated before data are initialized in master actor), only
+ * when this message is received by master, operational data-store is changed.
+ */
+public class MasterActorDataInitialized implements Serializable {
+    private static final long serialVersionUID = 1L;
+}
diff --git a/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/messages/NormalizedNodeMessage.java b/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/messages/NormalizedNodeMessage.java
new file mode 100644 (file)
index 0000000..b4ede5b
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.topology.singleton.messages;
+
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import org.opendaylight.controller.cluster.datastore.utils.SerializationUtils;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+/**
+ * Message which holds node data, prepared to sending between remote hosts with serialization.
+ */
+public class NormalizedNodeMessage implements Externalizable {
+    private static final long serialVersionUID = 1L;
+
+    private YangInstanceIdentifier identifier = null;
+    private NormalizedNode<?, ?> node = null;
+
+    public NormalizedNodeMessage() {
+        // empty constructor needed for Externalizable
+    }
+
+    public NormalizedNodeMessage(final YangInstanceIdentifier identifier, final NormalizedNode<?, ?> node) {
+        this.identifier = identifier;
+        this.node = node;
+    }
+
+    public YangInstanceIdentifier getIdentifier() {
+        return identifier;
+    }
+
+    public NormalizedNode<?, ?> getNode() {
+        return node;
+    }
+
+    @Override
+    public void writeExternal(final ObjectOutput out) throws IOException {
+        SerializationUtils.serializePathAndNode(getIdentifier(), node, out);
+    }
+
+    @Override
+    public void readExternal(final ObjectInput in) throws IOException, ClassNotFoundException {
+        SerializationUtils.deserializePathAndNode(in, this, APPLIER);
+    }
+
+    private static final SerializationUtils.Applier<NormalizedNodeMessage> APPLIER = (instance, path, node) -> {
+        instance.identifier = path;
+        instance.node = node;
+    };
+}
diff --git a/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/messages/RefreshSetupMasterActorData.java b/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/messages/RefreshSetupMasterActorData.java
new file mode 100644 (file)
index 0000000..fbc43f7
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.topology.singleton.messages;
+
+import java.io.Serializable;
+import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
+import org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologySetup;
+
+/**
+ * Master sends this message to the own actor to refresh setup data
+ */
+public class RefreshSetupMasterActorData implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    private final NetconfTopologySetup netconfTopologyDeviceSetup;
+    private final RemoteDeviceId remoteDeviceId;
+
+    public RefreshSetupMasterActorData(final NetconfTopologySetup netconfTopologyDeviceSetup,
+                                       final RemoteDeviceId remoteDeviceId) {
+        this.netconfTopologyDeviceSetup = netconfTopologyDeviceSetup;
+        this.remoteDeviceId = remoteDeviceId;
+    }
+
+    public NetconfTopologySetup getNetconfTopologyDeviceSetup() {
+        return netconfTopologyDeviceSetup;
+    }
+
+    public RemoteDeviceId getRemoteDeviceId() {
+        return remoteDeviceId;
+    }
+}
diff --git a/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/messages/RegisterMountPoint.java b/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/messages/RegisterMountPoint.java
new file mode 100644 (file)
index 0000000..0023103
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.topology.singleton.messages;
+
+import java.io.Serializable;
+import java.util.List;
+import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
+
+/**
+ * Master sends the message to slave with necessary parameters for creating slave mount point.
+ */
+public class RegisterMountPoint implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    private final List<SourceIdentifier> allSourceIdentifiers;
+
+    public RegisterMountPoint(final List<SourceIdentifier> allSourceIdentifiers) {
+        this.allSourceIdentifiers = allSourceIdentifiers;
+    }
+
+    public List<SourceIdentifier> getSourceIndentifiers() {
+        return allSourceIdentifiers;
+    }
+
+}
diff --git a/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/messages/UnregisterSlaveMountPoint.java b/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/messages/UnregisterSlaveMountPoint.java
new file mode 100644 (file)
index 0000000..303f0b4
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.topology.singleton.messages;
+
+import java.io.Serializable;
+
+/**
+ * Slave sends the message when unregisters slave mount point (in NetconfNodeManager
+ * close method). Message must be sended before slave actor is poisoned.
+ */
+public class UnregisterSlaveMountPoint implements Serializable {
+    private static final long serialVersionUID = 1L;
+}
diff --git a/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/messages/YangTextSchemaSourceRequest.java b/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/messages/YangTextSchemaSourceRequest.java
new file mode 100644 (file)
index 0000000..ffc3d13
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.topology.singleton.messages;
+
+import java.io.Serializable;
+import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
+
+/**
+ * Slave sends message to master when tries to resolve schema with particular sourceIdentifier (proxy call).
+ * Master responds with resolved schema source.
+ */
+public class YangTextSchemaSourceRequest implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    private final SourceIdentifier sourceIdentifier;
+
+    public YangTextSchemaSourceRequest(final SourceIdentifier sourceIdentifier) {
+        this.sourceIdentifier = sourceIdentifier;
+    }
+
+    public SourceIdentifier getSourceIdentifier() {
+        return sourceIdentifier;
+    }
+}
diff --git a/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/messages/transactions/CancelRequest.java b/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/messages/transactions/CancelRequest.java
new file mode 100644 (file)
index 0000000..7a73fe2
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.topology.singleton.messages.transactions;
+
+public class CancelRequest implements TransactionRequest {
+    private static final long serialVersionUID = 1L;
+}
diff --git a/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/messages/transactions/DeleteRequest.java b/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/messages/transactions/DeleteRequest.java
new file mode 100644 (file)
index 0000000..1548dc7
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.topology.singleton.messages.transactions;
+
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+
+public class DeleteRequest implements TransactionRequest {
+    private static final long serialVersionUID = 1L;
+
+    private final LogicalDatastoreType store;
+    private final YangInstanceIdentifier path;
+
+    public DeleteRequest(final LogicalDatastoreType store, final YangInstanceIdentifier path) {
+        this.store = store;
+        this.path = path;
+    }
+
+    public LogicalDatastoreType getStore() {
+        return store;
+    }
+
+    public YangInstanceIdentifier getPath() {
+        return path;
+    }
+}
@@ -1,17 +1,18 @@
 /*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
 
-package org.opendaylight.netconf.topology.util.messages;
+package org.opendaylight.netconf.topology.singleton.messages.transactions;
 
 import java.io.Serializable;
 
-public class AnnounceMasterMountPoint implements Serializable {
+/**
+ * Message is sended when read result do not present any value.
+ */
+public class EmptyReadResponse implements Serializable {
     private static final long serialVersionUID = 1L;
-
-    public AnnounceMasterMountPoint() {}
 }
diff --git a/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/messages/transactions/ExistsRequest.java b/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/messages/transactions/ExistsRequest.java
new file mode 100644 (file)
index 0000000..b5fae5f
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.topology.singleton.messages.transactions;
+
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+
+public class ExistsRequest implements TransactionRequest {
+    private static final long serialVersionUID = 1L;
+
+    private final LogicalDatastoreType store;
+    private final YangInstanceIdentifier path;
+
+    public ExistsRequest(final LogicalDatastoreType store, final YangInstanceIdentifier path) {
+        this.store = store;
+        this.path = path;
+    }
+
+    public LogicalDatastoreType getStore() {
+        return store;
+    }
+
+    public YangInstanceIdentifier getPath() {
+        return path;
+    }
+}
diff --git a/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/messages/transactions/MergeRequest.java b/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/messages/transactions/MergeRequest.java
new file mode 100644 (file)
index 0000000..8c03023
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.topology.singleton.messages.transactions;
+
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.netconf.topology.singleton.messages.NormalizedNodeMessage;
+
+public class MergeRequest implements TransactionRequest {
+    private static final long serialVersionUID = 1L;
+
+    private final NormalizedNodeMessage data;
+    private final LogicalDatastoreType store;
+
+    public MergeRequest(final LogicalDatastoreType store, final NormalizedNodeMessage data) {
+        this.store = store;
+        this.data = data;
+    }
+
+    public NormalizedNodeMessage getNormalizedNodeMessage() {
+        return data;
+    }
+
+    public LogicalDatastoreType getStore() {
+        return store;
+    }
+}
diff --git a/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/messages/transactions/PutRequest.java b/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/messages/transactions/PutRequest.java
new file mode 100644 (file)
index 0000000..41de9c2
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.topology.singleton.messages.transactions;
+
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.netconf.topology.singleton.messages.NormalizedNodeMessage;
+
+public class PutRequest implements TransactionRequest {
+    private static final long serialVersionUID = 1L;
+
+    private final LogicalDatastoreType store;
+    private final NormalizedNodeMessage data;
+
+    public PutRequest(final LogicalDatastoreType store, final NormalizedNodeMessage data) {
+        this.store = store;
+        this.data = data;
+    }
+
+    public NormalizedNodeMessage getNormalizedNodeMessage() {
+        return data;
+    }
+
+    public LogicalDatastoreType getStore() {
+        return store;
+    }
+}
diff --git a/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/messages/transactions/ReadRequest.java b/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/messages/transactions/ReadRequest.java
new file mode 100644 (file)
index 0000000..d950f28
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.topology.singleton.messages.transactions;
+
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+
+public class ReadRequest implements TransactionRequest {
+    private static final long serialVersionUID = 1L;
+
+    private final LogicalDatastoreType store;
+    private final YangInstanceIdentifier path;
+
+    public ReadRequest(final LogicalDatastoreType store, final YangInstanceIdentifier path) {
+        this.store = store;
+        this.path = path;
+    }
+
+    public LogicalDatastoreType getStore() {
+        return store;
+    }
+
+    public YangInstanceIdentifier getPath() {
+        return path;
+    }
+}
diff --git a/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/messages/transactions/SubmitFailedReply.java b/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/messages/transactions/SubmitFailedReply.java
new file mode 100644 (file)
index 0000000..fe077e2
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.topology.singleton.messages.transactions;
+
+import java.io.Serializable;
+
+/**
+ * Message sent from master back to the slave when submit is not performed, tx is closed
+ */
+public class SubmitFailedReply implements Serializable {
+    private static final long serialVersionUID = 1L;
+}
@@ -1,19 +1,18 @@
 /*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
 
-package org.opendaylight.netconf.topology.util.messages;
+package org.opendaylight.netconf.topology.singleton.messages.transactions;
 
 import java.io.Serializable;
 
-public class AnnounceMasterMountPointDown implements Serializable {
+/**
+ * Message sent from master back to the slave when submit is successfully performed.
+ */
+public class SubmitReply implements Serializable {
     private static final long serialVersionUID = 1L;
-
-    public AnnounceMasterMountPointDown() {
-
-    }
 }
diff --git a/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/messages/transactions/SubmitRequest.java b/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/messages/transactions/SubmitRequest.java
new file mode 100644 (file)
index 0000000..6b6af7e
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.topology.singleton.messages.transactions;
+
+public class SubmitRequest implements TransactionRequest {
+    private static final long serialVersionUID = 1L;
+}
diff --git a/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/messages/transactions/TransactionRequest.java b/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/messages/transactions/TransactionRequest.java
new file mode 100644 (file)
index 0000000..b5ef9f1
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.topology.singleton.messages.transactions;
+
+import java.io.Serializable;
+
+/**
+ * API for transaction request messages, slave sends these message types to master for performing required operation.
+ * This interface helps better handle request messages in actor. All messages are send with operations defined in
+ * NetconfProxyDOMTransaction. Messages requiring response are send by ask otherwise with tell.
+ */
+public interface TransactionRequest extends Serializable {
+}
diff --git a/netconf/netconf-topology-singleton/src/main/resources/org/opendaylight/blueprint/netconf-topology-singleton.xml b/netconf/netconf-topology-singleton/src/main/resources/org/opendaylight/blueprint/netconf-topology-singleton.xml
new file mode 100644 (file)
index 0000000..8fced19
--- /dev/null
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<!--
+Copyright Â© 2016 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
+-->
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
+           xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0"
+           odl:use-default-for-reference-types="true">
+
+    <reference id="dataBroker"
+               interface="org.opendaylight.controller.md.sal.binding.api.DataBroker"/>
+    <reference id="rpcRegistry"
+               interface="org.opendaylight.controller.sal.binding.api.RpcProviderRegistry"/>
+    <reference id="clusterSingletonService"
+               interface="org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider"/>
+    <reference id="bindingAwareBroker"
+               interface="org.opendaylight.controller.sal.binding.api.BindingAwareBroker"/>
+    <reference id="keepAliveExecutor"
+               interface="org.opendaylight.controller.config.threadpool.ScheduledThreadPool"/>
+    <reference id="processingExecutor"
+               interface="org.opendaylight.controller.config.threadpool.ThreadPool"/>
+    <reference id="domBroker"
+               interface="org.opendaylight.controller.sal.core.api.Broker"/>
+    <reference id="actorSystemProvider"
+               interface="org.opendaylight.controller.cluster.ActorSystemProvider"/>
+    <reference id="eventExecutor"
+               interface="io.netty.util.concurrent.EventExecutor"
+               odl:type="global-event-executor"/>
+    <reference id="clientDispatcherDependency"
+               interface="org.opendaylight.netconf.client.NetconfClientDispatcher"/>
+
+    <bean id="netconfTopologyManager"
+          class="org.opendaylight.netconf.topology.singleton.impl.NetconfTopologyManager"
+          init-method="init" destroy-method="close">
+        <argument ref="dataBroker"/>
+        <argument ref="rpcRegistry"/>
+        <argument ref="clusterSingletonService"/>
+        <argument ref="bindingAwareBroker"/>
+        <argument ref="keepAliveExecutor"/>
+        <argument ref="processingExecutor"/>
+        <argument ref="domBroker"/>
+        <argument ref="actorSystemProvider"/>
+        <argument ref="eventExecutor"/>
+        <argument ref="clientDispatcherDependency"/>
+        <argument value="topology-netconf"/>
+    </bean>
+    <service ref="netconfTopologyManager"
+             interface="org.opendaylight.netconf.topology.singleton.api.NetconfTopologySingletonService"/>
+
+</blueprint>
diff --git a/netconf/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/NetconfNodeActorTest.java b/netconf/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/NetconfNodeActorTest.java
new file mode 100644 (file)
index 0000000..a77104e
--- /dev/null
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.topology.singleton.impl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologyUtils.DEFAULT_SCHEMA_REPOSITORY;
+
+import akka.actor.ActorContext;
+import akka.actor.ActorRef;
+import akka.actor.ActorSystem;
+import akka.actor.Props;
+import akka.pattern.Patterns;
+import akka.testkit.JavaTestKit;
+import akka.testkit.TestActorRef;
+import akka.util.Timeout;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Optional;
+import com.google.common.collect.Lists;
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.Futures;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.UnknownHostException;
+import java.util.List;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.opendaylight.controller.cluster.schema.provider.impl.YangTextSchemaSourceSerializationProxy;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
+import org.opendaylight.netconf.topology.singleton.impl.actors.NetconfNodeActor;
+import org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologySetup;
+import org.opendaylight.netconf.topology.singleton.messages.AskForMasterMountPoint;
+import org.opendaylight.netconf.topology.singleton.messages.CreateInitialMasterActorData;
+import org.opendaylight.netconf.topology.singleton.messages.MasterActorDataInitialized;
+import org.opendaylight.netconf.topology.singleton.messages.RefreshSetupMasterActorData;
+import org.opendaylight.netconf.topology.singleton.messages.RegisterMountPoint;
+import org.opendaylight.yangtools.yang.model.repo.api.MissingSchemaSourceException;
+import org.opendaylight.yangtools.yang.model.repo.api.SchemaRepository;
+import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceException;
+import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
+import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
+import scala.concurrent.Await;
+import scala.concurrent.Future;
+import scala.concurrent.duration.Duration;
+
+public class NetconfNodeActorTest {
+
+    private static final Timeout TIMEOUT = new Timeout(Duration.create(5, "seconds"));
+    private static ActorSystem system;
+
+    @Rule
+    public final ExpectedException exception = ExpectedException.none();
+
+    private ActorRef masterRef;
+    private RemoteDeviceId remoteDeviceId;
+
+    @Before
+    public void setup() throws UnknownHostException {
+
+        remoteDeviceId = new RemoteDeviceId("netconf-topology",
+                new InetSocketAddress(InetAddress.getByName("127.0.0.1"), 9999));
+
+        final NetconfTopologySetup setup = mock(NetconfTopologySetup.class);
+
+        final Props props = NetconfNodeActor.props(setup, remoteDeviceId, DEFAULT_SCHEMA_REPOSITORY,
+                DEFAULT_SCHEMA_REPOSITORY);
+
+        system = ActorSystem.create();
+
+        masterRef = TestActorRef.create(system, props, "master_messages");
+    }
+
+    @After
+    public void teardown() {
+        JavaTestKit.shutdownActorSystem(system);
+        system = null;
+    }
+
+    @Test
+    public void testInitDataMessages() throws Exception {
+
+        final DOMDataBroker domDataBroker = mock(DOMDataBroker.class);
+        final List<SourceIdentifier> sourceIdentifiers = Lists.newArrayList();
+
+        /* Test init master data */
+
+        final Future<Object> initialDataToActor =
+                Patterns.ask(masterRef, new CreateInitialMasterActorData(domDataBroker, sourceIdentifiers),
+                        TIMEOUT);
+
+        final Object success = Await.result(initialDataToActor, TIMEOUT.duration());
+        assertTrue(success instanceof MasterActorDataInitialized);
+
+
+        /* Test refresh master data */
+
+        final RemoteDeviceId remoteDeviceId2 = new RemoteDeviceId("netconf-topology2",
+                new InetSocketAddress(InetAddress.getByName("127.0.0.2"), 9999));
+
+        final NetconfTopologySetup setup2 = mock(NetconfTopologySetup.class);
+
+        final Future<Object> refreshDataToActor =
+                Patterns.ask(masterRef, new RefreshSetupMasterActorData(setup2, remoteDeviceId2),
+                        TIMEOUT);
+
+        final Object success2 = Await.result(refreshDataToActor, TIMEOUT.duration());
+        assertTrue(success2 instanceof MasterActorDataInitialized);
+
+    }
+
+    @Test
+    public void testRegisterMountPointMessage() throws Exception {
+
+        final DOMDataBroker domDataBroker = mock(DOMDataBroker.class);
+        final List<SourceIdentifier> sourceIdentifiers =
+                Lists.newArrayList(SourceIdentifier.create("testID", Optional.absent()));
+
+        // init master data
+
+        final Future<Object> initialDataToActor =
+                Patterns.ask(masterRef, new CreateInitialMasterActorData(domDataBroker, sourceIdentifiers),
+                        TIMEOUT);
+
+        final Object successInit = Await.result(initialDataToActor, TIMEOUT.duration());
+
+        assertTrue(successInit instanceof MasterActorDataInitialized);
+
+        // test if slave get right identifiers from master
+
+        final Future<Object> registerMountPointFuture =
+                Patterns.ask(masterRef, new AskForMasterMountPoint(),
+                        TIMEOUT);
+
+        final RegisterMountPoint success =
+                (RegisterMountPoint) Await.result(registerMountPointFuture, TIMEOUT.duration());
+
+        assertEquals(sourceIdentifiers, success.getSourceIndentifiers());
+
+    }
+
+    @Test
+    public void testYangTextSchemaSourceRequestMessage() throws Exception {
+        final SchemaRepository schemaRepository = mock(SchemaRepository.class);
+        final SourceIdentifier sourceIdentifier = SourceIdentifier.create("testID", Optional.absent());
+        final Props props = NetconfNodeActor.props(mock(NetconfTopologySetup.class), remoteDeviceId,
+                DEFAULT_SCHEMA_REPOSITORY, schemaRepository);
+
+        final ActorRef actorRefSchemaRepo = TestActorRef.create(system, props, "master_mocked_schema_repository");
+        final ActorContext actorContext = mock(ActorContext.class);
+        doReturn(system.dispatcher()).when(actorContext).dispatcher();
+
+        final ProxyYangTextSourceProvider proxyYang =
+                new ProxyYangTextSourceProvider(actorRefSchemaRepo, actorContext);
+        // test if asking for source is resolved and sended back
+
+        final YangTextSchemaSource yangTextSchemaSource = new YangTextSchemaSource(sourceIdentifier) {
+            @Override
+            protected MoreObjects.ToStringHelper addToStringAttributes(MoreObjects.ToStringHelper toStringHelper) {
+                return null;
+            }
+
+            @Override
+            public InputStream openStream() throws IOException {
+                return new ByteArrayInputStream("YANG".getBytes());
+            }
+        };
+
+
+        final CheckedFuture<YangTextSchemaSource, SchemaSourceException> result =
+                Futures.immediateCheckedFuture(yangTextSchemaSource);
+
+        doReturn(result).when(schemaRepository).getSchemaSource(sourceIdentifier, YangTextSchemaSource.class);
+
+        final Future<YangTextSchemaSourceSerializationProxy> resolvedSchema =
+                proxyYang.getYangTextSchemaSource(sourceIdentifier);
+
+        final YangTextSchemaSourceSerializationProxy success = Await.result(resolvedSchema, TIMEOUT.duration());
+
+        assertEquals(sourceIdentifier, success.getRepresentation().getIdentifier());
+        assertEquals("YANG", convertStreamToString(success.getRepresentation().openStream()));
+
+
+        // test if asking for source is missing
+        exception.expect(MissingSchemaSourceException.class);
+
+        final SchemaSourceException schemaSourceException =
+                new MissingSchemaSourceException("Fail", sourceIdentifier);
+
+        final CheckedFuture<YangTextSchemaSource, SchemaSourceException> resultFail =
+                Futures.immediateFailedCheckedFuture(schemaSourceException);
+
+        doReturn(resultFail).when(schemaRepository).getSchemaSource(sourceIdentifier, YangTextSchemaSource.class);
+
+        final Future<YangTextSchemaSourceSerializationProxy> failedSchema =
+                proxyYang.getYangTextSchemaSource(sourceIdentifier);
+
+        Await.result(failedSchema, TIMEOUT.duration());
+
+    }
+
+    private String convertStreamToString(java.io.InputStream is) {
+        java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
+        return s.hasNext() ? s.next() : "";
+    }
+
+}
diff --git a/netconf/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/NetconfTopologyManagerTest.java b/netconf/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/NetconfTopologyManagerTest.java
new file mode 100644 (file)
index 0000000..9a3749c
--- /dev/null
@@ -0,0 +1,271 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.topology.singleton.impl;
+
+import static junit.framework.TestCase.assertFalse;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.MockitoAnnotations.initMocks;
+import static org.opendaylight.controller.md.sal.binding.api.DataObjectModification.ModificationType.DELETE;
+import static org.opendaylight.controller.md.sal.binding.api.DataObjectModification.ModificationType.WRITE;
+
+import com.google.common.util.concurrent.Futures;
+import io.netty.util.concurrent.EventExecutor;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Map;
+import javax.annotation.Nonnull;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.opendaylight.controller.cluster.ActorSystemProvider;
+import org.opendaylight.controller.config.threadpool.ScheduledThreadPool;
+import org.opendaylight.controller.config.threadpool.ThreadPool;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.controller.sal.core.api.Broker;
+import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
+import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration;
+import org.opendaylight.netconf.client.NetconfClientDispatcher;
+import org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologyUtils;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Host;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
+import org.opendaylight.yangtools.yang.binding.Identifier;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class NetconfTopologyManagerTest {
+
+    private final String topologyId = "topologyID";
+    private NetconfTopologyManager netconfTopologyManager;
+
+    @Mock
+    private DataBroker dataBroker;
+
+    @Mock
+    private ClusterSingletonServiceProvider clusterSingletonServiceProvider;
+
+    @Before
+    public void setUp() {
+        initMocks(this);
+
+        final RpcProviderRegistry rpcProviderRegistry = mock(RpcProviderRegistry.class);
+        final BindingAwareBroker bindingAwareBroker = mock(BindingAwareBroker.class);
+        final ScheduledThreadPool keepaliveExecutor = mock(ScheduledThreadPool.class);
+        final ThreadPool processingExecutor = mock(ThreadPool.class);
+        final Broker domBroker = mock(Broker.class);
+        final ActorSystemProvider actorSystemProvider = mock(ActorSystemProvider.class);
+        final EventExecutor eventExecutor = mock(EventExecutor.class);
+        final NetconfClientDispatcher clientDispatcher = mock(NetconfClientDispatcher.class);
+
+        netconfTopologyManager = new NetconfTopologyManager(dataBroker, rpcProviderRegistry,
+                clusterSingletonServiceProvider, bindingAwareBroker, keepaliveExecutor, processingExecutor, domBroker,
+                actorSystemProvider, eventExecutor, clientDispatcher, topologyId);
+    }
+    @Test
+    public void testWriteConfiguration() throws Exception {
+
+        final ClusterSingletonServiceRegistration clusterRegistration = mock(ClusterSingletonServiceRegistration.class);
+
+        final Field fieldContexts = NetconfTopologyManager.class.getDeclaredField("contexts");
+        fieldContexts.setAccessible(true);
+        @SuppressWarnings("unchecked")
+        final Map<InstanceIdentifier<Node>, NetconfTopologyContext> contexts =
+                (Map<InstanceIdentifier<Node>, NetconfTopologyContext>) fieldContexts.get(netconfTopologyManager);
+
+        final Field fieldClusterRegistrations = NetconfTopologyManager.class.getDeclaredField("clusterRegistrations");
+        fieldClusterRegistrations.setAccessible(true);
+        @SuppressWarnings("unchecked")
+        final Map<InstanceIdentifier<Node>, ClusterSingletonServiceRegistration> clusterRegistrations =
+                (Map<InstanceIdentifier<Node>, ClusterSingletonServiceRegistration>)
+                        fieldClusterRegistrations.get(netconfTopologyManager);
+
+        final Collection<DataTreeModification<Node>> changes = new ArrayList<>();
+
+        final InstanceIdentifier<Node> instanceIdentifier = NetconfTopologyUtils.createTopologyNodeListPath(
+                new NodeKey(new NodeId("node-id-1")),"topology-1");
+
+        final InstanceIdentifier<Node> instanceIdentifierDiferent = NetconfTopologyUtils.createTopologyNodeListPath(
+                new NodeKey(new NodeId("node-id-2")),"topology-2");
+
+        final DataTreeIdentifier<Node> rootIdentifier =
+                new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION, instanceIdentifier);
+
+        final DataTreeIdentifier<Node> rootIdentifierDifferent =
+                new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION, instanceIdentifierDiferent);
+
+        @SuppressWarnings("unchecked")
+        final DataObjectModification<Node> objectModification = mock(DataObjectModification.class);
+
+        final NetconfNode netconfNode = new NetconfNodeBuilder()
+                .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
+                .setPort(new PortNumber(9999))
+                .setReconnectOnChangedSchema(true)
+                .setDefaultRequestTimeoutMillis(1000L)
+                .setBetweenAttemptsTimeoutMillis(100)
+                .setSchemaless(false)
+                .setTcpOnly(false)
+                .build();
+        final Node node = new NodeBuilder().setNodeId(new NodeId("node-id"))
+                .addAugmentation(NetconfNode.class, netconfNode).build();
+
+        final Identifier key = new NodeKey(new NodeId("node-id"));
+
+        @SuppressWarnings("unchecked")
+        final InstanceIdentifier.IdentifiableItem<Node, NodeKey> pathArgument =
+                new InstanceIdentifier.IdentifiableItem(Node.class, key);
+
+
+        // testing WRITE on two identical rootIdentifiers and one different
+
+        changes.add(new CustomTreeModification(rootIdentifier, objectModification));
+        changes.add(new CustomTreeModification(rootIdentifier, objectModification));
+        changes.add(new CustomTreeModification(rootIdentifierDifferent, objectModification));
+
+        doReturn(WRITE).when(objectModification).getModificationType();
+        doReturn(node).when(objectModification).getDataAfter();
+        doReturn(pathArgument).when(objectModification).getIdentifier();
+        doReturn(clusterRegistration).when(clusterSingletonServiceProvider).registerClusterSingletonService(any());
+
+        netconfTopologyManager.onDataTreeChanged(changes);
+
+        verify(clusterSingletonServiceProvider, times(2)).registerClusterSingletonService(any());
+
+        // only two created contexts
+        assertEquals(2, contexts.size());
+        assertTrue(contexts.containsKey(rootIdentifier.getRootIdentifier()));
+        assertTrue(contexts.containsKey(rootIdentifierDifferent.getRootIdentifier()));
+
+        // only two created cluster registrations
+        assertEquals(2, contexts.size());
+        assertTrue(clusterRegistrations.containsKey(rootIdentifier.getRootIdentifier()));
+        assertTrue(clusterRegistrations.containsKey(rootIdentifierDifferent.getRootIdentifier()));
+
+        // after delete there should be no context and clustered registrations
+        doReturn(DELETE).when(objectModification).getModificationType();
+
+        doNothing().when(clusterRegistration).close();
+
+        netconfTopologyManager.onDataTreeChanged(changes);
+
+        verify(clusterRegistration, times(2)).close();
+
+        // empty map of contexts
+        assertTrue(contexts.isEmpty());
+        assertFalse(contexts.containsKey(rootIdentifier.getRootIdentifier()));
+        assertFalse(contexts.containsKey(rootIdentifierDifferent.getRootIdentifier()));
+
+        // empty map of clustered registrations
+        assertTrue(clusterRegistrations.isEmpty());
+        assertFalse(clusterRegistrations.containsKey(rootIdentifier.getRootIdentifier()));
+        assertFalse(clusterRegistrations.containsKey(rootIdentifierDifferent.getRootIdentifier()));
+
+    }
+
+    @Test
+    public void testRegisterDataTreeChangeListener() {
+
+        final WriteTransaction wtx = mock(WriteTransaction.class);
+
+        doReturn(wtx).when(dataBroker).newWriteOnlyTransaction();
+        doNothing().when(wtx).merge(any(), any(), any());
+        doReturn(Futures.immediateCheckedFuture(null)).when(wtx).submit();
+        doReturn(null).when(dataBroker).registerDataChangeListener(any(), any(), any(), any());
+
+        netconfTopologyManager.init();
+
+        // verify if listener is called with right parameters = registered on right path
+
+        verify(dataBroker, times(1)).registerDataTreeChangeListener(
+                new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION, NetconfTopologyUtils
+                        .createTopologyListPath(topologyId).child(Node.class)), netconfTopologyManager);
+
+    }
+
+    @Test
+    public void testClose() throws Exception {
+
+        final Field fieldContexts = NetconfTopologyManager.class.getDeclaredField("contexts");
+        fieldContexts.setAccessible(true);
+        @SuppressWarnings("unchecked")
+        final Map<InstanceIdentifier<Node>, NetconfTopologyContext> contexts =
+                (Map<InstanceIdentifier<Node>, NetconfTopologyContext>) fieldContexts.get(netconfTopologyManager);
+
+        final Field fieldClusterRegistrations = NetconfTopologyManager.class.getDeclaredField("clusterRegistrations");
+        fieldClusterRegistrations.setAccessible(true);
+        @SuppressWarnings("unchecked")
+        final Map<InstanceIdentifier<Node>, ClusterSingletonServiceRegistration> clusterRegistrations =
+                (Map<InstanceIdentifier<Node>, ClusterSingletonServiceRegistration>)
+                        fieldClusterRegistrations.get(netconfTopologyManager);
+
+        final InstanceIdentifier<Node> instanceIdentifier = NetconfTopologyUtils.createTopologyNodeListPath(
+                new NodeKey(new NodeId("node-id-1")),"topology-1");
+
+
+        final NetconfTopologyContext context = mock(NetconfTopologyContext.class);
+        final ClusterSingletonServiceRegistration clusterRegistration =
+                mock(ClusterSingletonServiceRegistration.class);
+        contexts.put(instanceIdentifier, context);
+        clusterRegistrations.put(instanceIdentifier, clusterRegistration);
+
+        doNothing().when(context).closeFinal();
+        doNothing().when(clusterRegistration).close();
+
+        netconfTopologyManager.close();
+        verify(context, times(1)).closeFinal();
+        verify(clusterRegistration, times(1)).close();
+
+        assertTrue(contexts.isEmpty());
+        assertTrue(clusterRegistrations.isEmpty());
+
+    }
+
+    private class CustomTreeModification  implements DataTreeModification<Node> {
+
+        private final DataTreeIdentifier<Node> rootPath;
+        private final DataObjectModification<Node> rootNode;
+
+        CustomTreeModification(DataTreeIdentifier<Node> rootPath, DataObjectModification<Node> rootNode) {
+            this.rootPath = rootPath;
+            this.rootNode = rootNode;
+        }
+
+        @Nonnull
+        @Override
+        public DataTreeIdentifier<Node> getRootPath() {
+            return rootPath;
+        }
+
+        @Nonnull
+        @Override
+        public DataObjectModification<Node> getRootNode() {
+            return rootNode;
+        }
+    }
+}
diff --git a/netconf/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/RemoteDeviceConnectorImplTest.java b/netconf/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/RemoteDeviceConnectorImplTest.java
new file mode 100644 (file)
index 0000000..c1515ab
--- /dev/null
@@ -0,0 +1,271 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.topology.singleton.impl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.MockitoAnnotations.initMocks;
+
+import akka.actor.ActorRef;
+import akka.actor.ActorSystem;
+import io.netty.util.concurrent.EventExecutor;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.UnknownHostException;
+import java.util.concurrent.ExecutorService;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.opendaylight.controller.config.threadpool.ScheduledThreadPool;
+import org.opendaylight.controller.config.threadpool.ThreadPool;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.controller.sal.core.api.Broker;
+import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
+import org.opendaylight.netconf.client.NetconfClientDispatcher;
+import org.opendaylight.netconf.client.NetconfClientSessionListener;
+import org.opendaylight.netconf.client.conf.NetconfClientConfiguration;
+import org.opendaylight.netconf.client.conf.NetconfReconnectingClientConfiguration;
+import org.opendaylight.netconf.sal.connect.api.RemoteDeviceHandler;
+import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfDeviceCommunicator;
+import org.opendaylight.netconf.sal.connect.netconf.sal.KeepaliveSalFacade;
+import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
+import org.opendaylight.netconf.topology.singleton.impl.utils.NetconfConnectorDTO;
+import org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologySetup;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Host;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.credentials.Credentials;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.credentials.credentials.LoginPasswordBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
+
+public class RemoteDeviceConnectorImplTest {
+
+    private static final NodeId NODE_ID = new NodeId("testing-node");
+    private static final String TOPOLOGY_ID = "testing-topology";
+
+    @Mock
+    private DataBroker dataBroker;
+
+    @Mock
+    private RpcProviderRegistry rpcProviderRegistry;
+
+    @Mock
+    private ClusterSingletonServiceProvider clusterSingletonServiceProvider;
+
+    @Mock
+    private BindingAwareBroker bindingAwareBroker;
+
+    @Mock
+    private ScheduledThreadPool keepaliveExecutor;
+
+    @Mock
+    private ThreadPool processingExecutor;
+
+    @Mock
+    private Broker domBroker;
+
+    @Mock
+    private ActorSystem actorSystem;
+
+    @Mock
+    private EventExecutor eventExecutor;
+
+    @Mock
+    private NetconfClientDispatcher clientDispatcher;
+
+    private NetconfTopologySetup.NetconfTopologySetupBuilder builder;
+    private RemoteDeviceId remoteDeviceId;
+
+    @Before
+    public void setUp() throws UnknownHostException {
+        initMocks(this);
+
+        remoteDeviceId = new RemoteDeviceId(TOPOLOGY_ID,
+                new InetSocketAddress(InetAddress.getByName("127.0.0.1"), 9999));
+
+        builder = new NetconfTopologySetup.NetconfTopologySetupBuilder();
+        builder.setDataBroker(dataBroker);
+        builder.setRpcProviderRegistry(rpcProviderRegistry);
+        builder.setClusterSingletonServiceProvider(clusterSingletonServiceProvider);
+        builder.setBindingAwareBroker(bindingAwareBroker);
+        builder.setKeepaliveExecutor(keepaliveExecutor);
+        builder.setProcessingExecutor(processingExecutor);
+        builder.setDomBroker(domBroker);
+        builder.setActorSystem(actorSystem);
+        builder.setEventExecutor(eventExecutor);
+        builder.setNetconfClientDispatcher(clientDispatcher);
+        builder.setTopologyId(TOPOLOGY_ID);
+
+    }
+
+    @Test
+    public void testStopRemoteDeviceConnection() {
+        final Credentials credentials = new LoginPasswordBuilder().setPassword("admin").setUsername("admin").build();
+        final NetconfNode netconfNode = new NetconfNodeBuilder()
+                .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
+                .setPort(new PortNumber(9999))
+                .setReconnectOnChangedSchema(true)
+                .setDefaultRequestTimeoutMillis(1000L)
+                .setBetweenAttemptsTimeoutMillis(100)
+                .setSchemaless(false)
+                .setTcpOnly(false)
+                .setCredentials(credentials)
+                .build();
+        final Node node = new NodeBuilder().setNodeId(NODE_ID).addAugmentation(NetconfNode.class, netconfNode).build();
+
+        builder.setNode(node);
+
+
+        final NetconfDeviceCommunicator communicator = mock (NetconfDeviceCommunicator.class);
+        final RemoteDeviceHandler salFacade = mock(RemoteDeviceHandler.class);
+
+        final TestingRemoteDeviceConnectorImpl remoteDeviceConnection =
+                new TestingRemoteDeviceConnectorImpl(builder.build(), remoteDeviceId, communicator, salFacade);
+
+        final ActorRef masterRef = mock(ActorRef.class);
+
+        remoteDeviceConnection.startRemoteDeviceConnection(masterRef);
+
+        remoteDeviceConnection.stopRemoteDeviceConnection();
+
+        verify(communicator, times(1)).close();
+        verify(salFacade, times(1)).close();
+
+    }
+
+    @Test
+    public void testMasterSalFacade() throws UnknownHostException {
+        final ExecutorService executorService = mock(ExecutorService.class);
+        doReturn(executorService).when(processingExecutor).getExecutor();
+
+        final Credentials credentials = new LoginPasswordBuilder().setPassword("admin").setUsername("admin").build();
+        final NetconfNode netconfNode = new NetconfNodeBuilder()
+                .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
+                .setPort(new PortNumber(9999))
+                .setReconnectOnChangedSchema(true)
+                .setDefaultRequestTimeoutMillis(1000L)
+                .setBetweenAttemptsTimeoutMillis(100)
+                .setSchemaless(false)
+                .setTcpOnly(false)
+                .setCredentials(credentials)
+                .build();
+
+        final RemoteDeviceConnectorImpl remoteDeviceConnection =
+                new RemoteDeviceConnectorImpl(builder.build(), remoteDeviceId);
+
+        final ActorRef masterRef = mock(ActorRef.class);
+
+        final NetconfConnectorDTO connectorDTO =
+                remoteDeviceConnection.createDeviceCommunicator(NODE_ID, netconfNode, masterRef);
+
+        assertTrue(connectorDTO.getFacade() instanceof MasterSalFacade);
+    }
+
+    @Test
+    public void testKeapAliveFacade() throws UnknownHostException {
+        final ExecutorService executorService = mock(ExecutorService.class);
+        doReturn(executorService).when(processingExecutor).getExecutor();
+
+        final Credentials credentials = new LoginPasswordBuilder().setPassword("admin").setUsername("admin").build();
+        final NetconfNode netconfNode = new NetconfNodeBuilder()
+                .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
+                .setPort(new PortNumber(9999))
+                .setReconnectOnChangedSchema(true)
+                .setDefaultRequestTimeoutMillis(1000L)
+                .setBetweenAttemptsTimeoutMillis(100)
+                .setSchemaless(false)
+                .setTcpOnly(false)
+                .setCredentials(credentials)
+                .setKeepaliveDelay(1L)
+                .build();
+
+        final RemoteDeviceId remoteDeviceId = new RemoteDeviceId(TOPOLOGY_ID,
+                new InetSocketAddress(InetAddress.getByName("127.0.0.1"), 9999));
+
+        final RemoteDeviceConnectorImpl remoteDeviceConnection =
+                new RemoteDeviceConnectorImpl(builder.build(), remoteDeviceId);
+
+        final ActorRef masterRef = mock(ActorRef.class);
+
+        final NetconfConnectorDTO connectorDTO =
+                remoteDeviceConnection.createDeviceCommunicator(NODE_ID, netconfNode, masterRef);
+
+        assertTrue(connectorDTO.getFacade() instanceof KeepaliveSalFacade);
+    }
+
+    @Test
+    public void testGetClientConfig() throws UnknownHostException {
+        final NetconfClientSessionListener listener = mock(NetconfClientSessionListener.class);
+        final Host host = new Host(new IpAddress(new Ipv4Address("127.0.0.1")));
+        final PortNumber portNumber = new PortNumber(9999);
+        final NetconfNode testingNode = new NetconfNodeBuilder()
+                .setConnectionTimeoutMillis(1000L)
+                .setDefaultRequestTimeoutMillis(2000L)
+                .setHost(host)
+                .setPort(portNumber)
+                .setCredentials(new LoginPasswordBuilder()
+                        .setUsername("testuser")
+                        .setPassword("testpassword").build())
+                .setTcpOnly(true)
+                .build();
+
+        final RemoteDeviceConnectorImpl remoteDeviceConnection =
+                new RemoteDeviceConnectorImpl(builder.build(), remoteDeviceId);
+
+        final NetconfReconnectingClientConfiguration defaultClientConfig =
+                remoteDeviceConnection.getClientConfig(listener, testingNode);
+
+        assertEquals(defaultClientConfig.getConnectionTimeoutMillis().longValue(), 1000L);
+        assertEquals(defaultClientConfig.getAddress(), new InetSocketAddress(InetAddress.getByName("127.0.0.1"), 9999));
+        assertSame(defaultClientConfig.getSessionListener(), listener);
+        assertEquals(defaultClientConfig.getAuthHandler().getUsername(), "testuser");
+        assertEquals(defaultClientConfig.getProtocol(), NetconfClientConfiguration.NetconfClientProtocol.TCP);
+    }
+
+    @Test
+    public void testSchemaResourceDTO() throws UnknownHostException {
+        final ExecutorService executorService = mock(ExecutorService.class);
+        doReturn(executorService).when(processingExecutor).getExecutor();
+
+        final Credentials credentials = new LoginPasswordBuilder().setPassword("admin").setUsername("admin").build();
+        final NetconfNode netconfNode = new NetconfNodeBuilder()
+                .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
+                .setPort(new PortNumber(9999))
+                .setReconnectOnChangedSchema(true)
+                .setDefaultRequestTimeoutMillis(1000L)
+                .setBetweenAttemptsTimeoutMillis(100)
+                .setSchemaless(false)
+                .setTcpOnly(false)
+                .setCredentials(credentials)
+                .setSchemaCacheDirectory("schemas-test")
+                .build();
+
+        final RemoteDeviceConnectorImpl remoteDeviceConnection =
+                new RemoteDeviceConnectorImpl(builder.build(), remoteDeviceId);
+
+        final ActorRef masterRef = mock(ActorRef.class);
+
+        remoteDeviceConnection.createDeviceCommunicator(NODE_ID, netconfNode, masterRef);
+
+        assertTrue(remoteDeviceConnection.getSchemaResourcesDTOs().containsKey("schemas-test"));
+    }
+
+}
diff --git a/netconf/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/TestingRemoteDeviceConnectorImpl.java b/netconf/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/TestingRemoteDeviceConnectorImpl.java
new file mode 100644 (file)
index 0000000..d4b4ec0
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.topology.singleton.impl;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doReturn;
+
+import akka.actor.ActorRef;
+import com.google.common.util.concurrent.Futures;
+import org.opendaylight.netconf.sal.connect.api.RemoteDeviceHandler;
+import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfDeviceCommunicator;
+import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
+import org.opendaylight.netconf.topology.singleton.impl.utils.NetconfConnectorDTO;
+import org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologySetup;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
+
+class TestingRemoteDeviceConnectorImpl extends RemoteDeviceConnectorImpl {
+
+    private final NetconfDeviceCommunicator communicator;
+    private final RemoteDeviceHandler salFacade;
+
+    TestingRemoteDeviceConnectorImpl(final NetconfTopologySetup netconfTopologyDeviceSetup,
+                                            final RemoteDeviceId remoteDeviceId,
+                                            final NetconfDeviceCommunicator communicator,
+                                            final RemoteDeviceHandler salFacade) {
+        super(netconfTopologyDeviceSetup, remoteDeviceId);
+        this.communicator = communicator;
+        this.salFacade = salFacade;
+    }
+
+    @Override
+    public NetconfConnectorDTO createDeviceCommunicator(final NodeId nodeId, final NetconfNode node,
+                                                        final ActorRef deviceContextActorRef) {
+        final NetconfConnectorDTO connectorDTO = new NetconfConnectorDTO(communicator, salFacade);
+        doReturn(Futures.immediateCheckedFuture(null)).when(communicator).initializeRemoteConnection(any(), any());
+
+        return connectorDTO;
+    }
+
+}
diff --git a/netconf/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/tx/ReadOnlyTransactionTest.java b/netconf/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/tx/ReadOnlyTransactionTest.java
new file mode 100644 (file)
index 0000000..c491ee6
--- /dev/null
@@ -0,0 +1,262 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.topology.singleton.impl.tx;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.MockitoAnnotations.initMocks;
+import static org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologyUtils.DEFAULT_SCHEMA_REPOSITORY;
+
+import akka.actor.ActorRef;
+import akka.actor.ActorSystem;
+import akka.actor.Props;
+import akka.pattern.Patterns;
+import akka.testkit.JavaTestKit;
+import akka.testkit.TestActorRef;
+import akka.util.Timeout;
+import com.google.common.base.Optional;
+import com.google.common.collect.Lists;
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.Futures;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.UnknownHostException;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.mockito.Mock;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
+import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
+import org.opendaylight.netconf.topology.singleton.api.NetconfDOMTransaction;
+import org.opendaylight.netconf.topology.singleton.impl.NetconfDOMDataBroker;
+import org.opendaylight.netconf.topology.singleton.impl.actors.NetconfNodeActor;
+import org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologySetup;
+import org.opendaylight.netconf.topology.singleton.messages.CreateInitialMasterActorData;
+import org.opendaylight.netconf.topology.singleton.messages.MasterActorDataInitialized;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
+import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
+import scala.concurrent.Await;
+import scala.concurrent.Future;
+import scala.concurrent.duration.Duration;
+
+public class ReadOnlyTransactionTest {
+    private static final Timeout TIMEOUT = new Timeout(Duration.create(5, "seconds"));
+    private static final int TIMEOUT_SEC = 5;
+    private static ActorSystem system;
+
+    @Rule
+    public final ExpectedException exception = ExpectedException.none();
+
+    private ActorRef masterRef;
+    private NetconfDOMDataBroker slaveDataBroker;
+    private DOMDataBroker masterDataBroker;
+    private List<SourceIdentifier> sourceIdentifiers;
+
+    @Mock
+    private DOMDataReadOnlyTransaction readTx;
+
+    @Before
+    public void setup() throws UnknownHostException {
+        initMocks(this);
+
+        system = ActorSystem.create();
+
+        final RemoteDeviceId remoteDeviceId = new RemoteDeviceId("netconf-topology",
+                new InetSocketAddress(InetAddress.getByName("127.0.0.1"), 9999));
+
+        final NetconfTopologySetup setup = mock(NetconfTopologySetup.class);
+        final Props props = NetconfNodeActor.props(setup, remoteDeviceId, DEFAULT_SCHEMA_REPOSITORY,
+                DEFAULT_SCHEMA_REPOSITORY);
+
+        masterRef = TestActorRef.create(system, props, "master_read");
+
+        sourceIdentifiers = Lists.newArrayList();
+
+        // Create master data broker
+
+        final DOMDataBroker delegateDataBroker = mock(DOMDataBroker.class);
+        readTx = mock(DOMDataReadOnlyTransaction.class);
+
+        doReturn(readTx).when(delegateDataBroker).newReadOnlyTransaction();
+
+        final NetconfDOMTransaction masterDOMTransactions =
+                new NetconfMasterDOMTransaction(remoteDeviceId, delegateDataBroker);
+
+        masterDataBroker =
+                new NetconfDOMDataBroker(system, remoteDeviceId, masterDOMTransactions);
+
+        // Create slave data broker for testing proxy
+
+        final NetconfDOMTransaction proxyDOMTransactions =
+                new NetconfProxyDOMTransaction(remoteDeviceId, system, masterRef);
+
+        slaveDataBroker = new NetconfDOMDataBroker(system, remoteDeviceId, proxyDOMTransactions);
+
+
+    }
+
+    @After
+    public void teardown() {
+        JavaTestKit.shutdownActorSystem(system);
+        system = null;
+    }
+
+    @Test
+    public void testRead() throws Exception {
+
+        /* Initialize data on master */
+
+        initializeDataTest();
+
+        final YangInstanceIdentifier instanceIdentifier = YangInstanceIdentifier.EMPTY;
+        final LogicalDatastoreType storeType = LogicalDatastoreType.CONFIGURATION;
+
+        // Message: EmptyReadResponse
+
+        final CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> resultEmpty =
+                Futures.immediateCheckedFuture(Optional.absent());
+
+        doReturn(resultEmpty).when(readTx).read(storeType, instanceIdentifier);
+
+        final CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> resultEmptyResponse =
+                slaveDataBroker.newReadOnlyTransaction().read(storeType,
+                        instanceIdentifier);
+
+        final Optional<NormalizedNode<?, ?>> resultEmptyMessage =
+                resultEmptyResponse.checkedGet(TIMEOUT_SEC, TimeUnit.SECONDS);
+
+        assertEquals(resultEmptyMessage, Optional.absent());
+
+        // Message: NormalizedNodeMessage
+
+        final NormalizedNode<?, ?> outputNode = ImmutableContainerNodeBuilder.create()
+                .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(QName.create("TestQname")))
+                .withChild(ImmutableNodes.leafNode(QName.create("NodeQname"), "foo")).build();
+
+        final CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> resultNormalizedNodeMessage =
+                Futures.immediateCheckedFuture(Optional.of(outputNode));
+
+        doReturn(resultNormalizedNodeMessage).when(readTx).read(storeType, instanceIdentifier);
+
+        final CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> resultNodeMessageResponse =
+                slaveDataBroker.newReadOnlyTransaction().read(storeType, instanceIdentifier);
+
+        final Optional<NormalizedNode<?, ?>> resultNodeMessage =
+                resultNodeMessageResponse.checkedGet(TIMEOUT_SEC, TimeUnit.SECONDS);
+
+        assertTrue(resultNodeMessage.isPresent());
+        assertEquals(resultNodeMessage.get(), outputNode);
+
+        // Message: Throwable
+
+        final ReadFailedException readFailedException = new ReadFailedException("Fail", null);
+        final CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> resultThrowable =
+                Futures.immediateFailedCheckedFuture(readFailedException);
+
+        doReturn(resultThrowable).when(readTx).read(storeType, instanceIdentifier);
+
+        final CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> resultThrowableResponse =
+                slaveDataBroker.newReadOnlyTransaction().read(storeType, instanceIdentifier);
+
+        exception.expect(ReadFailedException.class);
+        resultThrowableResponse.checkedGet(TIMEOUT_SEC, TimeUnit.SECONDS);
+
+    }
+
+    @Test
+    public void testExist() throws Exception {
+
+        /* Initialize data on master */
+
+        initializeDataTest();
+
+        final YangInstanceIdentifier instanceIdentifier = YangInstanceIdentifier.EMPTY;
+        final LogicalDatastoreType storeType = LogicalDatastoreType.CONFIGURATION;
+
+        // Message: True
+
+        final CheckedFuture<Boolean, ReadFailedException> resultTrue =
+                Futures.immediateCheckedFuture(true);
+
+        doReturn(resultTrue).when(readTx).exists(storeType, instanceIdentifier);
+
+        final CheckedFuture<Boolean, ReadFailedException> trueResponse =
+                slaveDataBroker.newReadOnlyTransaction().exists(storeType, instanceIdentifier);
+
+        final Boolean trueMessage = trueResponse.checkedGet(TIMEOUT_SEC, TimeUnit.SECONDS);
+
+        assertEquals(true, trueMessage);
+
+        // Message: False
+
+        final CheckedFuture<Boolean, ReadFailedException> resultFalse = Futures.immediateCheckedFuture(false);
+
+        doReturn(resultFalse).when(readTx).exists(storeType, instanceIdentifier);
+
+        final CheckedFuture<Boolean, ReadFailedException> falseResponse =
+                slaveDataBroker.newReadOnlyTransaction().exists(storeType,
+                        instanceIdentifier);
+
+        final Boolean falseMessage = falseResponse.checkedGet(TIMEOUT_SEC, TimeUnit.SECONDS);
+
+        assertEquals(false, falseMessage);
+
+        // Message: False, result null
+
+        final CheckedFuture<Boolean, ReadFailedException> resultNull = Futures.immediateCheckedFuture(null);
+
+        doReturn(resultNull).when(readTx).exists(storeType, instanceIdentifier);
+
+        final CheckedFuture<Boolean, ReadFailedException> nullResponse =
+                slaveDataBroker.newReadOnlyTransaction().exists(storeType,
+                        instanceIdentifier);
+
+        final Boolean nullFalseMessage = nullResponse.checkedGet(TIMEOUT_SEC, TimeUnit.SECONDS);
+
+        assertEquals(false, nullFalseMessage);
+
+        // Message: Throwable
+
+        final ReadFailedException readFailedException = new ReadFailedException("Fail", null);
+        final CheckedFuture<Boolean, ReadFailedException> resultThrowable =
+                Futures.immediateFailedCheckedFuture(readFailedException);
+
+        doReturn(resultThrowable).when(readTx).exists(storeType, instanceIdentifier);
+
+        final CheckedFuture<Boolean, ReadFailedException> resultThrowableResponse =
+                slaveDataBroker.newReadOnlyTransaction().exists(storeType, instanceIdentifier);
+
+        exception.expect(ReadFailedException.class);
+        resultThrowableResponse.checkedGet(TIMEOUT_SEC, TimeUnit.SECONDS);
+
+    }
+
+    private void initializeDataTest() throws Exception {
+        final Future<Object> initialDataToActor =
+                Patterns.ask(masterRef, new CreateInitialMasterActorData(masterDataBroker, sourceIdentifiers),
+                        TIMEOUT);
+
+        final Object success = Await.result(initialDataToActor, TIMEOUT.duration());
+
+        assertTrue(success instanceof MasterActorDataInitialized);
+    }
+}
diff --git a/netconf/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/tx/WriteOnlyTransactionTest.java b/netconf/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/tx/WriteOnlyTransactionTest.java
new file mode 100644 (file)
index 0000000..c9fa38f
--- /dev/null
@@ -0,0 +1,258 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.topology.singleton.impl.tx;
+
+import static junit.framework.TestCase.assertNull;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.MockitoAnnotations.initMocks;
+import static org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologyUtils.DEFAULT_SCHEMA_REPOSITORY;
+
+import akka.actor.ActorRef;
+import akka.actor.ActorSystem;
+import akka.actor.Props;
+import akka.pattern.Patterns;
+import akka.testkit.JavaTestKit;
+import akka.testkit.TestActorRef;
+import akka.util.Timeout;
+import com.google.common.collect.Lists;
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.Futures;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.UnknownHostException;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
+import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
+import org.opendaylight.netconf.topology.singleton.api.NetconfDOMTransaction;
+import org.opendaylight.netconf.topology.singleton.impl.NetconfDOMDataBroker;
+import org.opendaylight.netconf.topology.singleton.impl.actors.NetconfNodeActor;
+import org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologySetup;
+import org.opendaylight.netconf.topology.singleton.messages.CreateInitialMasterActorData;
+import org.opendaylight.netconf.topology.singleton.messages.MasterActorDataInitialized;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
+import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
+import scala.concurrent.Await;
+import scala.concurrent.Future;
+import scala.concurrent.duration.Duration;
+
+public class WriteOnlyTransactionTest {
+    private static final Timeout TIMEOUT = new Timeout(Duration.create(5, "seconds"));
+    private static final int TIMEOUT_SEC = 5;
+    private static ActorSystem system;
+
+    @Rule
+    public final ExpectedException exception = ExpectedException.none();
+
+    private ActorRef masterRef;
+    private NetconfDOMDataBroker slaveDataBroker;
+    private DOMDataBroker masterDataBroker;
+    private List<SourceIdentifier> sourceIdentifiers;
+
+    @Mock
+    private DOMDataWriteTransaction writeTx;
+
+    @Before
+    public void setup() throws UnknownHostException {
+        initMocks(this);
+
+        system = ActorSystem.create();
+
+        final RemoteDeviceId remoteDeviceId = new RemoteDeviceId("netconf-topology",
+                new InetSocketAddress(InetAddress.getByName("127.0.0.1"), 9999));
+
+        final NetconfTopologySetup setup = mock(NetconfTopologySetup.class);
+        final Props props = NetconfNodeActor.props(setup, remoteDeviceId, DEFAULT_SCHEMA_REPOSITORY,
+                DEFAULT_SCHEMA_REPOSITORY);
+
+        masterRef = TestActorRef.create(system, props, "master_read");
+
+        sourceIdentifiers = Lists.newArrayList();
+
+        // Create master data broker
+
+        final DOMDataBroker delegateDataBroker = mock(DOMDataBroker.class);
+        writeTx = mock(DOMDataWriteTransaction.class);
+        final DOMDataReadOnlyTransaction readTx = mock(DOMDataReadOnlyTransaction.class);
+
+        doReturn(writeTx).when(delegateDataBroker).newWriteOnlyTransaction();
+        doReturn(readTx).when(delegateDataBroker).newReadOnlyTransaction();
+
+        final NetconfDOMTransaction masterDOMTransactions =
+                new NetconfMasterDOMTransaction(remoteDeviceId, delegateDataBroker);
+
+        masterDataBroker =
+                new NetconfDOMDataBroker(system, remoteDeviceId, masterDOMTransactions);
+
+        // Create slave data broker for testing proxy
+
+        final NetconfDOMTransaction proxyDOMTransactions =
+                new NetconfProxyDOMTransaction(remoteDeviceId, system, masterRef);
+
+        slaveDataBroker = new NetconfDOMDataBroker(system, remoteDeviceId, proxyDOMTransactions);
+
+
+    }
+
+    @After
+    public void teardown() {
+        JavaTestKit.shutdownActorSystem(system);
+        system = null;
+    }
+
+    @Test
+    public void testPutMergeDeleteCalls() throws Exception {
+
+        /* Initialize data on master */
+
+        initializeDataTest();
+
+        final YangInstanceIdentifier instanceIdentifier = YangInstanceIdentifier.EMPTY;
+        final LogicalDatastoreType storeType = LogicalDatastoreType.CONFIGURATION;
+        final NormalizedNode<?, ?> testNode = ImmutableContainerNodeBuilder.create()
+                .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(QName.create("TestQname")))
+                .withChild(ImmutableNodes.leafNode(QName.create("NodeQname"), "foo")).build();
+
+        // Test of invoking put on master through slave proxy
+
+        doNothing().when(writeTx).put(storeType, instanceIdentifier, testNode);
+        slaveDataBroker.newWriteOnlyTransaction().put(storeType, instanceIdentifier, testNode);
+
+        verify(writeTx, times(1)).put(storeType, instanceIdentifier, testNode);
+
+        // Test of invoking merge on master through slave proxy
+
+        doNothing().when(writeTx).merge(storeType, instanceIdentifier, testNode);
+        slaveDataBroker.newWriteOnlyTransaction().merge(storeType, instanceIdentifier, testNode);
+
+        verify(writeTx, times(1)).merge(storeType, instanceIdentifier, testNode);
+
+        // Test of invoking delete on master through slave proxy
+
+        doNothing().when(writeTx).delete(storeType, instanceIdentifier);
+        slaveDataBroker.newWriteOnlyTransaction().delete(storeType, instanceIdentifier);
+
+        verify(writeTx, times(1)).delete(storeType, instanceIdentifier);
+
+    }
+
+    @Test
+    public void testSubmit() throws Exception {
+
+        /* Initialize data on master */
+
+        initializeDataTest();
+
+        // Without Tx
+
+        final CheckedFuture<Void,TransactionCommitFailedException> resultSubmit = Futures.immediateCheckedFuture(null);
+        doReturn(resultSubmit).when(writeTx).submit();
+
+        final CheckedFuture<Void, TransactionCommitFailedException> resultSubmitResponse =
+                slaveDataBroker.newWriteOnlyTransaction().submit();
+
+        final Object result= resultSubmitResponse.checkedGet(TIMEOUT_SEC, TimeUnit.SECONDS);
+
+        assertNull(result);
+
+        // With Tx
+
+        doNothing().when(writeTx).delete(any(), any());
+        slaveDataBroker.newWriteOnlyTransaction().delete(LogicalDatastoreType.CONFIGURATION,
+                YangInstanceIdentifier.EMPTY);
+
+        final CheckedFuture<Void,TransactionCommitFailedException> resultSubmitTx = Futures.immediateCheckedFuture(null);
+        doReturn(resultSubmitTx).when(writeTx).submit();
+
+        final CheckedFuture<Void, TransactionCommitFailedException> resultSubmitTxResponse =
+                slaveDataBroker.newWriteOnlyTransaction().submit();
+
+        final Object resultTx = resultSubmitTxResponse.checkedGet(TIMEOUT_SEC, TimeUnit.SECONDS);
+
+        assertNull(resultTx);
+
+        slaveDataBroker.newWriteOnlyTransaction().delete(LogicalDatastoreType.CONFIGURATION,
+                YangInstanceIdentifier.EMPTY);
+
+        final TransactionCommitFailedException throwable = new TransactionCommitFailedException("Fail", null);
+        final CheckedFuture<Void,TransactionCommitFailedException> resultThrowable =
+                Futures.immediateFailedCheckedFuture(throwable);
+
+        doReturn(resultThrowable).when(writeTx).submit();
+
+        final CheckedFuture<Void, TransactionCommitFailedException> resultThrowableResponse =
+                slaveDataBroker.newWriteOnlyTransaction().submit();
+
+        exception.expect(TransactionCommitFailedException.class);
+        resultThrowableResponse.checkedGet(TIMEOUT_SEC, TimeUnit.SECONDS);
+    }
+
+    @Test
+    public void testCancel() throws Exception {
+
+        /* Initialize data on master */
+
+        initializeDataTest();
+
+        // Without Tx
+
+        final Boolean resultFalseNoTx = slaveDataBroker.newWriteOnlyTransaction().cancel();
+        assertEquals(false, resultFalseNoTx);
+
+        // With Tx, readWriteTx test
+
+        doNothing().when(writeTx).delete(any(), any());
+        slaveDataBroker.newReadWriteTransaction().delete(LogicalDatastoreType.CONFIGURATION,
+                YangInstanceIdentifier.EMPTY);
+
+        doReturn(true).when(writeTx).cancel();
+
+        final Boolean resultTrue = slaveDataBroker.newWriteOnlyTransaction().cancel();
+        assertEquals(true, resultTrue);
+
+        doReturn(false).when(writeTx).cancel();
+
+        final Boolean resultFalse = slaveDataBroker.newWriteOnlyTransaction().cancel();
+        assertEquals(false, resultFalse);
+
+    }
+
+    private void initializeDataTest() throws Exception {
+        final Future<Object> initialDataToActor =
+                Patterns.ask(masterRef, new CreateInitialMasterActorData(masterDataBroker, sourceIdentifiers),
+                        TIMEOUT);
+
+        final Object success = Await.result(initialDataToActor, TIMEOUT.duration());
+
+        assertTrue(success instanceof MasterActorDataInitialized);
+    }
+
+}
diff --git a/netconf/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/utils/NetconfTopologyUtilTest.java b/netconf/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/utils/NetconfTopologyUtilTest.java
new file mode 100644 (file)
index 0000000..9f8d153
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.topology.singleton.impl.utils;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Host;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class NetconfTopologyUtilTest {
+
+    @Test
+    public void testCreateRemoteDeviceId() {
+        final Host host = new Host(new IpAddress(new Ipv4Address("127.0.0.1")));
+        final NetconfNode netconfNode = new NetconfNodeBuilder().setHost(host).setPort(new PortNumber(9999)).build();
+        final NodeId nodeId = new NodeId("testing-node");
+        final RemoteDeviceId id = NetconfTopologyUtils.createRemoteDeviceId(nodeId, netconfNode);
+
+        assertEquals("testing-node", id.getName());
+        assertEquals(host, id.getHost());
+        assertEquals(9999, id.getAddress().getPort());
+    }
+
+    @Test
+    public void testCreateActorPath() {
+        final String actorPath = NetconfTopologyUtils.createActorPath("member", "name");
+        assertEquals("member/user/name", actorPath);
+    }
+
+    @Test
+    public void testCreateListPath() {
+        final InstanceIdentifier<Node> listPath =
+                NetconfTopologyUtils.createTopologyNodeListPath(new NodeKey(new NodeId("nodeId")), "topologyId");
+
+        assertEquals("nodeId", listPath.firstKeyOf(Node.class).getNodeId().getValue());
+        assertEquals("topologyId", listPath.firstKeyOf(Topology.class).getTopologyId().getValue());
+
+        assertEquals("topologyId",  NetconfTopologyUtils.createTopologyNodePath("topologyId").
+                firstKeyOf(Topology.class).getTopologyId().getValue());
+    }
+
+}
index b2488bd0ff36841e78ea55710aea7b62ad20025a..f0839ae945f914aabd912ff2b405decab5aec4f9 100644 (file)
             <groupId>org.opendaylight.netconf</groupId>
             <artifactId>sal-netconf-connector</artifactId>
         </dependency>
-        <dependency>
-            <groupId>org.opendaylight.controller</groupId>
-            <artifactId>sal-clustering-commons</artifactId>
-        </dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>sal-common-api</artifactId>
         </dependency>
-        <dependency>
-            <groupId>org.opendaylight.netconf</groupId>
-            <artifactId>abstract-topology</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>com.typesafe</groupId>
-            <artifactId>config</artifactId>
-        </dependency>
         <dependency>
             <groupId>org.mockito</groupId>
             <artifactId>mockito-all</artifactId>
-            <version>1.9.5</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>com.jayway.awaitility</groupId>
-            <artifactId>awaitility</artifactId>
-            <version>1.6.5</version>
             <scope>test</scope>
         </dependency>
         <dependency>
diff --git a/netconf/netconf-topology/src/main/java/org/opendaylight/controller/config/yang/clustered/netconf/topology/ClusteredNetconfTopologyModule.java b/netconf/netconf-topology/src/main/java/org/opendaylight/controller/config/yang/clustered/netconf/topology/ClusteredNetconfTopologyModule.java
deleted file mode 100644 (file)
index 54be237..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.config.yang.clustered.netconf.topology;
-
-import org.opendaylight.netconf.topology.impl.ClusteredNetconfTopology;
-
-public class ClusteredNetconfTopologyModule extends org.opendaylight.controller.config.yang.clustered.netconf.topology.AbstractClusteredNetconfTopologyModule {
-    public ClusteredNetconfTopologyModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
-        super(identifier, dependencyResolver);
-    }
-
-    public ClusteredNetconfTopologyModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.controller.config.yang.clustered.netconf.topology.ClusteredNetconfTopologyModule oldModule, java.lang.AutoCloseable oldInstance) {
-        super(identifier, dependencyResolver, oldModule, oldInstance);
-    }
-
-    @Override
-    public void customValidation() {
-        // add custom validation form module attributes here.
-    }
-
-    @Override
-    public java.lang.AutoCloseable createInstance() {
-        return new ClusteredNetconfTopology(getTopologyId(),
-                getClientDispatcherDependency(),
-                getBindingRegistryDependency(),
-                getDomRegistryDependency(),
-                getEventExecutorDependency(),
-                getKeepaliveExecutorDependency(),
-                getProcessingExecutorDependency(),
-                getSharedSchemaRepositoryDependency(),
-                getActorSystemProviderServiceDependency().getActorSystem(),
-                getEntityOwnershipServiceDependency());
-    }
-
-}
diff --git a/netconf/netconf-topology/src/main/java/org/opendaylight/controller/config/yang/clustered/netconf/topology/ClusteredNetconfTopologyModuleFactory.java b/netconf/netconf-topology/src/main/java/org/opendaylight/controller/config/yang/clustered/netconf/topology/ClusteredNetconfTopologyModuleFactory.java
deleted file mode 100644 (file)
index 0fb3a5b..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-/*
-* Generated file
-*
-* Generated from: yang module name: clustered-netconf-topology yang module local name: clustered-netconf-topology-impl
-* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
-* Generated at: Wed Nov 04 10:59:45 CET 2015
-*
-* Do not modify this file unless it is present under src/main directory
-*/
-package org.opendaylight.controller.config.yang.clustered.netconf.topology;
-public class ClusteredNetconfTopologyModuleFactory extends org.opendaylight.controller.config.yang.clustered.netconf.topology.AbstractClusteredNetconfTopologyModuleFactory {
-
-}
index f0c56f3ca79301defcca62328ba63378083dbf84..7174c53be544c628a4d85eb510c870d7a18ea751 100644 (file)
@@ -57,13 +57,13 @@ import org.opendaylight.netconf.sal.connect.netconf.listener.UserPreferences;
 import org.opendaylight.netconf.sal.connect.netconf.sal.KeepaliveSalFacade;
 import org.opendaylight.netconf.sal.connect.netconf.schema.YangLibrarySchemaYangSourceProvider;
 import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
-import org.opendaylight.netconf.topology.pipeline.TopologyMountPointFacade.ConnectionStatusListenerRegistration;
 import org.opendaylight.protocol.framework.ReconnectStrategy;
 import org.opendaylight.protocol.framework.ReconnectStrategyFactory;
 import org.opendaylight.protocol.framework.TimedReconnectStrategy;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Host;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.available.capabilities.AvailableCapability.CapabilityOrigin;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.credentials.Credentials;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
@@ -203,16 +203,6 @@ public abstract class AbstractNetconfTopology implements NetconfTopology, Bindin
     @Override
     public abstract void onSessionInitiated(ProviderContext session);
 
-    @Override
-    public String getTopologyId() {
-        return topologyId;
-    }
-
-    @Override
-    public DataBroker getDataBroker() {
-        return dataBroker;
-    }
-
     @Override
     public ListenableFuture<NetconfDeviceCapabilities> connectNode(NodeId nodeId, Node configNode) {
         LOG.info("Connecting RemoteDevice{{}} , with config {}", nodeId, configNode);
@@ -448,9 +438,6 @@ public abstract class AbstractNetconfTopology implements NetconfTopology, Bindin
 
     protected abstract RemoteDeviceHandler<NetconfSessionPreferences> createSalFacade(final RemoteDeviceId id, final Broker domBroker, final BindingAwareBroker bindingBroker);
 
-    @Override
-    public abstract ConnectionStatusListenerRegistration registerConnectionStatusListener(NodeId node, RemoteDeviceHandler<NetconfSessionPreferences> listener);
-
     @Override
     public void onSessionInitiated(ProviderSession session) {
          mountPointService = session.getService(DOMMountPointService.class);
@@ -481,7 +468,7 @@ public abstract class AbstractNetconfTopology implements NetconfTopology, Bindin
             return Optional.absent();
         }
 
-        final NetconfSessionPreferences parsedOverrideCapabilities = NetconfSessionPreferences.fromStrings(capabilities);
+        final NetconfSessionPreferences parsedOverrideCapabilities = NetconfSessionPreferences.fromStrings(capabilities, CapabilityOrigin.UserDefined);
         Preconditions.checkState(parsedOverrideCapabilities.getNonModuleCaps().isEmpty(), "Capabilities to override can " +
                 "only contain module based capabilities, non-module capabilities will be retrieved from the device," +
                 " configured non-module capabilities: " + parsedOverrideCapabilities.getNonModuleCaps());
index 7c3b83617b7ff2ef1e70210ea9f22428d63f22c4..b275c7584da82dd8db87cc986d64a15da00ca563 100644 (file)
@@ -8,43 +8,15 @@
 
 package org.opendaylight.netconf.topology;
 
-import akka.actor.ActorContext;
-import akka.actor.ActorRef;
 import com.google.common.util.concurrent.ListenableFuture;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.netconf.sal.connect.api.RemoteDeviceHandler;
 import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfDeviceCapabilities;
-import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences;
-import org.opendaylight.netconf.topology.pipeline.TopologyMountPointFacade.ConnectionStatusListenerRegistration;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
 
 public interface NetconfTopology {
 
-    String getTopologyId();
-
-    DataBroker getDataBroker();
-
     ListenableFuture<NetconfDeviceCapabilities> connectNode(NodeId nodeId, Node configNode);
 
     ListenableFuture<Void> disconnectNode(NodeId nodeId);
 
-    /**
-     * register master mount point
-     * @param context
-     * @param nodeId
-     */
-    void registerMountPoint(ActorContext context, NodeId nodeId);
-
-    /**
-     * register slave mountpoint with the provided ActorRef
-     * @param context
-     * @param nodeId
-     * @param masterRef
-     */
-    void registerMountPoint(ActorContext context, NodeId nodeId, ActorRef masterRef);
-
-    void unregisterMountPoint(NodeId nodeId);
-
-    ConnectionStatusListenerRegistration registerConnectionStatusListener(NodeId node, RemoteDeviceHandler<NetconfSessionPreferences> listener);
 }
diff --git a/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/impl/ClusteredNetconfTopology.java b/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/impl/ClusteredNetconfTopology.java
deleted file mode 100644 (file)
index 3822455..0000000
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.netconf.topology.impl;
-
-import akka.actor.ActorContext;
-import akka.actor.ActorRef;
-import akka.actor.ActorSystem;
-import akka.actor.TypedActor;
-import akka.actor.TypedActorExtension;
-import akka.actor.TypedProps;
-import akka.japi.Creator;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import io.netty.util.concurrent.EventExecutor;
-import java.net.InetSocketAddress;
-import java.util.Collection;
-import java.util.Collections;
-import javassist.ClassPool;
-import org.opendaylight.controller.config.threadpool.ScheduledThreadPool;
-import org.opendaylight.controller.config.threadpool.ThreadPool;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
-import org.opendaylight.controller.sal.core.api.Broker;
-import org.opendaylight.netconf.client.NetconfClientDispatcher;
-import org.opendaylight.netconf.client.NetconfClientSessionListener;
-import org.opendaylight.netconf.sal.connect.api.RemoteDeviceHandler;
-import org.opendaylight.netconf.sal.connect.netconf.NetconfDevice;
-import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences;
-import org.opendaylight.netconf.sal.connect.netconf.sal.KeepaliveSalFacade;
-import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
-import org.opendaylight.netconf.topology.AbstractNetconfTopology;
-import org.opendaylight.netconf.topology.NetconfTopology;
-import org.opendaylight.netconf.topology.NodeManagerCallback;
-import org.opendaylight.netconf.topology.NodeManagerCallback.NodeManagerCallbackFactory;
-import org.opendaylight.netconf.topology.SchemaRepositoryProvider;
-import org.opendaylight.netconf.topology.TopologyManager;
-import org.opendaylight.netconf.topology.TopologyManagerCallback;
-import org.opendaylight.netconf.topology.TopologyManagerCallback.TopologyManagerCallbackFactory;
-import org.opendaylight.netconf.topology.example.LoggingSalNodeWriter;
-import org.opendaylight.netconf.topology.pipeline.ClusteredNetconfDevice;
-import org.opendaylight.netconf.topology.pipeline.ClusteredNetconfDeviceCommunicator;
-import org.opendaylight.netconf.topology.pipeline.ClusteredNetconfDeviceCommunicator.NetconfClientSessionListenerRegistration;
-import org.opendaylight.netconf.topology.pipeline.TopologyMountPointFacade;
-import org.opendaylight.netconf.topology.pipeline.TopologyMountPointFacade.ConnectionStatusListenerRegistration;
-import org.opendaylight.netconf.topology.util.BaseTopologyManager;
-import org.opendaylight.netconf.topology.util.NodeRoleChangeStrategy;
-import org.opendaylight.netconf.topology.util.NodeWriter;
-import org.opendaylight.netconf.topology.util.TopologyRoleChangeStrategy;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.$YangModuleInfoImpl;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
-import org.opendaylight.yangtools.binding.data.codec.gen.impl.StreamWriterGenerator;
-import org.opendaylight.yangtools.binding.data.codec.impl.BindingNormalizedNodeCodecRegistry;
-import org.opendaylight.yangtools.sal.binding.generator.impl.ModuleInfoBackedContext;
-import org.opendaylight.yangtools.sal.binding.generator.util.BindingRuntimeContext;
-import org.opendaylight.yangtools.sal.binding.generator.util.JavassistUtils;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ClusteredNetconfTopology extends AbstractNetconfTopology implements AutoCloseable {
-
-    private static final Logger LOG = LoggerFactory.getLogger(ClusteredNetconfTopology.class);
-
-    private final BindingNormalizedNodeCodecRegistry codecRegistry;
-
-    private final ActorSystem actorSystem;
-    private final EntityOwnershipService entityOwnershipService;
-    private TopologyManager topologyManager;
-
-    public ClusteredNetconfTopology(final String topologyId, final NetconfClientDispatcher clientDispatcher,
-                               final BindingAwareBroker bindingAwareBroker, final Broker domBroker,
-                               final EventExecutor eventExecutor, final ScheduledThreadPool keepaliveExecutor,
-                               final ThreadPool processingExecutor, final SchemaRepositoryProvider schemaRepositoryProvider,
-                               final ActorSystem actorSystem, final EntityOwnershipService entityOwnershipService) {
-        super(topologyId, clientDispatcher,
-                bindingAwareBroker, domBroker, eventExecutor,
-                keepaliveExecutor, processingExecutor, schemaRepositoryProvider);
-
-        final ModuleInfoBackedContext moduleInfoBackedContext = ModuleInfoBackedContext.create();
-        moduleInfoBackedContext.addModuleInfos(Collections.singletonList($YangModuleInfoImpl.getInstance()));
-        final Optional<SchemaContext> schemaContextOptional = moduleInfoBackedContext.tryToCreateSchemaContext();
-        Preconditions.checkState(schemaContextOptional.isPresent());
-        final SchemaContext topologySchemaCtx = schemaContextOptional.get();
-
-        final JavassistUtils javassist = JavassistUtils.forClassPool(ClassPool.getDefault());
-        codecRegistry = new BindingNormalizedNodeCodecRegistry(StreamWriterGenerator.create(javassist));
-        codecRegistry.onBindingRuntimeContextUpdated(BindingRuntimeContext.create(moduleInfoBackedContext, topologySchemaCtx));
-
-        this.actorSystem = actorSystem;
-        this.entityOwnershipService = entityOwnershipService;
-        registerToSal(this, this);
-        LOG.warn("Clustered netconf topo started");
-    }
-
-
-
-    @Override
-    public void onSessionInitiated(final ProviderContext session) {
-        dataBroker = session.getSALService(DataBroker.class);
-        final NodeWriter writer = new TopologyNodeWriter(topologyId, dataBroker);
-        TypedActorExtension typedActorExtension = TypedActor.get(this.actorSystem);
-        LOG.warn("Registering actor on path {}", actorSystem.name() + "/user/" + topologyId);
-        topologyManager = typedActorExtension.typedActorOf(new TypedProps<>(TopologyManager.class, new Creator<BaseTopologyManager>() {
-            @Override
-            public BaseTopologyManager create() throws Exception {
-                return new BaseTopologyManager(actorSystem,
-                        codecRegistry,
-                        dataBroker,
-                        topologyId,
-                        new TopologyCallbackFactory(ClusteredNetconfTopology.this, entityOwnershipService, writer),
-                        new NetconfNodeOperationalDataAggregator(),
-                        new LoggingSalNodeWriter(writer),
-                        new TopologyRoleChangeStrategy(dataBroker, entityOwnershipService, "topology-netconf", "topology-manager"));
-            }
-        }), topologyId);
-    }
-
-    @Override
-    public void close() throws Exception {
-        // close all existing connectors, delete whole topology in datastore?
-        for (NetconfConnectorDTO connectorDTO : activeConnectors.values()) {
-            connectorDTO.getCommunicator().close();
-        }
-        activeConnectors.clear();
-    }
-
-    @Override
-    protected NetconfConnectorDTO createDeviceCommunicator(final NodeId nodeId,
-                                                           final NetconfNode node) {
-        //setup default values since default value is not supported in mdsal
-        final Long defaultRequestTimeoutMillis = node.getDefaultRequestTimeoutMillis() == null ? DEFAULT_REQUEST_TIMEOUT_MILLIS : node.getDefaultRequestTimeoutMillis();
-        final Long keepaliveDelay = node.getKeepaliveDelay() == null ? DEFAULT_KEEPALIVE_DELAY : node.getKeepaliveDelay();
-        final Boolean reconnectOnChangedSchema = node.isReconnectOnChangedSchema() == null ? DEFAULT_RECONNECT_ON_CHANGED_SCHEMA : node.isReconnectOnChangedSchema();
-
-        IpAddress ipAddress = node.getHost().getIpAddress();
-        InetSocketAddress address = new InetSocketAddress(ipAddress.getIpv4Address() != null ?
-                ipAddress.getIpv4Address().getValue() : ipAddress.getIpv6Address().getValue(),
-                node.getPort().getValue());
-        RemoteDeviceId remoteDeviceId = new RemoteDeviceId(nodeId.getValue(), address);
-
-        RemoteDeviceHandler<NetconfSessionPreferences> salFacade =
-                createSalFacade(remoteDeviceId, domBroker, bindingAwareBroker);
-
-        if (keepaliveDelay > 0) {
-            LOG.warn("Adding keepalive facade, for device {}", nodeId);
-            salFacade = new KeepaliveSalFacade(remoteDeviceId, salFacade, keepaliveExecutor.getExecutor(), keepaliveDelay, defaultRequestTimeoutMillis);
-        }
-
-        final NetconfDevice.SchemaResourcesDTO schemaResourcesDTO = setupSchemaCacheDTO(nodeId, node);
-
-        final NetconfDevice device = new ClusteredNetconfDevice(schemaResourcesDTO, remoteDeviceId, salFacade,
-                processingExecutor.getExecutor(), actorSystem, topologyId, nodeId.getValue(), TypedActor.context(),
-                reconnectOnChangedSchema);
-
-        final int rpcMessageLimit =
-                node.getConcurrentRpcLimit() == null ? DEFAULT_CONCURRENT_RPC_LIMIT : node.getConcurrentRpcLimit();
-
-        if (rpcMessageLimit < 1) {
-            LOG.info("Concurrent rpc limit is smaller than 1, no limit will be enforced for device {}", remoteDeviceId);
-        }
-
-        return new NetconfConnectorDTO(new ClusteredNetconfDeviceCommunicator(remoteDeviceId, device, entityOwnershipService, rpcMessageLimit), salFacade);
-    }
-
-    @Override
-    protected RemoteDeviceHandler<NetconfSessionPreferences> createSalFacade(final RemoteDeviceId id, final Broker domBroker, final BindingAwareBroker bindingBroker) {
-        return new TopologyMountPointFacade(topologyId, id, domBroker, bindingBroker);
-    }
-
-    @Override
-    public void registerMountPoint(final ActorContext context, final NodeId nodeId) {
-        ((TopologyMountPointFacade) activeConnectors.get(nodeId).getFacade()).registerMountPoint(actorSystem, context);
-    }
-
-    @Override
-    public void registerMountPoint(final ActorContext context, final NodeId nodeId, final ActorRef masterRef) {
-        ((TopologyMountPointFacade) activeConnectors.get(nodeId).getFacade()).registerMountPoint(actorSystem, context, masterRef);
-    }
-
-    @Override
-    public void unregisterMountPoint(final NodeId nodeId) {
-        Preconditions.checkState(activeConnectors.containsKey(nodeId), "Cannot unregister nonexistent mountpoint");
-        ((TopologyMountPointFacade) activeConnectors.get(nodeId).getFacade()).unregisterMountPoint();
-    }
-
-    @Override
-    public ConnectionStatusListenerRegistration registerConnectionStatusListener(final NodeId node, final RemoteDeviceHandler<NetconfSessionPreferences> listener) {
-        Preconditions.checkState(activeConnectors.containsKey(node), "Need to connect a node before a connection listener can be registered");
-        return ((TopologyMountPointFacade) activeConnectors.get(node).getFacade()).registerConnectionStatusListener(listener);
-    }
-
-    public Collection<ProviderFunctionality> getProviderFunctionality() {
-        return Collections.emptySet();
-    }
-
-    public NetconfClientSessionListenerRegistration registerNetconfClientSessionListener(final NodeId node, final NetconfClientSessionListener listener) {
-        Preconditions.checkState(activeConnectors.containsKey(node), "Need to connect a node before a session listener can be registered");
-        return ((ClusteredNetconfDeviceCommunicator) activeConnectors.get(node).getCommunicator()).registerNetconfClientSessionListener(listener);
-    }
-
-    static class TopologyCallbackFactory implements TopologyManagerCallbackFactory {
-
-        private final NetconfTopology netconfTopology;
-        private final EntityOwnershipService entityOwnershipService;
-        private final NodeWriter writer;
-
-        TopologyCallbackFactory(final NetconfTopology netconfTopology, final EntityOwnershipService entityOwnershipService, final NodeWriter writer) {
-            this.netconfTopology = netconfTopology;
-            this.entityOwnershipService = entityOwnershipService;
-            this.writer = writer;
-        }
-
-        @Override
-        public TopologyManagerCallback create(final ActorSystem actorSystem, final String topologyId) {
-            return new NetconfTopologyManagerCallback(actorSystem, topologyId, new NodeCallbackFactory(netconfTopology, entityOwnershipService), new LoggingSalNodeWriter(writer));
-        }
-    }
-
-    private static class NodeCallbackFactory implements NodeManagerCallbackFactory {
-
-        private final NetconfTopology netconfTopology;
-        private final EntityOwnershipService entityOwnershipService;
-
-        NodeCallbackFactory(final NetconfTopology netconfTopology, final EntityOwnershipService entityOwnershipService) {
-            this.netconfTopology = netconfTopology;
-            this.entityOwnershipService = entityOwnershipService;
-        }
-
-        @Override
-        public NodeManagerCallback create(final String nodeId, final String topologyId, final ActorSystem actorSystem) {
-            return new NetconfNodeManagerCallback(nodeId, topologyId, actorSystem, netconfTopology, new NodeRoleChangeStrategy(entityOwnershipService, "netconf-node", nodeId));
-        }
-    }
-}
diff --git a/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/impl/NetconfNodeManagerCallback.java b/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/impl/NetconfNodeManagerCallback.java
deleted file mode 100644 (file)
index 89e1dfa..0000000
+++ /dev/null
@@ -1,520 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.netconf.topology.impl;
-
-import akka.actor.ActorContext;
-import akka.actor.ActorRef;
-import akka.actor.ActorSystem;
-import akka.actor.TypedActor;
-import akka.actor.TypedProps;
-import akka.cluster.Cluster;
-import akka.dispatch.OnComplete;
-import com.google.common.base.Function;
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.Lists;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map.Entry;
-import java.util.concurrent.TimeUnit;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import org.opendaylight.controller.md.sal.dom.api.DOMNotification;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
-import org.opendaylight.netconf.api.NetconfMessage;
-import org.opendaylight.netconf.api.NetconfTerminationReason;
-import org.opendaylight.netconf.client.NetconfClientSession;
-import org.opendaylight.netconf.client.NetconfClientSessionListener;
-import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfDeviceCapabilities;
-import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences;
-import org.opendaylight.netconf.topology.NetconfTopology;
-import org.opendaylight.netconf.topology.NodeManager;
-import org.opendaylight.netconf.topology.NodeManagerCallback;
-import org.opendaylight.netconf.topology.RoleChangeStrategy;
-import org.opendaylight.netconf.topology.TopologyManager;
-import org.opendaylight.netconf.topology.pipeline.ClusteredNetconfDeviceCommunicator.NetconfClientSessionListenerRegistration;
-import org.opendaylight.netconf.topology.pipeline.TopologyMountPointFacade.ConnectionStatusListenerRegistration;
-import org.opendaylight.netconf.topology.util.BaseNodeManager;
-import org.opendaylight.netconf.topology.util.BaseTopologyManager;
-import org.opendaylight.netconf.topology.util.messages.AnnounceMasterMountPoint;
-import org.opendaylight.netconf.topology.util.messages.AnnounceMasterMountPointDown;
-import org.opendaylight.netconf.util.NetconfTopologyPathCreator;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus.ConnectionStatus;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.AvailableCapabilitiesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.ClusteredConnectionStatusBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.UnavailableCapabilities;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.UnavailableCapabilitiesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.clustered.connection.status.NodeStatus.Status;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.clustered.connection.status.NodeStatusBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.unavailable.capabilities.UnavailableCapability;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.unavailable.capabilities.UnavailableCapability.FailureReason;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.unavailable.capabilities.UnavailableCapabilityBuilder;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import scala.concurrent.Future;
-import scala.concurrent.duration.FiniteDuration;
-
-public class NetconfNodeManagerCallback implements NodeManagerCallback, NetconfClientSessionListener{
-
-    private static final Logger LOG = LoggerFactory.getLogger(NetconfNodeManagerCallback.class);
-
-    public static final Function<Entry<QName, FailureReason>, UnavailableCapability> UNAVAILABLE_CAPABILITY_TRANSFORMER = new Function<Entry<QName, FailureReason>, UnavailableCapability>() {
-        @Override
-        public UnavailableCapability apply(final Entry<QName, FailureReason> input) {
-            return new UnavailableCapabilityBuilder()
-                    .setCapability(input.getKey().toString())
-                    .setFailureReason(input.getValue()).build();
-        }
-    };
-    public static final Function<QName, String> AVAILABLE_CAPABILITY_TRANSFORMER = new Function<QName, String>() {
-        @Override
-        public String apply(QName qName) {
-            // intern string representation of a capability to avoid duplicates
-            return qName.toString().intern();
-        }
-    };
-
-    private static final String UNKNOWN_REASON = "Unknown reason";
-
-    private boolean isMaster = false;
-    private ClusteredNetconfTopology topologyDispatcher;
-    private final ActorSystem actorSystem;
-    private final Cluster clusterExtension;
-
-    private final RoleChangeStrategy roleChangeStrategy;
-
-    private String nodeId;
-    private String topologyId;
-    private TopologyManager topologyManager;
-    private NodeManager nodeManager;
-    // cached context so that we can use it in callbacks from topology
-    private ActorContext cachedContext;
-
-    private Node currentConfig;
-    private Node currentOperationalNode;
-
-    private ConnectionStatusListenerRegistration connectionStatusregistration = null;
-    private NetconfClientSessionListenerRegistration sessionListener = null;
-
-    private ActorRef masterDataBrokerRef = null;
-    private boolean connected = false;
-
-    public NetconfNodeManagerCallback(final String nodeId,
-                                      final String topologyId,
-                                      final ActorSystem actorSystem,
-                                      final NetconfTopology topologyDispatcher,
-                                      final RoleChangeStrategy roleChangeStrategy) {
-        this.nodeId = nodeId;
-        this.topologyId = topologyId;
-        this.actorSystem = actorSystem;
-        this.clusterExtension = Cluster.get(actorSystem);
-        this.topologyDispatcher = (ClusteredNetconfTopology) topologyDispatcher;
-        this.roleChangeStrategy = roleChangeStrategy;
-
-        final NetconfTopologyPathCreator pathCreator = new NetconfTopologyPathCreator(topologyId);
-        final Future<ActorRef> topologyRefFuture = actorSystem.actorSelection(pathCreator.build()).resolveOne(FiniteDuration.create(10L, TimeUnit.SECONDS));
-        topologyRefFuture.onComplete(new OnComplete<ActorRef>() {
-            @Override
-            public void onComplete(Throwable throwable, ActorRef actorRef) throws Throwable {
-                if (throwable != null) {
-                    LOG.warn("Unable to resolve actor for path: {} ", "/user/" + topologyId, throwable);
-
-                }
-
-                LOG.debug("Actor ref for path {} resolved", "/user/" + topologyId);
-                topologyManager = TypedActor.get(actorSystem).typedActorOf(new TypedProps<>(TopologyManager.class, BaseTopologyManager.class), actorRef);
-            }
-        }, actorSystem.dispatcher());
-
-        final Future<ActorRef> nodeRefFuture = actorSystem.actorSelection(pathCreator.withSuffix(nodeId).build()).resolveOne(FiniteDuration.create(10L, TimeUnit.SECONDS));
-        nodeRefFuture.onComplete(new OnComplete<ActorRef>() {
-            @Override
-            public void onComplete(Throwable throwable, ActorRef actorRef) throws Throwable {
-                if (throwable != null) {
-                    LOG.warn("Unable to resolve actor for path: {} ", "/user/" + topologyId + "/" + nodeId, throwable);
-                }
-                LOG.debug("Actor ref for path {} resolved", "/user/" + topologyId);
-                nodeManager = TypedActor.get(actorSystem).typedActorOf(new TypedProps<>(NodeManager.class, BaseNodeManager.class), actorRef);
-            }
-        }, actorSystem.dispatcher());
-    }
-
-
-    @Nonnull
-    @Override public Node getInitialState(@Nonnull final NodeId nodeId,
-                                          @Nonnull final Node configNode) {
-        final NetconfNode netconfNode = configNode.getAugmentation(NetconfNode.class);
-
-        final Node initialNode = new NodeBuilder()
-                .setNodeId(nodeId)
-                .addAugmentation(NetconfNode.class,
-                        new NetconfNodeBuilder()
-                                .setHost(netconfNode.getHost())
-                                .setPort(netconfNode.getPort())
-                                .setConnectionStatus(ConnectionStatus.Connecting)
-                                .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<String>()).build())
-                                .setUnavailableCapabilities(new UnavailableCapabilitiesBuilder().setUnavailableCapability(new ArrayList<UnavailableCapability>()).build())
-                                .setClusteredConnectionStatus(
-                                        new ClusteredConnectionStatusBuilder()
-                                                .setNodeStatus(
-                                                        Lists.newArrayList(
-                                                                new NodeStatusBuilder()
-                                                                        .setNode(clusterExtension.selfAddress().toString())
-                                                                        .setStatus(Status.Unavailable)
-                                                                        .build()))
-                                                .build())
-                                .build())
-                .build();
-
-        if (currentOperationalNode == null) {
-            currentOperationalNode = initialNode;
-        }
-
-        return initialNode;
-    }
-
-    @Nonnull @Override public Node getFailedState(@Nonnull final NodeId nodeId,
-                                                  @Nullable final Node configNode) {
-        final NetconfNode netconfNode = configNode == null ? currentOperationalNode.getAugmentation(NetconfNode.class) : configNode.getAugmentation(NetconfNode.class);
-
-        final Node failedNode = new NodeBuilder()
-                .setNodeId(nodeId)
-                .addAugmentation(NetconfNode.class,
-                        new NetconfNodeBuilder()
-                                .setHost(netconfNode.getHost())
-                                .setPort(netconfNode.getPort())
-                                .setConnectionStatus(ConnectionStatus.UnableToConnect)
-                                .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<String>()).build())
-                                .setUnavailableCapabilities(new UnavailableCapabilitiesBuilder().setUnavailableCapability(new ArrayList<UnavailableCapability>()).build())
-                                .setClusteredConnectionStatus(
-                                        new ClusteredConnectionStatusBuilder()
-                                                .setNodeStatus(
-                                                        Collections.singletonList(
-                                                                new NodeStatusBuilder()
-                                                                        .setNode(clusterExtension.selfAddress().toString())
-                                                                        .setStatus(Status.Failed)
-                                                                        .build()))
-                                                .build())
-                                .build())
-                .build();
-
-        if (currentOperationalNode == null) {
-            currentOperationalNode = failedNode;
-        }
-
-        return failedNode;
-    }
-
-    @Nonnull @Override public ListenableFuture<Node> onNodeCreated(@Nonnull final NodeId nodeId,
-                                                                   @Nonnull final Node configNode) {
-        cachedContext = TypedActor.context();
-        this.nodeId = nodeId.getValue();
-        this.currentConfig = configNode;
-        // set initial state before anything happens
-        this.currentOperationalNode = getInitialState(nodeId, configNode);
-
-        // connect magic, send config into the netconf pipeline through topo dispatcher
-        final ListenableFuture<NetconfDeviceCapabilities> connectionFuture = topologyDispatcher.connectNode(nodeId, configNode);
-
-        Futures.addCallback(connectionFuture, new FutureCallback<NetconfDeviceCapabilities>() {
-            @Override
-            public void onSuccess(@Nullable NetconfDeviceCapabilities result) {
-                connectionStatusregistration = topologyDispatcher.registerConnectionStatusListener(nodeId, nodeManager);
-                sessionListener = topologyDispatcher.registerNetconfClientSessionListener(nodeId, NetconfNodeManagerCallback.this);
-            }
-
-            @Override
-            public void onFailure(Throwable t) {
-                LOG.error("Connection to device failed", t);
-            }
-        });
-
-        final NetconfNode netconfNode = configNode.getAugmentation(NetconfNode.class);
-
-        // transform future result into state that gets written into datastore
-        return Futures.transform(connectionFuture, new Function<NetconfDeviceCapabilities, Node>() {
-            @Nullable
-            @Override
-            public Node apply(NetconfDeviceCapabilities input) {
-                // build state data
-                currentOperationalNode = new NodeBuilder().setNodeId(nodeId)
-                        .addAugmentation(NetconfNode.class,
-                                new NetconfNodeBuilder()
-                                        .setConnectionStatus(ConnectionStatus.Connected)
-                                        .setClusteredConnectionStatus(
-                                                new ClusteredConnectionStatusBuilder()
-                                                        .setNodeStatus(
-                                                                Collections.singletonList(
-                                                                        new NodeStatusBuilder()
-                                                                                .setNode(clusterExtension.selfAddress().toString())
-                                                                                .setStatus(Status.Connected)
-                                                                                .build()))
-                                                        .build())
-                                        .setHost(netconfNode.getHost())
-                                        .setPort(netconfNode.getPort())
-                                        .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<String>()).build())
-                                        .setUnavailableCapabilities(new UnavailableCapabilitiesBuilder().setUnavailableCapability(new ArrayList<UnavailableCapability>()).build())
-                                        .build()).build();
-                return currentOperationalNode;
-            }
-        });
-    }
-
-    @Nonnull
-    @Override
-    public ListenableFuture<Node> onNodeUpdated(@Nonnull final NodeId nodeId,
-                                                @Nonnull final Node configNode) {
-        // first disconnect this node
-        topologyDispatcher.unregisterMountPoint(nodeId);
-
-        if (connectionStatusregistration != null) {
-            connectionStatusregistration.close();
-        }
-        topologyDispatcher.disconnectNode(nodeId);
-
-        // now reinit this connection with new settings
-        final ListenableFuture<NetconfDeviceCapabilities> connectionFuture = topologyDispatcher.connectNode(nodeId, configNode);
-
-        Futures.addCallback(connectionFuture, new FutureCallback<NetconfDeviceCapabilities>() {
-            @Override
-            public void onSuccess(@Nullable NetconfDeviceCapabilities result) {
-                connectionStatusregistration = topologyDispatcher.registerConnectionStatusListener(nodeId, NetconfNodeManagerCallback.this);
-            }
-
-            @Override
-            public void onFailure(Throwable t) {
-                LOG.error("Connection to device failed", t);
-            }
-        });
-
-        final NetconfNode netconfNode = configNode.getAugmentation(NetconfNode.class);
-
-        return Futures.transform(connectionFuture, new Function<NetconfDeviceCapabilities, Node>() {
-            @Nullable
-            @Override
-            public Node apply(NetconfDeviceCapabilities input) {
-                // build state data
-                return new NodeBuilder()
-                        .setNodeId(nodeId)
-                        .addAugmentation(NetconfNode.class,
-                                new NetconfNodeBuilder()
-                                        .setConnectionStatus(ConnectionStatus.Connected)
-                                        .setClusteredConnectionStatus(
-                                                new ClusteredConnectionStatusBuilder()
-                                                        .setNodeStatus(
-                                                                Collections.singletonList(
-                                                                        new NodeStatusBuilder()
-                                                                                .setNode(clusterExtension.selfAddress().toString())
-                                                                                .setStatus(Status.Connected)
-                                                                                .build()))
-                                                        .build())
-                                        .setHost(netconfNode.getHost())
-                                        .setPort(netconfNode.getPort())
-                                        .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<String>()).build())
-                                        .setUnavailableCapabilities(new UnavailableCapabilitiesBuilder().setUnavailableCapability(new ArrayList<UnavailableCapability>()).build())
-                                        .build())
-                        .build();
-            }
-        });
-    }
-
-    @Nonnull @Override public ListenableFuture<Void> onNodeDeleted(@Nonnull final NodeId nodeId) {
-        // cleanup and disconnect
-        topologyDispatcher.unregisterMountPoint(nodeId);
-
-        if(connectionStatusregistration != null) {
-            connectionStatusregistration.close();
-        }
-        roleChangeStrategy.unregisterRoleCandidate();
-        return topologyDispatcher.disconnectNode(nodeId);
-    }
-
-    @Nonnull
-    @Override
-    public ListenableFuture<Node> getCurrentStatusForNode(@Nonnull NodeId nodeId) {
-        LOG.debug("Getting current status for node: {} status: {}", nodeId, currentOperationalNode);
-        return Futures.immediateFuture(currentOperationalNode);
-    }
-
-    @Override
-    public void onRoleChanged(final RoleChangeDTO roleChangeDTO) {
-        topologyDispatcher.unregisterMountPoint(new NodeId(nodeId));
-
-        isMaster = roleChangeDTO.isOwner();
-    }
-
-    @Override
-    public void onDeviceConnected(final SchemaContext remoteSchemaContext, final NetconfSessionPreferences netconfSessionPreferences, final DOMRpcService deviceRpc) {
-        // we need to notify the higher level that something happened, get a current status from all other nodes, and aggregate a new result
-        connected = true;
-        if (isMaster) {
-            LOG.debug("Master is done with schema resolution, registering mount point");
-            topologyDispatcher.registerMountPoint(TypedActor.context(), new NodeId(nodeId));
-        } else if (masterDataBrokerRef != null) {
-            LOG.warn("Device connected, master already present in topology, registering mount point");
-            topologyDispatcher.registerMountPoint(cachedContext, new NodeId(nodeId), masterDataBrokerRef);
-        }
-
-        List<String> capabilityList = new ArrayList<>();
-        capabilityList.addAll(netconfSessionPreferences.getNetconfDeviceCapabilities().getNonModuleBasedCapabilities());
-        capabilityList.addAll(FluentIterable.from(netconfSessionPreferences.getNetconfDeviceCapabilities().getResolvedCapabilities()).transform(AVAILABLE_CAPABILITY_TRANSFORMER).toList());
-        final AvailableCapabilitiesBuilder avCapabalitiesBuilder = new AvailableCapabilitiesBuilder();
-        avCapabalitiesBuilder.setAvailableCapability(capabilityList);
-
-        final UnavailableCapabilities unavailableCapabilities =
-                new UnavailableCapabilitiesBuilder().setUnavailableCapability(FluentIterable.from(netconfSessionPreferences.getNetconfDeviceCapabilities().getUnresolvedCapabilites().entrySet())
-                        .transform(UNAVAILABLE_CAPABILITY_TRANSFORMER).toList()).build();
-
-        final NetconfNode netconfNode = currentConfig.getAugmentation(NetconfNode.class);
-        currentOperationalNode = new NodeBuilder().setNodeId(new NodeId(nodeId))
-                .addAugmentation(NetconfNode.class,
-                        new NetconfNodeBuilder()
-                                .setConnectionStatus(ConnectionStatus.Connected)
-                                .setClusteredConnectionStatus(
-                                        new ClusteredConnectionStatusBuilder()
-                                                .setNodeStatus(
-                                                        Collections.singletonList(
-                                                                new NodeStatusBuilder()
-                                                                        .setNode(clusterExtension.selfAddress().toString())
-                                                                        .setStatus(Status.Connected)
-                                                                        .build()))
-                                                .build())
-                                .setHost(netconfNode.getHost())
-                                .setPort(netconfNode.getPort())
-                                .setAvailableCapabilities(avCapabalitiesBuilder.build())
-                                .setUnavailableCapabilities(unavailableCapabilities)
-                                .build())
-                .build();
-        topologyManager.notifyNodeStatusChange(new NodeId(nodeId));
-    }
-
-    @Override
-    public void onDeviceDisconnected() {
-        // we need to notify the higher level that something happened, get a current status from all other nodes, and aggregate a new result
-        LOG.debug("onDeviceDisconnected received, unregistered role candidate");
-        connected = false;
-        if (isMaster) {
-            // set master to false since we are unregistering, the ownershipChanged callback can sometimes lag behind causing multiple nodes behaving as masters
-            isMaster = false;
-            // onRoleChanged() callback can sometimes lag behind, so unregister the mount right when it disconnects
-            topologyDispatcher.unregisterMountPoint(new NodeId(nodeId));
-        }
-
-        final NetconfNode netconfNode = currentConfig.getAugmentation(NetconfNode.class);
-        currentOperationalNode = new NodeBuilder().setNodeId(new NodeId(nodeId))
-                .addAugmentation(NetconfNode.class,
-                        new NetconfNodeBuilder()
-                                .setConnectionStatus(ConnectionStatus.Connecting)
-                                .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<String>()).build())
-                                .setUnavailableCapabilities(new UnavailableCapabilitiesBuilder().setUnavailableCapability(new ArrayList<UnavailableCapability>()).build())
-                                .setClusteredConnectionStatus(
-                                        new ClusteredConnectionStatusBuilder()
-                                                .setNodeStatus(
-                                                        Collections.singletonList(
-                                                                new NodeStatusBuilder()
-                                                                        .setNode(clusterExtension.selfAddress().toString())
-                                                                        .setStatus(Status.Unavailable)
-                                                                        .build()))
-                                                .build())
-                                .setHost(netconfNode.getHost())
-                                .setPort(netconfNode.getPort())
-                                .build()).build();
-        topologyManager.notifyNodeStatusChange(new NodeId(nodeId));
-    }
-
-    @Override
-    public void onDeviceFailed(Throwable throwable) {
-        // we need to notify the higher level that something happened, get a current status from all other nodes, and aggregate a new result
-        // no need to remove mountpoint, we should receive onRoleChanged callback after unregistering from election that unregisters the mountpoint
-        LOG.warn("Netconf node {} failed with {}", nodeId, throwable);
-        connected = false;
-        String reason = (throwable != null && throwable.getMessage() != null) ? throwable.getMessage() : UNKNOWN_REASON;
-
-        currentOperationalNode = new NodeBuilder().setNodeId(new NodeId(nodeId))
-                .addAugmentation(NetconfNode.class,
-                        new NetconfNodeBuilder()
-                                .setConnectionStatus(ConnectionStatus.UnableToConnect)
-                                .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<String>()).build())
-                                .setUnavailableCapabilities(new UnavailableCapabilitiesBuilder().setUnavailableCapability(new ArrayList<UnavailableCapability>()).build())
-                                .setClusteredConnectionStatus(
-                                        new ClusteredConnectionStatusBuilder()
-                                                .setNodeStatus(
-                                                        Collections.singletonList(
-                                                                new NodeStatusBuilder()
-                                                                        .setNode(clusterExtension.selfAddress().toString())
-                                                                        .setStatus(Status.Failed)
-                                                                        .build()))
-                                                .build())
-                                .setConnectedMessage(reason)
-                                .build()).build();
-        topologyManager.notifyNodeStatusChange(new NodeId(nodeId));
-    }
-
-    @Override
-    public void onNotification(DOMNotification domNotification) {
-        //NOOP
-    }
-
-    @Override
-    public void close() {
-        //NOOP
-    }
-
-    @Override
-    public void onReceive(Object message, ActorRef actorRef) {
-        LOG.debug("Netconf node callback received message {}", message);
-        if (message instanceof AnnounceMasterMountPoint) {
-            masterDataBrokerRef = actorRef;
-            // candidate gets registered when mount point is already prepared so we can go ahead a register it
-            if (connected) {
-                topologyDispatcher.registerMountPoint(TypedActor.context(), new NodeId(nodeId), masterDataBrokerRef);
-            } else {
-                LOG.debug("Announce master mount point msg received but mount point is not ready yet");
-            }
-        } else if (message instanceof AnnounceMasterMountPointDown) {
-            LOG.debug("Master mountpoint went down");
-            masterDataBrokerRef = null;
-            topologyDispatcher.unregisterMountPoint(new NodeId(nodeId));
-        }
-    }
-
-    @Override
-    public void onSessionUp(NetconfClientSession netconfClientSession) {
-        //NetconfClientSession is up, we can register role candidate
-        LOG.debug("Netconf client session is up, registering role candidate");
-        roleChangeStrategy.registerRoleCandidate(nodeManager);
-    }
-
-    @Override
-    public void onSessionDown(NetconfClientSession netconfClientSession, Exception e) {
-        LOG.debug("Netconf client session is down, unregistering role candidate");
-        roleChangeStrategy.unregisterRoleCandidate();
-    }
-
-    @Override
-    public void onSessionTerminated(NetconfClientSession netconfClientSession, NetconfTerminationReason netconfTerminationReason) {
-        LOG.debug("Netconf client session is down, unregistering role candidate");
-        roleChangeStrategy.unregisterRoleCandidate();
-    }
-
-    @Override
-    public void onMessage(NetconfClientSession netconfClientSession, NetconfMessage netconfMessage) {
-        //NOOP
-    }
-}
\ No newline at end of file
diff --git a/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/impl/NetconfNodeOperationalDataAggregator.java b/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/impl/NetconfNodeOperationalDataAggregator.java
deleted file mode 100644 (file)
index 4a739f9..0000000
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.netconf.topology.impl;
-
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.SettableFuture;
-import java.util.ArrayList;
-import java.util.List;
-import org.opendaylight.netconf.topology.StateAggregator;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus.ConnectionStatus;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.AvailableCapabilities;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.ClusteredConnectionStatusBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.UnavailableCapabilities;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.clustered.connection.status.NodeStatus;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class NetconfNodeOperationalDataAggregator implements StateAggregator{
-
-    private static final Logger LOG = LoggerFactory.getLogger(NetconfNodeOperationalDataAggregator.class);
-
-    @Override
-    public ListenableFuture<Node> combineCreateAttempts(final List<ListenableFuture<Node>> stateFutures) {
-        final SettableFuture<Node> future = SettableFuture.create();
-        final ListenableFuture<List<Node>> allAsList = Futures.allAsList(stateFutures);
-        Futures.addCallback(allAsList, new FutureCallback<List<Node>>() {
-            @Override
-            public void onSuccess(final List<Node> result) {
-                Node base = null;
-                NetconfNode baseAugmentation = null;
-                AvailableCapabilities masterCaps = null;
-                UnavailableCapabilities unavailableMasterCaps = null;
-                final ArrayList<NodeStatus> statusList = new ArrayList<>();
-                for (final Node node : result) {
-                    final NetconfNode netconfNode = node.getAugmentation(NetconfNode.class);
-                    if (base == null && netconfNode.getConnectionStatus().equals(ConnectionStatus.Connected)) {
-                        base = node;
-                        baseAugmentation = netconfNode;
-                    }
-                    // we need to pull out caps from master, since slave does not go through resolution
-                    if (masterCaps == null) {
-                        masterCaps = netconfNode.getAvailableCapabilities();
-                        unavailableMasterCaps = netconfNode.getUnavailableCapabilities();
-                    }
-                    if (netconfNode.getAvailableCapabilities().getAvailableCapability().size() > masterCaps.getAvailableCapability().size()) {
-                        masterCaps = netconfNode.getAvailableCapabilities();
-                        unavailableMasterCaps = netconfNode.getUnavailableCapabilities();
-                    }
-                    LOG.debug(netconfNode.toString());
-                    statusList.addAll(netconfNode.getClusteredConnectionStatus().getNodeStatus());
-                }
-
-                if (base == null) {
-                    base = result.get(0);
-                    baseAugmentation = result.get(0).getAugmentation(NetconfNode.class);
-                    LOG.debug("All results {}", result.toString());
-                }
-
-                final Node aggregatedNode =
-                        new NodeBuilder(base)
-                                .addAugmentation(NetconfNode.class,
-                                        new NetconfNodeBuilder(baseAugmentation)
-                                                .setClusteredConnectionStatus(
-                                                        new ClusteredConnectionStatusBuilder()
-                                                                .setNodeStatus(statusList)
-                                                                .build())
-                                                .setAvailableCapabilities(masterCaps)
-                                                .setUnavailableCapabilities(unavailableMasterCaps)
-                                                .build())
-                                .build();
-
-                future.set(aggregatedNode);
-            }
-
-            @Override
-            public void onFailure(final Throwable t) {
-                LOG.error("One of the combined create attempts failed {}", t);
-                future.setException(t);
-            }
-        });
-        return future;
-    }
-
-    @Override
-    public ListenableFuture<Node> combineUpdateAttempts(final List<ListenableFuture<Node>> stateFutures) {
-        final SettableFuture<Node> future = SettableFuture.create();
-        final ListenableFuture<List<Node>> allAsList = Futures.allAsList(stateFutures);
-        Futures.addCallback(allAsList, new FutureCallback<List<Node>>() {
-            @Override
-            public void onSuccess(final List<Node> result) {
-                Node base = null;
-                NetconfNode baseAugmentation = null;
-                AvailableCapabilities masterCaps = null;
-                UnavailableCapabilities unavailableMasterCaps = null;
-                final ArrayList<NodeStatus> statusList = new ArrayList<>();
-                for (final Node node : result) {
-                    final NetconfNode netconfNode = node.getAugmentation(NetconfNode.class);
-                    if (base == null && netconfNode.getConnectionStatus().equals(ConnectionStatus.Connected)) {
-                        base = node;
-                        baseAugmentation = netconfNode;
-                    }
-                    // we need to pull out caps from master, since slave does not go through resolution
-                    if (masterCaps == null) {
-                        masterCaps = netconfNode.getAvailableCapabilities();
-                        unavailableMasterCaps = netconfNode.getUnavailableCapabilities();
-                    }
-                    if (netconfNode.getAvailableCapabilities().getAvailableCapability().size() > masterCaps.getAvailableCapability().size()) {
-                        masterCaps = netconfNode.getAvailableCapabilities();
-                        unavailableMasterCaps = netconfNode.getUnavailableCapabilities();
-                    }
-                    LOG.debug(netconfNode.toString());
-                    statusList.addAll(netconfNode.getClusteredConnectionStatus().getNodeStatus());
-                }
-
-                if (base == null) {
-                    base = result.get(0);
-                    baseAugmentation = result.get(0).getAugmentation(NetconfNode.class);
-                    LOG.debug("All results {}", result.toString());
-                }
-
-                final Node aggregatedNode =
-                        new NodeBuilder(base)
-                                .addAugmentation(NetconfNode.class,
-                                        new NetconfNodeBuilder(baseAugmentation)
-                                                .setClusteredConnectionStatus(
-                                                        new ClusteredConnectionStatusBuilder()
-                                                                .setNodeStatus(statusList)
-                                                                .build())
-                                                .setAvailableCapabilities(masterCaps)
-                                                .setUnavailableCapabilities(unavailableMasterCaps)
-                                                .build())
-                                .build();
-                future.set(aggregatedNode);
-            }
-
-            @Override
-            public void onFailure(final Throwable t) {
-                LOG.error("One of the combined update attempts failed {}", t);
-                future.setException(t);
-            }
-        });
-        return future;
-    }
-
-    @Override
-    public ListenableFuture<Void> combineDeleteAttempts(final List<ListenableFuture<Void>> stateFutures) {
-        final SettableFuture<Void> future = SettableFuture.create();
-        final ListenableFuture<List<Void>> allAsList = Futures.allAsList(stateFutures);
-        Futures.addCallback(allAsList, new FutureCallback<List<Void>>() {
-            @Override
-            public void onSuccess(final List<Void> result) {
-                future.set(null);
-            }
-
-            @Override
-            public void onFailure(final Throwable t) {
-                LOG.error("One of the combined delete attempts failed {}", t);
-                future.setException(t);
-            }
-        });
-        return future;
-    }
-}
index c1e41189e3353a05dac9aa010cd1ec855ef2f6c8..0553a5aa5b4753ccf1af8c94a26c331cefda5177 100644 (file)
@@ -8,8 +8,6 @@
 
 package org.opendaylight.netconf.topology.impl;
 
-import akka.actor.ActorContext;
-import akka.actor.ActorRef;
 import com.google.common.util.concurrent.FutureCallback;
 import com.google.common.util.concurrent.Futures;
 import io.netty.util.concurrent.EventExecutor;
@@ -34,11 +32,8 @@ import org.opendaylight.netconf.sal.connect.netconf.sal.NetconfDeviceSalFacade;
 import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
 import org.opendaylight.netconf.topology.AbstractNetconfTopology;
 import org.opendaylight.netconf.topology.SchemaRepositoryProvider;
-import org.opendaylight.netconf.topology.pipeline.TopologyMountPointFacade.ConnectionStatusListenerRegistration;
-import org.opendaylight.netconf.topology.util.TopologyUtil;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopologyBuilder;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyBuilder;
@@ -84,26 +79,6 @@ public class NetconfTopologyImpl extends AbstractNetconfTopology implements Data
         return new NetconfDeviceSalFacade(id, domBroker, bindingAwareBroker);
     }
 
-    @Override
-    public void registerMountPoint(ActorContext context, NodeId nodeId) {
-        throw new UnsupportedOperationException("MountPoint registration is not supported in regular topology, this happens automaticaly in the netconf pipeline");
-    }
-
-    @Override
-    public void registerMountPoint(ActorContext context, NodeId nodeId, ActorRef masterRef) {
-        throw new UnsupportedOperationException("MountPoint registration is not supported in regular topology, this happens automaticaly in the netconf pipeline");
-    }
-
-    @Override
-    public void unregisterMountPoint(NodeId nodeId) {
-        throw new UnsupportedOperationException("MountPoint registration is not supported in regular topology, this happens automaticaly in the netconf pipeline");
-    }
-
-    @Override
-    public ConnectionStatusListenerRegistration registerConnectionStatusListener(NodeId node, RemoteDeviceHandler<NetconfSessionPreferences> listener) {
-        throw new UnsupportedOperationException("Registering a listener on a regular netconf device is not supported(supported only in clustered netconf topology)");
-    }
-
     @Override
     public void onSessionInitiated(ProviderContext session) {
         dataBroker = session.getSALService(DataBroker.class);
diff --git a/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/impl/NetconfTopologyManagerCallback.java b/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/impl/NetconfTopologyManagerCallback.java
deleted file mode 100644 (file)
index 3a9c8db..0000000
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.netconf.topology.impl;
-
-import akka.actor.ActorRef;
-import akka.actor.ActorSystem;
-import akka.actor.TypedActor;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import java.util.HashMap;
-import java.util.Map;
-import javax.annotation.Nonnull;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.netconf.topology.NodeManager;
-import org.opendaylight.netconf.topology.NodeManagerCallback.NodeManagerCallbackFactory;
-import org.opendaylight.netconf.topology.TopologyManagerCallback;
-import org.opendaylight.netconf.topology.util.BaseNodeManager.BaseNodeManagerBuilder;
-import org.opendaylight.netconf.topology.util.NodeWriter;
-import org.opendaylight.netconf.topology.util.NoopRoleChangeStrategy;
-import org.opendaylight.netconf.topology.util.SalNodeWriter;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class NetconfTopologyManagerCallback implements TopologyManagerCallback {
-
-    private static final Logger LOG = LoggerFactory.getLogger(NetconfTopologyManagerCallback.class);
-
-    private final ActorSystem actorSystem;
-    private boolean isMaster;
-
-    private final String topologyId;
-    private final NodeWriter naSalNodeWriter;
-    private final Map<NodeId, NodeManager> nodes = new HashMap<>();
-    private final NodeManagerCallbackFactory nodeHandlerFactory;
-
-    public NetconfTopologyManagerCallback(final ActorSystem actorSystem,
-                                          final DataBroker dataBroker,
-                                          final String topologyId,
-                                          final NodeManagerCallbackFactory nodeHandlerFactory) {
-        this(actorSystem, topologyId, nodeHandlerFactory, new SalNodeWriter(dataBroker, topologyId));
-    }
-
-    public NetconfTopologyManagerCallback(final ActorSystem actorSystem,
-                                          final String topologyId,
-                                          final NodeManagerCallbackFactory nodeHandlerFactory,
-                                          final NodeWriter naSalNodeWriter) {
-        this(actorSystem, topologyId, nodeHandlerFactory, naSalNodeWriter, false);
-
-    }
-
-    public NetconfTopologyManagerCallback(final ActorSystem actorSystem,
-                                          final String topologyId,
-                                          final NodeManagerCallbackFactory nodeHandlerFactory,
-                                          final NodeWriter naSalNodeWriter,
-                                          boolean isMaster) {
-        this.actorSystem = actorSystem;
-        this.topologyId = topologyId;
-        this.nodeHandlerFactory = nodeHandlerFactory;
-        this.naSalNodeWriter = naSalNodeWriter;
-
-        this.isMaster = isMaster;
-    }
-
-    @Override
-    public ListenableFuture<Node> onNodeCreated(final NodeId nodeId, final Node node) {
-
-        // if this node was already configured, and whole config was pushed again, reinit with update
-        if (nodes.containsKey(nodeId)) {
-            return onNodeUpdated(nodeId, node);
-        }
-
-        // Init node admin
-        final NodeManager naBaseNodeManager =
-                createNodeManager(nodeId);
-        nodes.put(nodeId, naBaseNodeManager);
-
-        // only master should put initial state into datastore
-        if (isMaster) {
-            naSalNodeWriter.init(nodeId, naBaseNodeManager.getInitialState(nodeId, node));
-        }
-
-        // trigger connect on this node
-        return naBaseNodeManager.onNodeCreated(nodeId, node);
-    }
-
-    @Override
-    public ListenableFuture<Node> onNodeUpdated(final NodeId nodeId, final Node node) {
-        // only master should put initial state into datastore
-        if (isMaster) {
-            naSalNodeWriter.init(nodeId, nodes.get(nodeId).getInitialState(nodeId, node));
-        }
-
-        // Trigger onNodeUpdated only on this node
-        return nodes.get(nodeId).onNodeUpdated(nodeId, node);
-    }
-
-    @Override
-    public ListenableFuture<Void> onNodeDeleted(final NodeId nodeId) {
-        // Trigger delete only on this node
-        final ListenableFuture<Void> future = nodes.get(nodeId).onNodeDeleted(nodeId);
-        Futures.addCallback(future, new FutureCallback<Void>() {
-            @Override
-            public void onSuccess(Void result) {
-                // remove proxy from node list and stop the actor
-                LOG.debug("Stopping node actor for node : {}", nodeId.getValue());
-                final NodeManager remove = nodes.remove(nodeId);
-                TypedActor.get(actorSystem).stop(remove);
-            }
-
-            @Override
-            public void onFailure(Throwable t) {
-                // NOOP will be handled on higher level
-            }
-        });
-        return future;
-    }
-
-    @Nonnull
-    @Override
-    public ListenableFuture<Node> getCurrentStatusForNode(@Nonnull NodeId nodeId) {
-        if (!nodes.containsKey(nodeId)) {
-            nodes.put(nodeId, createNodeManager(nodeId));
-        }
-        return nodes.get(nodeId).getCurrentStatusForNode(nodeId);
-    }
-
-    @Override
-    public void onRoleChanged(RoleChangeDTO roleChangeDTO) {
-        isMaster = roleChangeDTO.isOwner();
-        // our post-election logic
-    }
-
-    private NodeManager createNodeManager(NodeId nodeId) {
-        return new BaseNodeManagerBuilder().setNodeId(nodeId.getValue())
-                .setActorContext(TypedActor.context())
-                .setDelegateFactory(nodeHandlerFactory)
-                .setRoleChangeStrategy(new NoopRoleChangeStrategy())
-                .setTopologyId(topologyId)
-                .build();
-    }
-
-    @Override
-    public void onReceive(Object o, ActorRef actorRef) {
-
-    }
-
-    @Nonnull
-    @Override
-    public Node getInitialState(@Nonnull NodeId nodeId, @Nonnull Node configNode) {
-        return nodes.get(nodeId).getInitialState(nodeId, configNode);
-    }
-
-    @Nonnull
-    @Override
-    public Node getFailedState(@Nonnull NodeId nodeId, @Nonnull Node configNode) {
-        return nodes.get(nodeId).getFailedState(nodeId, configNode);
-    }
-}
diff --git a/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/impl/TopologyNodeWriter.java b/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/impl/TopologyNodeWriter.java
deleted file mode 100644 (file)
index 8106799..0000000
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.netconf.topology.impl;
-
-import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import java.util.concurrent.locks.ReentrantLock;
-import javax.annotation.Nonnull;
-import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionChain;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
-import org.opendaylight.netconf.topology.util.NodeWriter;
-import org.opendaylight.netconf.topology.util.TopologyUtil;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopologyBuilder;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyBuilder;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class TopologyNodeWriter implements NodeWriter{
-
-    private static final Logger LOG = LoggerFactory.getLogger(TopologyNodeWriter.class);
-
-    private final String topologyId;
-    private final BindingTransactionChain txChain;
-
-    private final InstanceIdentifier<NetworkTopology> networkTopologyPath;
-    private final KeyedInstanceIdentifier<Topology, TopologyKey> topologyListPath;
-
-    private final ReentrantLock lock = new ReentrantLock(true);
-
-    public TopologyNodeWriter(final String topologyId, final DataBroker dataBroker) {
-        this.topologyId = topologyId;
-        this.txChain = Preconditions.checkNotNull(dataBroker).createTransactionChain(new TransactionChainListener() {
-            @Override
-            public void onTransactionChainFailed(TransactionChain<?, ?> chain, AsyncTransaction<?, ?> transaction, Throwable cause) {
-                LOG.error("{}: TransactionChain({}) {} FAILED!", chain,
-                        transaction.getIdentifier(), cause);
-                throw new IllegalStateException("Clustered topology writer TransactionChain(" + chain + ") not committed correctly", cause);
-            }
-
-            @Override
-            public void onTransactionChainSuccessful(TransactionChain<?, ?> chain) {
-                LOG.trace("Clustered topology writer TransactionChain({}) SUCCESSFUL", chain);
-            }
-        });
-
-        this.networkTopologyPath = InstanceIdentifier.builder(NetworkTopology.class).build();
-        this.topologyListPath = networkTopologyPath.child(Topology.class, new TopologyKey(new TopologyId(topologyId)));
-
-        // write an empty topology container at the start
-        final WriteTransaction wTx = txChain.newWriteOnlyTransaction();
-        createNetworkTopologyIfNotPresent(wTx, LogicalDatastoreType.OPERATIONAL);
-        createNetworkTopologyIfNotPresent(wTx, LogicalDatastoreType.CONFIGURATION);
-        commitTransaction(wTx, "init topology container", new NodeId("topology-netconf"));
-    }
-
-    @Override
-    public void init(@Nonnull NodeId id, @Nonnull Node operationalDataNode) {
-        lock.lock();
-        try {
-            final WriteTransaction writeTx = txChain.newWriteOnlyTransaction();
-
-            createNetworkTopologyIfNotPresent(writeTx, LogicalDatastoreType.OPERATIONAL);
-            final InstanceIdentifier<Node> path = TopologyUtil.createTopologyNodeListPath(new NodeKey(id), topologyId);
-
-            LOG.trace("{}: Init device state transaction {} putting if absent operational data started. Putting data on path {}",
-                    id.getValue(), writeTx.getIdentifier(), path);
-            writeTx.put(LogicalDatastoreType.OPERATIONAL, path, operationalDataNode);
-            LOG.trace("{}: Init device state transaction {} putting operational data ended.",
-                    id.getValue(), writeTx.getIdentifier());
-
-            commitTransaction(writeTx, "init", id);
-        } finally {
-            lock.unlock();
-        }
-    }
-
-    @Override
-    public void update(@Nonnull NodeId id, @Nonnull Node operationalDataNode) {
-        lock.lock();
-        try {
-            final WriteTransaction writeTx = txChain.newWriteOnlyTransaction();
-
-            final InstanceIdentifier<Node> path = TopologyUtil.createTopologyNodeListPath(new NodeKey(id), topologyId);
-            LOG.trace("{}: Update device state transaction {} merging operational data started. Putting data on path {}",
-                    id, writeTx.getIdentifier(), operationalDataNode);
-            writeTx.put(LogicalDatastoreType.OPERATIONAL, path, operationalDataNode);
-            LOG.trace("{}: Update device state transaction {} merging operational data ended.",
-                    id, writeTx.getIdentifier());
-
-            commitTransaction(writeTx, "update", id);
-        } finally {
-            lock.unlock();
-        }
-
-    }
-
-    @Override
-    public void delete(@Nonnull NodeId id) {
-        lock.lock();
-        try {
-            final WriteTransaction writeTx = txChain.newWriteOnlyTransaction();
-
-            final InstanceIdentifier<Node> path = TopologyUtil.createTopologyNodeListPath(new NodeKey(id), topologyId);
-
-            LOG.trace(
-                    "{}: Close device state transaction {} removing all data started. Path: {}",
-                    id, writeTx.getIdentifier(), path);
-            writeTx.delete(LogicalDatastoreType.OPERATIONAL, path);
-            LOG.trace(
-                    "{}: Close device state transaction {} removing all data ended.",
-                    id, writeTx.getIdentifier());
-
-            commitTransaction(writeTx, "close", id);
-        } finally {
-            lock.unlock();
-        }
-    }
-
-    private void commitTransaction(final WriteTransaction transaction, final String txType, final NodeId id) {
-        LOG.trace("{}: Committing Transaction {}:{}", id.getValue(), txType,
-                transaction.getIdentifier());
-        final CheckedFuture<Void, TransactionCommitFailedException> result = transaction.submit();
-
-        Futures.addCallback(result, new FutureCallback<Void>() {
-            @Override
-            public void onSuccess(final Void result) {
-                LOG.trace("{}: Transaction({}) {} SUCCESSFUL", id.getValue(), txType,
-                        transaction.getIdentifier());
-            }
-
-            @Override
-            public void onFailure(final Throwable t) {
-                LOG.error("{}: Transaction({}) {} FAILED!", id.getValue(), txType,
-                        transaction.getIdentifier(), t);
-                throw new IllegalStateException(id.getValue() + "  Transaction(" + txType + ") not committed correctly", t);
-            }
-        });
-    }
-
-    private void createNetworkTopologyIfNotPresent(final WriteTransaction writeTx, final LogicalDatastoreType datastoreType) {
-
-        final NetworkTopology networkTopology = new NetworkTopologyBuilder().build();
-        LOG.trace("{}: Merging {} container to ensure its presence", topologyId,
-                NetworkTopology.QNAME, writeTx.getIdentifier());
-        writeTx.merge(datastoreType, networkTopologyPath, networkTopology);
-
-        final Topology topology = new TopologyBuilder().setTopologyId(new TopologyId(topologyId)).build();
-        LOG.trace("{}: Merging {} container to ensure its presence", topologyId,
-                Topology.QNAME, writeTx.getIdentifier());
-        writeTx.merge(datastoreType, topologyListPath, topology);
-    }
-}
similarity index 84%
rename from netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/util/TopologyUtil.java
rename to netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/impl/TopologyUtil.java
index d7c700d1a99a4946452e88a53370e963a0592110..336589de405bca783c171a5c11da49898f5eaf9e 100644 (file)
@@ -6,7 +6,7 @@
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
 
-package org.opendaylight.netconf.topology.util;
+package org.opendaylight.netconf.topology.impl;
 
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
@@ -47,12 +47,4 @@ public final class TopologyUtil {
         final InstanceIdentifier<NetworkTopology> networkTopology = InstanceIdentifier.create(NetworkTopology.class);
         return networkTopology.child(Topology.class, new TopologyKey(new TopologyId(topologyId)));
     }
-
-    public static InstanceIdentifier<Node> createTopologyNodeListPath(final NodeKey key, final String topologyId) {
-        return createTopologyListPath(topologyId).child(Node.class, new NodeKey(new NodeId(key.getNodeId().getValue())));
-    }
-
-    public static InstanceIdentifier<Node> createTopologyNodePath(final String topologyId) {
-        return createTopologyListPath(topologyId).child(Node.class);
-    }
 }
diff --git a/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/pipeline/ClusteredDeviceSourcesResolver.java b/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/pipeline/ClusteredDeviceSourcesResolver.java
deleted file mode 100644 (file)
index 6e0c1d1..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.netconf.topology.pipeline;
-
-import akka.actor.TypedActor;
-import java.util.Set;
-import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
-import scala.concurrent.Future;
-
-public interface ClusteredDeviceSourcesResolver extends TypedActor.Receiver, TypedActor.PreStart {
-
-    Future<Set<SourceIdentifier>> getResolvedSources();
-}
diff --git a/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/pipeline/ClusteredDeviceSourcesResolverImpl.java b/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/pipeline/ClusteredDeviceSourcesResolverImpl.java
deleted file mode 100644 (file)
index 8ea8d3d..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-
-package org.opendaylight.netconf.topology.pipeline;
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-import akka.actor.ActorRef;
-import akka.actor.ActorSystem;
-import akka.actor.TypedActor;
-import akka.actor.TypedProps;
-import akka.cluster.Cluster;
-import akka.cluster.Member;
-import akka.dispatch.Futures;
-import akka.dispatch.OnComplete;
-import java.util.List;
-import java.util.Set;
-import org.opendaylight.controller.cluster.schema.provider.impl.RemoteSchemaProvider;
-import org.opendaylight.netconf.topology.pipeline.messages.AnnounceClusteredDeviceSourcesResolverUp;
-import org.opendaylight.netconf.topology.pipeline.messages.AnnounceMasterOnSameNodeUp;
-import org.opendaylight.netconf.topology.pipeline.messages.AnnounceMasterSourceProviderUp;
-import org.opendaylight.netconf.util.NetconfTopologyPathCreator;
-import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceRepresentation;
-import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
-import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
-import org.opendaylight.yangtools.yang.model.repo.spi.PotentialSchemaSource;
-import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceRegistration;
-import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceRegistry;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import scala.concurrent.Future;
-import scala.concurrent.Promise;
-
-
-public class ClusteredDeviceSourcesResolverImpl implements ClusteredDeviceSourcesResolver {
-
-    private static Logger LOG = LoggerFactory.getLogger(ClusteredDeviceSourcesResolver.class);
-
-    private final String topologyId;
-    private final String nodeId;
-    private final ActorSystem actorSystem;
-    private final SchemaSourceRegistry schemaRegistry;
-    private final List<SchemaSourceRegistration<? extends SchemaSourceRepresentation>> sourceRegistrations;
-
-    private final Promise<Set<SourceIdentifier>> resolvedSourcesPromise;
-    private MasterSourceProvider remoteYangTextSourceProvider;
-
-    public ClusteredDeviceSourcesResolverImpl(String topologyId, String nodeId, ActorSystem actorSystem,
-                                              SchemaSourceRegistry schemaRegistry,
-                                              List<SchemaSourceRegistration<? extends SchemaSourceRepresentation>> sourceRegistrations) {
-        this.topologyId = topologyId;
-        this.nodeId = nodeId;
-        this.actorSystem = actorSystem;
-        this.schemaRegistry = schemaRegistry;
-        this.sourceRegistrations = sourceRegistrations;
-        resolvedSourcesPromise = Futures.promise();
-    }
-
-    @Override
-    public void preStart(){
-        Cluster cluster = Cluster.get(actorSystem);
-        for(Member node : cluster.state().getMembers()) {
-            if(!node.address().equals(cluster.selfAddress())) {
-                final NetconfTopologyPathCreator pathCreator = new NetconfTopologyPathCreator(node.address().toString(), topologyId);
-                final String path = pathCreator.withSuffix(nodeId).withSuffix(NetconfTopologyPathCreator.MASTER_SOURCE_PROVIDER).build();
-                actorSystem.actorSelection(path).tell(new AnnounceClusteredDeviceSourcesResolverUp(), TypedActor.context().self());
-            }
-        }
-    }
-
-    @Override
-    public void onReceive(Object o, ActorRef actorRef) {
-        if(o instanceof AnnounceMasterSourceProviderUp) {
-            if(remoteYangTextSourceProvider == null) {
-                remoteYangTextSourceProvider = TypedActor.get(actorSystem).typedActorOf(
-                        new TypedProps<>(MasterSourceProvider.class,
-                                MasterSourceProviderImpl.class), actorRef);
-                registerProvidedSourcesToSchemaRegistry();
-            }
-        } else if(o instanceof AnnounceMasterOnSameNodeUp) {
-            resolvedSourcesPromise.failure(new MasterSourceProviderOnSameNodeException());
-        }
-    }
-
-    private void registerProvidedSourcesToSchemaRegistry() {
-        Future<Set<SourceIdentifier>> sourcesFuture = remoteYangTextSourceProvider.getProvidedSources();
-        resolvedSourcesPromise.completeWith(sourcesFuture);
-        final RemoteSchemaProvider remoteProvider = new RemoteSchemaProvider(remoteYangTextSourceProvider, actorSystem.dispatcher());
-
-        sourcesFuture.onComplete(new OnComplete<Set<SourceIdentifier>>() {
-            @Override
-            public void onComplete(Throwable throwable, Set<SourceIdentifier> sourceIdentifiers) throws Throwable {
-                for (SourceIdentifier sourceId : sourceIdentifiers) {
-                   sourceRegistrations.add(schemaRegistry.registerSchemaSource(remoteProvider,
-                           PotentialSchemaSource.create(sourceId, YangTextSchemaSource.class, PotentialSchemaSource.Costs.REMOTE_IO.getValue())));
-                }
-            }
-        }, actorSystem.dispatcher());
-    }
-
-    @Override
-    public Future<Set<SourceIdentifier>> getResolvedSources() {
-        return resolvedSourcesPromise.future();
-    }
-}
diff --git a/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/pipeline/ClusteredNetconfDevice.java b/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/pipeline/ClusteredNetconfDevice.java
deleted file mode 100644 (file)
index cf0a857..0000000
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.netconf.topology.pipeline;
-
-import akka.actor.ActorContext;
-import akka.actor.ActorSystem;
-import akka.actor.TypedActor;
-import akka.actor.TypedProps;
-import akka.dispatch.OnComplete;
-import akka.japi.Creator;
-import com.google.common.base.Optional;
-import com.google.common.collect.Sets;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import java.util.Set;
-import java.util.concurrent.ExecutorService;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipChange;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListener;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
-import org.opendaylight.netconf.api.NetconfMessage;
-import org.opendaylight.netconf.sal.connect.api.RemoteDeviceCommunicator;
-import org.opendaylight.netconf.sal.connect.api.RemoteDeviceHandler;
-import org.opendaylight.netconf.sal.connect.netconf.NetconfDevice;
-import org.opendaylight.netconf.sal.connect.netconf.NetconfDeviceBuilder;
-import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfDeviceCapabilities;
-import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfDeviceCommunicator;
-import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences;
-import org.opendaylight.netconf.sal.connect.netconf.sal.NetconfDeviceRpc;
-import org.opendaylight.netconf.sal.connect.netconf.schema.mapping.NetconfMessageTransformer;
-import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
-import org.opendaylight.netconf.util.NetconfTopologyPathCreator;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil;
-import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.repo.api.SchemaRepository;
-import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ClusteredNetconfDevice extends NetconfDevice implements EntityOwnershipListener {
-
-    private static final Logger LOG = LoggerFactory.getLogger(ClusteredNetconfDevice.class);
-
-    private NetconfDeviceCommunicator listener;
-    private NetconfSessionPreferences sessionPreferences;
-    private SchemaRepository schemaRepo;
-    private final ActorSystem actorSystem;
-    private final String topologyId;
-    private final String nodeId;
-    private final ActorContext cachedContext;
-
-    private MasterSourceProvider masterSourceProvider = null;
-    private ClusteredDeviceSourcesResolver resolver = null;
-
-    public ClusteredNetconfDevice(final SchemaResourcesDTO schemaResourcesDTO, final RemoteDeviceId id, final RemoteDeviceHandler<NetconfSessionPreferences> salFacade,
-                                  final ExecutorService globalProcessingExecutor, final ActorSystem actorSystem, final String topologyId, final String nodeId,
-                                  final ActorContext cachedContext, final boolean reconnectOnSchemaChanged) {
-        super(schemaResourcesDTO, id, salFacade, globalProcessingExecutor, reconnectOnSchemaChanged);
-        this.schemaRepo = (SchemaRepository) schemaResourcesDTO.getSchemaRegistry();
-        this.actorSystem = actorSystem;
-        this.topologyId = topologyId;
-        this.nodeId = nodeId;
-        this.cachedContext = cachedContext;
-    }
-
-    @Override
-    public void onRemoteSessionUp(NetconfSessionPreferences remoteSessionCapabilities, NetconfDeviceCommunicator listener) {
-        LOG.warn("Node {} SessionUp, with capabilities {}", nodeId, remoteSessionCapabilities);
-        this.listener = listener;
-        this.sessionPreferences = remoteSessionCapabilities;
-        slaveSetupSchema();
-    }
-
-
-    @Override
-    protected void handleSalInitializationSuccess(SchemaContext result, NetconfSessionPreferences remoteSessionCapabilities, DOMRpcService deviceRpc) {
-        super.handleSalInitializationSuccess(result, remoteSessionCapabilities, deviceRpc);
-
-        final Set<SourceIdentifier> sourceIds = Sets.newHashSet();
-        for(ModuleIdentifier id : result.getAllModuleIdentifiers()) {
-            sourceIds.add(SourceIdentifier.create(id.getName(), (SimpleDateFormatUtil.DEFAULT_DATE_REV == id.getRevision() ? Optional.<String>absent() :
-                    Optional.of(SimpleDateFormatUtil.getRevisionFormat().format(id.getRevision())))));
-        }
-
-        //TODO extract string constant to util class
-        LOG.debug("Creating master source provider");
-        masterSourceProvider = TypedActor.get(cachedContext).typedActorOf(
-                new TypedProps<>(MasterSourceProvider.class,
-                        new Creator<MasterSourceProviderImpl>() {
-                            @Override
-                            public MasterSourceProviderImpl create() throws Exception {
-                                return new MasterSourceProviderImpl(schemaRepo, sourceIds, actorSystem, topologyId, nodeId);
-                            }
-                        }), NetconfTopologyPathCreator.MASTER_SOURCE_PROVIDER);
-    }
-
-    @Override
-    public void onRemoteSessionDown() {
-        super.onRemoteSessionDown();
-        listener = null;
-        sessionPreferences = null;
-        if (masterSourceProvider != null) {
-            // if we have master the slave that started on this node should be already killed via PoisonPill, so stop master only now
-            LOG.debug("Stopping master source provider for node {}", nodeId);
-            TypedActor.get(actorSystem).stop(masterSourceProvider);
-            masterSourceProvider = null;
-        } else {
-            LOG.debug("Stopping slave source resolver for node {}", nodeId);
-            TypedActor.get(actorSystem).stop(resolver);
-            resolver = null;
-        }
-    }
-
-    private void slaveSetupSchema() {
-        //TODO extract string constant to util class
-        resolver = TypedActor.get(cachedContext).typedActorOf(
-                new TypedProps<>(ClusteredDeviceSourcesResolver.class,
-                        new Creator<ClusteredDeviceSourcesResolverImpl>() {
-                            @Override
-                            public ClusteredDeviceSourcesResolverImpl create() throws Exception {
-                                return new ClusteredDeviceSourcesResolverImpl(topologyId, nodeId, actorSystem, schemaRegistry, sourceRegistrations);
-                            }
-                        }), NetconfTopologyPathCreator.CLUSTERED_DEVICE_SOURCES_RESOLVER);
-
-        final FutureCallback<SchemaContext> schemaContextFuture = new FutureCallback<SchemaContext>() {
-            @Override
-            public void onSuccess(SchemaContext schemaContext) {
-                LOG.debug("{}: Schema context built successfully.", id);
-
-                final NetconfDeviceCapabilities deviceCap = sessionPreferences.getNetconfDeviceCapabilities();
-                final Set<QName> providedSourcesQnames = Sets.newHashSet();
-                for(ModuleIdentifier id : schemaContext.getAllModuleIdentifiers()) {
-                    providedSourcesQnames.add(QName.create(id.getQNameModule(), id.getName()));
-                }
-
-                deviceCap.addNonModuleBasedCapabilities(sessionPreferences.getNonModuleCaps());
-                deviceCap.addCapabilities(providedSourcesQnames);
-
-                ClusteredNetconfDevice.super.handleSalInitializationSuccess(
-                        schemaContext, sessionPreferences, getDeviceSpecificRpc(schemaContext, listener));
-            }
-
-            @Override
-            public void onFailure(Throwable throwable) {
-                LOG.warn("{}: Unexpected error resolving device sources: {}", id, throwable);
-                handleSalInitializationFailure(throwable, listener);
-            }
-        };
-
-        resolver.getResolvedSources().onComplete(
-                new OnComplete<Set<SourceIdentifier>>() {
-                    @Override
-                    public void onComplete(Throwable throwable, Set<SourceIdentifier> sourceIdentifiers) throws Throwable {
-                        if(throwable != null) {
-                            if(throwable instanceof MasterSourceProviderOnSameNodeException) {
-                                //do nothing
-                            } else {
-                                LOG.warn("{}: Unexpected error resolving device sources: {}", id, throwable);
-                                handleSalInitializationFailure(throwable, listener);
-                            }
-                        } else {
-                            LOG.trace("{}: Trying to build schema context from {}", id, sourceIdentifiers);
-                            Futures.addCallback(schemaContextFactory.createSchemaContext(sourceIdentifiers), schemaContextFuture);
-                        }
-                    }
-                }, actorSystem.dispatcher());
-    }
-
-    private NetconfDeviceRpc getDeviceSpecificRpc(SchemaContext result, RemoteDeviceCommunicator<NetconfMessage> listener) {
-        return new NetconfDeviceRpc(result, listener, new NetconfMessageTransformer(result, true));
-    }
-
-    @Override
-    public void ownershipChanged(EntityOwnershipChange ownershipChange) {
-        LOG.debug("Entity ownership change received {}", ownershipChange);
-        if(ownershipChange.isOwner()) {
-            super.onRemoteSessionUp(sessionPreferences, listener);
-        } else if (ownershipChange.wasOwner()) {
-            slaveSetupSchema();
-        }
-    }
-}
diff --git a/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/pipeline/ClusteredNetconfDeviceCommunicator.java b/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/pipeline/ClusteredNetconfDeviceCommunicator.java
deleted file mode 100644 (file)
index 061024c..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.netconf.topology.pipeline;
-
-import java.util.ArrayList;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListenerRegistration;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
-import org.opendaylight.netconf.api.NetconfMessage;
-import org.opendaylight.netconf.api.NetconfTerminationReason;
-import org.opendaylight.netconf.client.NetconfClientSession;
-import org.opendaylight.netconf.client.NetconfClientSessionListener;
-import org.opendaylight.netconf.sal.connect.netconf.NetconfDevice;
-import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfDeviceCommunicator;
-import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
-
-public class ClusteredNetconfDeviceCommunicator extends NetconfDeviceCommunicator {
-
-    private final EntityOwnershipService ownershipService;
-
-    private final ArrayList<NetconfClientSessionListener> netconfClientSessionListeners = new ArrayList<>();
-    private EntityOwnershipListenerRegistration ownershipListenerRegistration = null;
-
-    public ClusteredNetconfDeviceCommunicator(RemoteDeviceId id, NetconfDevice remoteDevice, EntityOwnershipService ownershipService, final int rpcMessageLimit) {
-        super(id, remoteDevice, rpcMessageLimit);
-        this.ownershipService = ownershipService;
-    }
-
-    @Override
-    public void onMessage(NetconfClientSession session, NetconfMessage message) {
-        super.onMessage(session, message);
-        for(NetconfClientSessionListener listener : netconfClientSessionListeners) {
-            listener.onMessage(session, message);
-        }
-    }
-
-    @Override
-    public void onSessionDown(NetconfClientSession session, Exception e) {
-        super.onSessionDown(session, e);
-        ownershipListenerRegistration.close();
-        for(NetconfClientSessionListener listener : netconfClientSessionListeners) {
-            listener.onSessionDown(session, e);
-        }
-    }
-
-    @Override
-    public void onSessionUp(NetconfClientSession session) {
-        super.onSessionUp(session);
-        ownershipListenerRegistration = ownershipService.registerListener("netconf-node/" + id.getName(), (ClusteredNetconfDevice) remoteDevice);
-        for(NetconfClientSessionListener listener : netconfClientSessionListeners) {
-            listener.onSessionUp(session);
-        }
-    }
-
-    @Override
-    public void onSessionTerminated(NetconfClientSession session, NetconfTerminationReason reason) {
-        super.onSessionTerminated(session, reason);
-        ownershipListenerRegistration.close();
-        for(NetconfClientSessionListener listener : netconfClientSessionListeners) {
-            listener.onSessionTerminated(session, reason);
-        }
-    }
-
-    public NetconfClientSessionListenerRegistration registerNetconfClientSessionListener(NetconfClientSessionListener listener) {
-        netconfClientSessionListeners.add(listener);
-        return new NetconfClientSessionListenerRegistration(listener);
-    }
-
-    public class NetconfClientSessionListenerRegistration {
-
-        private final NetconfClientSessionListener listener;
-
-        public NetconfClientSessionListenerRegistration(NetconfClientSessionListener listener) {
-            this.listener = listener;
-        }
-
-        public void close() {
-            netconfClientSessionListeners.remove(listener);
-        }
-    }
-}
diff --git a/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/pipeline/ClusteredNetconfDeviceMountInstanceProxy.java b/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/pipeline/ClusteredNetconfDeviceMountInstanceProxy.java
deleted file mode 100644 (file)
index 7367512..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.netconf.topology.pipeline;
-
-import com.google.common.base.Preconditions;
-import java.util.Collection;
-import java.util.Collections;
-import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
-import org.opendaylight.controller.sal.core.api.Broker;
-import org.opendaylight.controller.sal.core.api.Provider;
-import org.opendaylight.netconf.sal.connect.netconf.sal.NetconfDeviceSalProvider.MountInstance;
-import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ClusteredNetconfDeviceMountInstanceProxy implements Provider, AutoCloseable{
-
-    private static final Logger LOG = LoggerFactory.getLogger(ClusteredNetconfDeviceMountInstanceProxy.class);
-
-    private final RemoteDeviceId id;
-    private MountInstance mountInstance;
-
-    public ClusteredNetconfDeviceMountInstanceProxy(final RemoteDeviceId deviceId) {
-        this.id = deviceId;
-    }
-
-    public MountInstance getMountInstance() {
-        Preconditions.checkState(mountInstance != null,
-                "%s: Mount instance was not initialized by sal. Cannot get mount instance", id);
-        return mountInstance;
-    }
-
-    @Override
-    public void close() throws Exception {
-        mountInstance.close();
-    }
-
-    @Override
-    public void onSessionInitiated(final Broker.ProviderSession session) {
-        LOG.debug("{}: (BI)Session with sal established {}", id, session);
-
-        final DOMMountPointService mountService = session.getService(DOMMountPointService.class);
-        if (mountService != null) {
-            mountInstance = new MountInstance(mountService, id);
-        }
-    }
-
-    @Override
-    public Collection<ProviderFunctionality> getProviderFunctionality() {
-        return Collections.emptySet();
-    }
-}
diff --git a/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/pipeline/MasterSourceProvider.java b/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/pipeline/MasterSourceProvider.java
deleted file mode 100644 (file)
index f9726f4..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.netconf.topology.pipeline;
-
-import akka.actor.TypedActor;
-import org.opendaylight.controller.cluster.schema.provider.RemoteYangTextSourceProvider;
-
-public interface MasterSourceProvider
-        extends TypedActor.PreStart, TypedActor.Receiver, RemoteYangTextSourceProvider {
-}
diff --git a/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/pipeline/MasterSourceProviderImpl.java b/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/pipeline/MasterSourceProviderImpl.java
deleted file mode 100644 (file)
index 618de81..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.netconf.topology.pipeline;
-
-import akka.actor.ActorRef;
-import akka.actor.ActorSystem;
-import akka.actor.PoisonPill;
-import akka.actor.TypedActor;
-import akka.cluster.Cluster;
-import akka.cluster.Member;
-import java.util.Set;
-import org.opendaylight.controller.cluster.schema.provider.impl.RemoteYangTextSourceProviderImpl;
-import org.opendaylight.netconf.topology.pipeline.messages.AnnounceClusteredDeviceSourcesResolverUp;
-import org.opendaylight.netconf.topology.pipeline.messages.AnnounceMasterOnSameNodeUp;
-import org.opendaylight.netconf.topology.pipeline.messages.AnnounceMasterSourceProviderUp;
-import org.opendaylight.netconf.util.NetconfTopologyPathCreator;
-import org.opendaylight.yangtools.yang.model.repo.api.SchemaRepository;
-import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class MasterSourceProviderImpl extends RemoteYangTextSourceProviderImpl
-        implements MasterSourceProvider {
-
-    private static Logger LOG = LoggerFactory.getLogger(MasterSourceProviderImpl.class);
-
-    private final ActorSystem actorSystem;
-    private final String topologyId;
-    private final String nodeId;
-
-    public MasterSourceProviderImpl(SchemaRepository schemaRepo, Set<SourceIdentifier> providedSources, ActorSystem actorSystem, String topologyId, String nodeId) {
-        super(schemaRepo, providedSources);
-        this.actorSystem = actorSystem;
-        this.topologyId = topologyId;
-        this.nodeId = nodeId;
-    }
-
-    @Override
-    public void onReceive(Object o, ActorRef actorRef) {
-        if(o instanceof AnnounceClusteredDeviceSourcesResolverUp) {
-            LOG.debug("Received source resolver up");
-            actorRef.tell(new AnnounceMasterSourceProviderUp(), TypedActor.context().self());
-        }
-    }
-
-    @Override
-    public void preStart() {
-        Cluster cluster = Cluster.get(actorSystem);
-        cluster.join(cluster.selfAddress());
-        LOG.debug("Notifying members master schema source provider is up.");
-        for(Member node : cluster.state().getMembers()) {
-            final NetconfTopologyPathCreator pathCreator = new NetconfTopologyPathCreator(node.address().toString(),topologyId);
-            final String path = pathCreator.withSuffix(nodeId).withSuffix(NetconfTopologyPathCreator.CLUSTERED_DEVICE_SOURCES_RESOLVER).build();
-            if(node.address().equals(cluster.selfAddress())) {
-                actorSystem.actorSelection(path).tell(new AnnounceMasterOnSameNodeUp(), TypedActor.context().self());
-                actorSystem.actorSelection(path).tell(PoisonPill.getInstance(), TypedActor.context().self());
-            } else {
-                //TODO extract string constant to util class
-                actorSystem.actorSelection(path).tell(new AnnounceMasterSourceProviderUp(), TypedActor.context().self());
-            }
-        }
-    }
-}
diff --git a/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/pipeline/MasterSourceProviderOnSameNodeException.java b/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/pipeline/MasterSourceProviderOnSameNodeException.java
deleted file mode 100644 (file)
index 71f3005..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.netconf.topology.pipeline;
-
-public class MasterSourceProviderOnSameNodeException extends Exception {
-}
diff --git a/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/pipeline/NetconfDeviceMasterDataBroker.java b/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/pipeline/NetconfDeviceMasterDataBroker.java
deleted file mode 100644 (file)
index 17bb793..0000000
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.netconf.topology.pipeline;
-
-import akka.actor.ActorSystem;
-import akka.actor.TypedActor;
-import com.google.common.base.Optional;
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import java.util.Collections;
-import java.util.Map;
-import javax.annotation.Nonnull;
-import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataBrokerExtension;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataChangeListener;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
-import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
-import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences;
-import org.opendaylight.netconf.sal.connect.netconf.sal.NetconfDeviceDataBroker;
-import org.opendaylight.netconf.sal.connect.netconf.sal.tx.ReadWriteTx;
-import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
-import org.opendaylight.netconf.topology.pipeline.tx.ProxyReadOnlyTransaction;
-import org.opendaylight.netconf.topology.pipeline.tx.ProxyWriteOnlyTransaction;
-import org.opendaylight.netconf.topology.util.messages.NormalizedNodeMessage;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import scala.concurrent.Future;
-import scala.concurrent.impl.Promise.DefaultPromise;
-
-public class NetconfDeviceMasterDataBroker implements ProxyNetconfDeviceDataBroker {
-
-    private final RemoteDeviceId id;
-
-    private final NetconfDeviceDataBroker delegateBroker;
-    private final ActorSystem actorSystem;
-
-    private DOMDataReadOnlyTransaction readTx;
-    private DOMDataWriteTransaction writeTx;
-
-    public NetconfDeviceMasterDataBroker(final ActorSystem actorSystem, final RemoteDeviceId id,
-                                         final SchemaContext schemaContext, final DOMRpcService rpc,
-                                         final NetconfSessionPreferences netconfSessionPreferences) {
-        this.id = id;
-        delegateBroker = new NetconfDeviceDataBroker(id, schemaContext, rpc, netconfSessionPreferences);
-        this.actorSystem = actorSystem;
-
-        // only ever need 1 readTx since it doesnt need to be closed
-        readTx = delegateBroker.newReadOnlyTransaction();
-    }
-
-    @Override
-    public DOMDataReadOnlyTransaction newReadOnlyTransaction() {
-        return new ProxyReadOnlyTransaction(actorSystem, id, TypedActor.<NetconfDeviceMasterDataBroker>self());
-    }
-
-    @Override
-    public DOMDataReadWriteTransaction newReadWriteTransaction() {
-        return new ReadWriteTx(new ProxyReadOnlyTransaction(actorSystem, id, TypedActor.<NetconfDeviceMasterDataBroker>self()),
-                newWriteOnlyTransaction());
-    }
-
-    @Override
-    public DOMDataWriteTransaction newWriteOnlyTransaction() {
-        writeTx = delegateBroker.newWriteOnlyTransaction();
-        return new ProxyWriteOnlyTransaction(actorSystem, TypedActor.<NetconfDeviceMasterDataBroker>self());
-    }
-
-    @Override
-    public ListenerRegistration<DOMDataChangeListener> registerDataChangeListener(LogicalDatastoreType store, YangInstanceIdentifier path, DOMDataChangeListener listener, DataChangeScope triggeringScope) {
-        throw new UnsupportedOperationException(id + ": Data change listeners not supported for netconf mount point");
-    }
-
-    @Override
-    public DOMTransactionChain createTransactionChain(TransactionChainListener listener) {
-        throw new UnsupportedOperationException(id + ": Transaction chains not supported for netconf mount point");
-    }
-
-    @Nonnull
-    @Override
-    public Map<Class<? extends DOMDataBrokerExtension>, DOMDataBrokerExtension> getSupportedExtensions() {
-        return Collections.emptyMap();
-    }
-
-    @Override
-    public Future<Optional<NormalizedNodeMessage>> read(final LogicalDatastoreType store, final YangInstanceIdentifier path) {
-        final CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> readFuture = readTx.read(store, path);
-
-        final DefaultPromise<Optional<NormalizedNodeMessage>> promise = new DefaultPromise<>();
-        Futures.addCallback(readFuture, new FutureCallback<Optional<NormalizedNode<?, ?>>>() {
-            @Override
-            public void onSuccess(Optional<NormalizedNode<?, ?>> result) {
-                if (!result.isPresent()) {
-                    promise.success(Optional.<NormalizedNodeMessage>absent());
-                } else {
-                    promise.success(Optional.of(new NormalizedNodeMessage(path, result.get())));
-                }
-            }
-
-            @Override
-            public void onFailure(Throwable t) {
-                promise.failure(t);
-            }
-        });
-        return promise.future();
-    }
-
-    @Override
-    public Future<Boolean> exists(final LogicalDatastoreType store, final YangInstanceIdentifier path) {
-        final CheckedFuture<Boolean, ReadFailedException> existsFuture = readTx.exists(store, path);
-
-        final DefaultPromise<Boolean> promise = new DefaultPromise<>();
-        Futures.addCallback(existsFuture, new FutureCallback<Boolean>() {
-            @Override
-            public void onSuccess(Boolean result) {
-                promise.success(result);
-            }
-
-            @Override
-            public void onFailure(Throwable t) {
-                promise.failure(t);
-            }
-        });
-        return promise.future();
-    }
-
-    @Override
-    public void put(final LogicalDatastoreType store, final NormalizedNodeMessage data) {
-        if (writeTx == null) {
-            writeTx = delegateBroker.newWriteOnlyTransaction();
-        }
-        writeTx.put(store, data.getIdentifier(), data.getNode());
-    }
-
-    @Override
-    public void merge(final LogicalDatastoreType store, final NormalizedNodeMessage data) {
-        if (writeTx == null) {
-            writeTx = delegateBroker.newWriteOnlyTransaction();
-        }
-        writeTx.merge(store, data.getIdentifier(), data.getNode());
-    }
-
-    @Override
-    public void delete(final LogicalDatastoreType store, final YangInstanceIdentifier path) {
-        if (writeTx == null) {
-            writeTx = delegateBroker.newWriteOnlyTransaction();
-        }
-        writeTx.delete(store, path);
-    }
-
-    @Override
-    public boolean cancel() {
-        return writeTx.cancel();
-    }
-
-    @Override
-    public Future<Void> submit() {
-        final CheckedFuture<Void, TransactionCommitFailedException> submitFuture = writeTx.submit();
-        final DefaultPromise<Void> promise = new DefaultPromise<>();
-        Futures.addCallback(submitFuture, new FutureCallback<Void>() {
-            @Override
-            public void onSuccess(Void result) {
-                promise.success(result);
-                writeTx = null;
-            }
-
-            @Override
-            public void onFailure(Throwable t) {
-                promise.failure(t);
-                writeTx = null;
-            }
-        });
-        return promise.future();
-    }
-
-    @Override
-    @Deprecated
-    public Future<RpcResult<TransactionStatus>> commit() {
-        final ListenableFuture<RpcResult<TransactionStatus>> commitFuture = writeTx.commit();
-        final DefaultPromise<RpcResult<TransactionStatus>> promise = new DefaultPromise<>();
-        Futures.addCallback(commitFuture, new FutureCallback<RpcResult<TransactionStatus>>() {
-            @Override
-            public void onSuccess(RpcResult<TransactionStatus> result) {
-                promise.success(result);
-                writeTx = null;
-            }
-
-            @Override
-            public void onFailure(Throwable t) {
-                promise.failure(t);
-                writeTx = null;
-            }
-        });
-        return promise.future();
-    }
-
-}
diff --git a/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/pipeline/ProxyNetconfDeviceDataBroker.java b/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/pipeline/ProxyNetconfDeviceDataBroker.java
deleted file mode 100644 (file)
index 3ef7688..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.netconf.topology.pipeline;
-
-import com.google.common.base.Optional;
-import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
-import org.opendaylight.netconf.topology.util.messages.NormalizedNodeMessage;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import scala.concurrent.Future;
-
-public interface ProxyNetconfDeviceDataBroker extends DOMDataBroker{
-    Future<Optional<NormalizedNodeMessage>> read(LogicalDatastoreType store, YangInstanceIdentifier path);
-
-    Future<Boolean> exists(LogicalDatastoreType store, YangInstanceIdentifier path);
-
-    void put(LogicalDatastoreType store, NormalizedNodeMessage data);
-
-    void merge(LogicalDatastoreType store, NormalizedNodeMessage data);
-
-    void delete(LogicalDatastoreType store, YangInstanceIdentifier path);
-
-    boolean cancel();
-
-    Future<Void> submit();
-
-    @Deprecated
-    Future<RpcResult<TransactionStatus>> commit();
-}
diff --git a/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/pipeline/TopologyMountPointFacade.java b/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/pipeline/TopologyMountPointFacade.java
deleted file mode 100644 (file)
index a44bf47..0000000
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.netconf.topology.pipeline;
-
-import akka.actor.ActorContext;
-import akka.actor.ActorRef;
-import akka.actor.ActorSystem;
-import akka.actor.TypedActor;
-import akka.actor.TypedProps;
-import akka.cluster.Cluster;
-import akka.cluster.Member;
-import akka.japi.Creator;
-import com.google.common.base.Preconditions;
-import java.util.ArrayList;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
-import org.opendaylight.controller.md.sal.dom.api.DOMNotification;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
-import org.opendaylight.controller.sal.core.api.Broker;
-import org.opendaylight.netconf.sal.connect.api.RemoteDeviceHandler;
-import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences;
-import org.opendaylight.netconf.sal.connect.netconf.sal.NetconfDeviceNotificationService;
-import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
-import org.opendaylight.netconf.topology.util.messages.AnnounceMasterMountPoint;
-import org.opendaylight.netconf.topology.util.messages.AnnounceMasterMountPointDown;
-import org.opendaylight.netconf.util.NetconfTopologyPathCreator;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class TopologyMountPointFacade implements AutoCloseable, RemoteDeviceHandler<NetconfSessionPreferences> {
-
-    private static final Logger LOG = LoggerFactory.getLogger(TopologyMountPointFacade.class);
-
-    private static final String MOUNT_POINT = "mountpoint";
-
-    private final String topologyId;
-    private final RemoteDeviceId id;
-    private final Broker domBroker;
-    private final BindingAwareBroker bindingBroker;
-
-    private SchemaContext remoteSchemaContext = null;
-    private NetconfSessionPreferences netconfSessionPreferences = null;
-    private DOMRpcService deviceRpc = null;
-    private final ClusteredNetconfDeviceMountInstanceProxy salProvider;
-
-    private ActorSystem actorSystem;
-    private DOMDataBroker deviceDataBroker = null;
-
-    private final ArrayList<RemoteDeviceHandler<NetconfSessionPreferences>> connectionStatusListeners = new ArrayList<>();
-
-    public TopologyMountPointFacade(final String topologyId,
-                                    final RemoteDeviceId id,
-                                    final Broker domBroker,
-                                    final BindingAwareBroker bindingBroker) {
-        this.topologyId = topologyId;
-        this.id = id;
-        this.domBroker = domBroker;
-        this.bindingBroker = bindingBroker;
-        this.salProvider = new ClusteredNetconfDeviceMountInstanceProxy(id);
-        registerToSal(domBroker);
-    }
-
-    public void registerToSal(final Broker domRegistryDependency) {
-        domRegistryDependency.registerProvider(salProvider);
-    }
-
-    @Override
-    public void onDeviceConnected(final SchemaContext remoteSchemaContext,
-                                  final NetconfSessionPreferences netconfSessionPreferences,
-                                  final DOMRpcService deviceRpc) {
-        // prepare our prerequisites for mountpoint
-        LOG.debug("Mount point facade onConnected capabilities {}", netconfSessionPreferences);
-        this.remoteSchemaContext = remoteSchemaContext;
-        this.netconfSessionPreferences = netconfSessionPreferences;
-        this.deviceRpc = deviceRpc;
-        for (RemoteDeviceHandler<NetconfSessionPreferences> listener : connectionStatusListeners) {
-            listener.onDeviceConnected(remoteSchemaContext, netconfSessionPreferences, deviceRpc);
-        }
-    }
-
-    @Override
-    public void onDeviceDisconnected() {
-        // do not unregister mount point here, this gets handle by the underlying call from role change callback
-        for (RemoteDeviceHandler<NetconfSessionPreferences> listener : connectionStatusListeners) {
-            listener.onDeviceDisconnected();
-        }
-    }
-
-    @Override
-    public void onDeviceFailed(Throwable throwable) {
-        // do not unregister mount point here, this gets handle by the underlying call from role change callback
-        for (RemoteDeviceHandler<NetconfSessionPreferences> listener : connectionStatusListeners) {
-            listener.onDeviceFailed(throwable);
-        }
-    }
-
-    @Override
-    public void onNotification(DOMNotification domNotification) {
-        salProvider.getMountInstance().publish(domNotification);
-    }
-
-    public void registerMountPoint(final ActorSystem actorSystem, final ActorContext context) {
-        if (remoteSchemaContext == null || netconfSessionPreferences == null) {
-            LOG.debug("Master mount point does not have schemas ready yet, delaying registration");
-            return;
-        }
-
-        Preconditions.checkNotNull(id);
-        Preconditions.checkNotNull(remoteSchemaContext, "Device has no remote schema context yet. Probably not fully connected.");
-        Preconditions.checkNotNull(netconfSessionPreferences, "Device has no capabilities yet. Probably not fully connected.");
-        this.actorSystem = actorSystem;
-        final NetconfDeviceNotificationService notificationService = new NetconfDeviceNotificationService();
-
-        LOG.warn("Creating master data broker for device {}", id);
-        deviceDataBroker = TypedActor.get(context).typedActorOf(new TypedProps<>(ProxyNetconfDeviceDataBroker.class, new Creator<NetconfDeviceMasterDataBroker>() {
-            @Override
-            public NetconfDeviceMasterDataBroker create() throws Exception {
-                return new NetconfDeviceMasterDataBroker(actorSystem, id, remoteSchemaContext, deviceRpc, netconfSessionPreferences);
-            }
-        }), MOUNT_POINT);
-        LOG.debug("Master data broker registered on path {}", TypedActor.get(actorSystem).getActorRefFor(deviceDataBroker).path());
-        salProvider.getMountInstance().onTopologyDeviceConnected(remoteSchemaContext, deviceDataBroker, deviceRpc, notificationService);
-        final Cluster cluster = Cluster.get(actorSystem);
-        final Iterable<Member> members = cluster.state().getMembers();
-        final ActorRef deviceDataBrokerRef = TypedActor.get(actorSystem).getActorRefFor(deviceDataBroker);
-        for (final Member member : members) {
-            if (!member.address().equals(cluster.selfAddress())) {
-                final NetconfTopologyPathCreator pathCreator = new NetconfTopologyPathCreator(member.address().toString(),topologyId);
-                final String path = pathCreator.withSuffix(id.getName()).build();
-                actorSystem.actorSelection(path).tell(new AnnounceMasterMountPoint(), deviceDataBrokerRef);
-            }
-        }
-    }
-
-    public void registerMountPoint(final ActorSystem actorSystem, final ActorContext context, final ActorRef masterRef) {
-        if (remoteSchemaContext == null || netconfSessionPreferences == null) {
-            LOG.debug("Slave mount point does not have schemas ready yet, delaying registration");
-            return;
-        }
-
-        Preconditions.checkNotNull(id);
-        Preconditions.checkNotNull(remoteSchemaContext, "Device has no remote schema context yet. Probably not fully connected.");
-        Preconditions.checkNotNull(netconfSessionPreferences, "Device has no capabilities yet. Probably not fully connected.");
-        this.actorSystem = actorSystem;
-        final NetconfDeviceNotificationService notificationService = new NetconfDeviceNotificationService();
-
-        final ProxyNetconfDeviceDataBroker masterDataBroker = TypedActor.get(actorSystem).typedActorOf(new TypedProps<>(ProxyNetconfDeviceDataBroker.class, NetconfDeviceMasterDataBroker.class), masterRef);
-        LOG.warn("Creating slave data broker for device {}", id);
-        final DOMDataBroker deviceDataBroker = new NetconfDeviceSlaveDataBroker(actorSystem, id, masterDataBroker);
-        salProvider.getMountInstance().onTopologyDeviceConnected(remoteSchemaContext, deviceDataBroker, deviceRpc, notificationService);
-    }
-
-    public void unregisterMountPoint() {
-        salProvider.getMountInstance().onTopologyDeviceDisconnected();
-        if (deviceDataBroker != null) {
-            LOG.debug("Stopping master data broker for device {}", id.getName());
-            for (final Member member : Cluster.get(actorSystem).state().getMembers()) {
-                if (member.address().equals(Cluster.get(actorSystem).selfAddress())) {
-                    continue;
-                }
-                final NetconfTopologyPathCreator pathCreator = new NetconfTopologyPathCreator(member.address().toString(), topologyId);
-                final String path = pathCreator.withSuffix(id.getName()).build();
-                actorSystem.actorSelection(path).tell(new AnnounceMasterMountPointDown(), null);
-            }
-            TypedActor.get(actorSystem).stop(deviceDataBroker);
-            deviceDataBroker = null;
-        }
-    }
-
-    public ConnectionStatusListenerRegistration registerConnectionStatusListener(final RemoteDeviceHandler<NetconfSessionPreferences> listener) {
-        connectionStatusListeners.add(listener);
-        return new ConnectionStatusListenerRegistration(listener);
-    }
-
-    @Override
-    public void close() {
-        closeGracefully(salProvider);
-    }
-
-    private void closeGracefully(final AutoCloseable resource) {
-        if (resource != null) {
-            try {
-                resource.close();
-            } catch (final Exception e) {
-                LOG.warn("{}: Ignoring exception while closing {}", id, resource, e);
-            }
-        }
-    }
-
-    public class ConnectionStatusListenerRegistration{
-
-        private final RemoteDeviceHandler<NetconfSessionPreferences> listener;
-
-        public ConnectionStatusListenerRegistration(final RemoteDeviceHandler<NetconfSessionPreferences> listener) {
-            this.listener = listener;
-        }
-
-        public void close() {
-            connectionStatusListeners.remove(listener);
-        }
-    }
-}
diff --git a/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/pipeline/messages/AnnounceClusteredDeviceSourcesResolverUp.java b/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/pipeline/messages/AnnounceClusteredDeviceSourcesResolverUp.java
deleted file mode 100644 (file)
index f8328e7..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.netconf.topology.pipeline.messages;
-
-import java.io.Serializable;
-
-public class AnnounceClusteredDeviceSourcesResolverUp implements Serializable {
-    public static final long serialVersionUID = 1L;
-
-    public AnnounceClusteredDeviceSourcesResolverUp() {}
-}
diff --git a/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/pipeline/messages/AnnounceMasterOnSameNodeUp.java b/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/pipeline/messages/AnnounceMasterOnSameNodeUp.java
deleted file mode 100644 (file)
index 793321c..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.netconf.topology.pipeline.messages;
-
-import java.io.Serializable;
-
-public class AnnounceMasterOnSameNodeUp  implements Serializable {
-    public static long serialVersionUID = 1L;
-
-    public AnnounceMasterOnSameNodeUp() {
-
-    }
-}
diff --git a/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/pipeline/messages/AnnounceMasterSourceProviderUp.java b/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/pipeline/messages/AnnounceMasterSourceProviderUp.java
deleted file mode 100644 (file)
index 7bec681..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.netconf.topology.pipeline.messages;
-
-import java.io.Serializable;
-
-public class AnnounceMasterSourceProviderUp implements Serializable {
-    public static final long serialVersionUID = 1L;
-
-    public AnnounceMasterSourceProviderUp() {
-
-    }
-}
diff --git a/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/pipeline/tx/ProxyWriteOnlyTransaction.java b/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/pipeline/tx/ProxyWriteOnlyTransaction.java
deleted file mode 100644 (file)
index d7a3c87..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.netconf.topology.pipeline.tx;
-
-import akka.actor.ActorSystem;
-import akka.dispatch.OnComplete;
-import com.google.common.base.Function;
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.SettableFuture;
-import javax.annotation.Nullable;
-import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
-import org.opendaylight.netconf.topology.pipeline.ProxyNetconfDeviceDataBroker;
-import org.opendaylight.netconf.topology.util.messages.NormalizedNodeMessage;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import scala.concurrent.Future;
-
-public class ProxyWriteOnlyTransaction implements DOMDataWriteTransaction {
-
-    private final ProxyNetconfDeviceDataBroker delegate;
-    private final ActorSystem actorSystem;
-
-    public ProxyWriteOnlyTransaction(ActorSystem actorSystem, final ProxyNetconfDeviceDataBroker delegate) {
-        this.delegate = delegate;
-        this.actorSystem = actorSystem;
-    }
-
-    @Override
-    public void put (final LogicalDatastoreType store, final YangInstanceIdentifier path, final NormalizedNode < ?,?>data){
-        delegate.put(store, new NormalizedNodeMessage(path, data));
-    }
-
-    @Override
-    public void merge (final LogicalDatastoreType store, final YangInstanceIdentifier path, final NormalizedNode < ?,?>data){
-        delegate.merge(store, new NormalizedNodeMessage(path, data));
-    }
-
-    @Override
-    public boolean cancel () {
-        return delegate.cancel();
-    }
-
-    @Override
-    public void delete (final LogicalDatastoreType store, final YangInstanceIdentifier path){
-        delegate.delete(store, path);
-    }
-
-    @Override
-    public CheckedFuture<Void, TransactionCommitFailedException> submit() {
-        final Future<Void> submit = delegate.submit();
-        final SettableFuture<Void> settableFuture = SettableFuture.create();
-        final CheckedFuture<Void, TransactionCommitFailedException> checkedFuture = Futures.makeChecked(settableFuture, new Function<Exception, TransactionCommitFailedException>() {
-            @Nullable
-            @Override
-            public TransactionCommitFailedException apply(Exception input) {
-                return new TransactionCommitFailedException("Transaction commit failed", input);
-            }
-        });
-        submit.onComplete(new OnComplete<Void>() {
-            @Override
-            public void onComplete(Throwable throwable, Void aVoid) throws Throwable {
-                if (throwable == null) {
-                    settableFuture.set(aVoid);
-                } else {
-                    settableFuture.setException(throwable);
-                }
-            }
-        }, actorSystem.dispatcher());
-        return checkedFuture;
-    }
-
-    @Override
-    public ListenableFuture<RpcResult<TransactionStatus>> commit () {
-        final Future<RpcResult<TransactionStatus>> commit = delegate.commit();
-        final SettableFuture<RpcResult<TransactionStatus>> settableFuture = SettableFuture.create();
-        commit.onComplete(new OnComplete<RpcResult<TransactionStatus>>() {
-            @Override
-            public void onComplete(Throwable throwable, RpcResult<TransactionStatus> transactionStatusRpcResult) throws Throwable {
-                if (throwable == null) {
-                    settableFuture.set(transactionStatusRpcResult);
-                } else {
-                    settableFuture.setException(throwable);
-                }
-            }
-        }, actorSystem.dispatcher());
-        return settableFuture;
-    }
-
-    @Override
-    public Object getIdentifier () {
-        return this;
-    }
-}
diff --git a/netconf/netconf-topology/src/main/yang/clustered-netconf-topology.yang b/netconf/netconf-topology/src/main/yang/clustered-netconf-topology.yang
deleted file mode 100644 (file)
index 6e72443..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-module clustered-netconf-topology {
-
-    yang-version 1;
-    namespace "urn:opendaylight:params:xml:ns:yang:controller:clustered:netconf:topology";
-    prefix "nt";
-
-    import config { prefix config; revision-date 2013-04-05; }
-    import threadpool {prefix th;}
-    import netty {prefix netty;}
-    import opendaylight-md-sal-dom {prefix dom;}
-    import opendaylight-md-sal-binding {prefix md-sal-binding; revision-date 2013-10-28;}
-    import odl-netconf-cfg { prefix cfg-net; revision-date 2014-04-08; }
-    import shared-schema-repository { prefix sh; revision-date 2015-07-27; }
-    import netconf-topology { prefix topo; revision-date 2015-07-27; }
-    import opendaylight-entity-ownership-service { prefix eos; revision-date 2015-08-10; }
-    import actor-system-provider-service { prefix asp; revision-date 2015-10-05; }
-
-    description
-            "Module definition for Netconf topolgy. Netconf topology provides a set of common configuration ";
-
-    revision "2015-11-04" {
-        description
-            "Initial revision";
-    }
-
-    identity clustered-netconf-topology-impl {
-        base config:module-type;
-        config:java-name-prefix ClusteredNetconfTopology;
-        config:provided-service topo:netconf-topology;
-    }
-
-    augment "/config:modules/config:module/config:configuration" {
-        case clustered-netconf-topology-impl {
-            when "/config:modules/config:module/config:type = 'clustered-netconf-topology-impl'";
-
-            leaf topology-id {
-                mandatory true;
-                type string;
-            }
-
-            container dom-registry {
-                uses config:service-ref {
-                    refine type {
-                        mandatory true;
-                        config:required-identity dom:dom-broker-osgi-registry;
-                    }
-                }
-            }
-
-            container binding-registry {
-                uses config:service-ref {
-                    refine type {
-                        mandatory true;
-                        config:required-identity md-sal-binding:binding-broker-osgi-registry;
-                    }
-                }
-            }
-
-            container event-executor {
-                uses config:service-ref {
-                    refine type {
-                        mandatory true;
-                        config:required-identity netty:netty-event-executor;
-                    }
-                }
-            }
-
-            container processing-executor {
-                uses config:service-ref {
-                    refine type {
-                        mandatory true;
-                        config:required-identity th:threadpool;
-                    }
-                }
-
-                description "Makes up for flaws in netty threading design";
-            }
-
-            container client-dispatcher {
-                uses config:service-ref {
-                    refine type {
-                        mandatory false;
-                        config:required-identity cfg-net:netconf-client-dispatcher;
-                    }
-                }
-            }
-
-            container keepalive-executor {
-                uses config:service-ref {
-                    refine type {
-                        mandatory false;
-                        config:required-identity th:scheduled-threadpool;
-                    }
-                }
-
-                description "Dedicated solely to keepalive execution";
-            }
-
-            container shared-schema-repository {
-                uses config:service-ref {
-                    refine type {
-                        mandatory true;
-                        config:required-identity sh:shared-schema-repository;
-                    }
-                }
-            }
-
-            container entity-ownership-service {
-                uses config:service-ref {
-                    refine type {
-                        mandatory true;
-                        config:required-identity eos:entity-ownership-service;
-                    }
-                }
-            }
-
-            container actor-system-provider-service {
-                uses config:service-ref {
-                    refine type {
-                        mandatory true;
-                        config:required-identity asp:actor-system-provider-service;
-                    }
-                }
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/netconf/netconf-topology/src/test/java/org/opendaylight/netconf/topology/AbstractNetconfTopologyTest.java b/netconf/netconf-topology/src/test/java/org/opendaylight/netconf/topology/AbstractNetconfTopologyTest.java
deleted file mode 100644 (file)
index a9d3e38..0000000
+++ /dev/null
@@ -1,318 +0,0 @@
-/*
- * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.netconf.topology;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import akka.actor.ActorContext;
-import akka.actor.ActorRef;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.MoreExecutors;
-import io.netty.util.concurrent.EventExecutor;
-import io.netty.util.concurrent.Future;
-import io.netty.util.concurrent.ImmediateEventExecutor;
-import io.netty.util.concurrent.SucceededFuture;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.UnknownHostException;
-import java.util.concurrent.ExecutionException;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.opendaylight.controller.config.threadpool.ScheduledThreadPool;
-import org.opendaylight.controller.config.threadpool.ThreadPool;
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
-import org.opendaylight.controller.sal.core.api.Broker;
-import org.opendaylight.netconf.client.NetconfClientDispatcher;
-import org.opendaylight.netconf.client.NetconfClientSessionListener;
-import org.opendaylight.netconf.client.conf.NetconfClientConfiguration;
-import org.opendaylight.netconf.client.conf.NetconfReconnectingClientConfiguration;
-import org.opendaylight.netconf.sal.connect.api.RemoteDeviceHandler;
-import org.opendaylight.netconf.sal.connect.netconf.NetconfDevice;
-import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfDeviceCapabilities;
-import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences;
-import org.opendaylight.netconf.sal.connect.netconf.sal.KeepaliveSalFacade;
-import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
-import org.opendaylight.netconf.topology.pipeline.TopologyMountPointFacade;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Host;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.credentials.Credentials;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.credentials.credentials.LoginPasswordBuilder;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.opendaylight.yangtools.yang.binding.DataContainer;
-import org.opendaylight.yangtools.yang.parser.repo.SharedSchemaRepository;
-
-public class AbstractNetconfTopologyTest {
-
-    private static final NodeId NODE_ID = new NodeId("testing-node");
-    private static final String TOPOLOGY_ID = "testing-topology";
-
-    @Mock
-    private Broker mockedDataBroker;
-
-    @Mock
-    private NetconfClientDispatcher mockedClientDispatcher;
-
-    @Mock
-    private BindingAwareBroker mockedBindingAwareBroker;
-
-    @Mock
-    private EventExecutor mockedEventExecutor;
-
-    @Mock
-    private ScheduledThreadPool mockedKeepaliveExecutor;
-
-    @Mock
-    private ThreadPool mockedProcessingExecutor;
-
-    @Mock
-    private SchemaRepositoryProvider mockedSchemaRepositoryProvider;
-
-
-    private TestingAbstractNetconfTopology topology;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-
-        when(mockedSchemaRepositoryProvider.getSharedSchemaRepository()).thenReturn(new SharedSchemaRepository("testingSharedSchemaRepo"));
-        when(mockedProcessingExecutor.getExecutor()).thenReturn(MoreExecutors.newDirectExecutorService());
-        Future<Void> future = new SucceededFuture<>(ImmediateEventExecutor.INSTANCE, null);
-        when(mockedClientDispatcher.createReconnectingClient(any(NetconfReconnectingClientConfiguration.class))).thenReturn(future);
-
-        topology = new TestingAbstractNetconfTopology(TOPOLOGY_ID, mockedClientDispatcher, mockedBindingAwareBroker,
-                mockedDataBroker, mockedEventExecutor, mockedKeepaliveExecutor, mockedProcessingExecutor, mockedSchemaRepositoryProvider);
-    }
-
-    @Test
-    public void testCreateSalFacade() {
-        NetconfNode testingNode = new NetconfNodeBuilder()
-                .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
-                .setPort(new PortNumber(9999))
-                .setReconnectOnChangedSchema(true)
-                .setDefaultRequestTimeoutMillis(1000L)
-                .setBetweenAttemptsTimeoutMillis(100)
-                .setSchemaless(false)
-                .build();
-
-        AbstractNetconfTopology.NetconfConnectorDTO connectorDTO = topology.createDeviceCommunicator(NODE_ID, testingNode);
-        assertSame(connectorDTO.getFacade(), topology.getFacade());
-    }
-
-    @Test
-    public void testCreateKeepAliveSalFacade() {
-        NetconfNode testingNode = new NetconfNodeBuilder()
-                .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
-                .setPort(new PortNumber(9999))
-                .setReconnectOnChangedSchema(true)
-                .setDefaultRequestTimeoutMillis(1000L)
-                .setBetweenAttemptsTimeoutMillis(100)
-                .setKeepaliveDelay(1L)
-                .setSchemaless(false)
-                .build();
-
-        AbstractNetconfTopology.NetconfConnectorDTO connectorDTO = topology.createDeviceCommunicator(NODE_ID, testingNode);
-        assertTrue(connectorDTO.getFacade() instanceof KeepaliveSalFacade);
-    }
-
-    @Test
-    public void testSetupSchemaResourceDTO() {
-        NetconfNode testingNode = new NetconfNodeBuilder()
-                .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
-                .setPort(new PortNumber(9999))
-                .setReconnectOnChangedSchema(true)
-                .setDefaultRequestTimeoutMillis(1000L)
-                .setBetweenAttemptsTimeoutMillis(100)
-                .setKeepaliveDelay(1000L).build();
-
-        NetconfDevice.SchemaResourcesDTO resultDTO = topology.setupSchemaCacheDTO(NODE_ID, testingNode);
-        SharedSchemaRepository repo = (SharedSchemaRepository) resultDTO.getSchemaRegistry();
-        assertEquals(repo.getIdentifier(), "sal-netconf-connector");
-
-        testingNode = new NetconfNodeBuilder()
-                .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
-                .setPort(new PortNumber(9999))
-                .setReconnectOnChangedSchema(true)
-                .setDefaultRequestTimeoutMillis(1000L)
-                .setBetweenAttemptsTimeoutMillis(100)
-                .setKeepaliveDelay(1000L)
-                .setSchemaCacheDirectory("test-directory")
-                .build();
-
-        resultDTO = topology.setupSchemaCacheDTO(NODE_ID, testingNode);
-        repo = (SharedSchemaRepository) resultDTO.getSchemaRegistry();
-        assertEquals(repo.getIdentifier(), "test-directory");
-    }
-
-    @Test
-    public void testGetClientConfig() throws UnknownHostException {
-        NetconfClientSessionListener listener = mock(NetconfClientSessionListener.class);
-        Host host = new Host(new IpAddress(new Ipv4Address("127.0.0.1")));
-        PortNumber portNumber = new PortNumber(9999);
-        NetconfNode testingNode = new NetconfNodeBuilder()
-                .setConnectionTimeoutMillis(1000L)
-                .setDefaultRequestTimeoutMillis(2000L)
-                .setHost(host)
-                .setPort(portNumber)
-                .setCredentials(new LoginPasswordBuilder().setUsername("testuser").setPassword("testpassword").build())
-                .setTcpOnly(true)
-                .build();
-        NetconfReconnectingClientConfiguration defaultClientConfig = topology.getClientConfig(listener, testingNode);
-
-        assertEquals(defaultClientConfig.getConnectionTimeoutMillis().longValue(), 1000L);
-        assertEquals(defaultClientConfig.getAddress(), new InetSocketAddress(InetAddress.getByName("127.0.0.1"), 9999));
-        assertSame(defaultClientConfig.getSessionListener(), listener);
-        assertEquals(defaultClientConfig.getAuthHandler().getUsername(), "testuser");
-        assertEquals(defaultClientConfig.getProtocol(), NetconfClientConfiguration.NetconfClientProtocol.TCP);
-    }
-
-    @Test
-    public void testGetClientConfigNotSupportedCredentialsFail() {
-        NetconfClientSessionListener listener = mock(NetconfClientSessionListener.class);
-        Host host = new Host(new IpAddress(new Ipv4Address("127.0.0.1")));
-        PortNumber portNumber = new PortNumber(9999);
-
-        Credentials notSupportedCredentials = new Credentials() {
-            @Override
-            public Class<? extends DataContainer> getImplementedInterface() {
-                return Credentials.class;
-            }
-        };
-
-        NetconfNode testingNode = new NetconfNodeBuilder()
-                .setConnectionTimeoutMillis(1000L)
-                .setDefaultRequestTimeoutMillis(2000L)
-                .setHost(host)
-                .setPort(portNumber)
-                .setCredentials(notSupportedCredentials)
-                .setTcpOnly(true)
-                .build();
-        try {
-            topology.getClientConfig(listener, testingNode);
-            fail("Exception expected here.");
-        } catch(Exception e) {
-            assertTrue(e instanceof IllegalStateException);
-        }
-    }
-
-    @Test
-    public void testConnectNode() {
-        NetconfNode testingNode = new NetconfNodeBuilder()
-                .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
-                .setPort(new PortNumber(9999))
-                .setReconnectOnChangedSchema(true)
-                .setDefaultRequestTimeoutMillis(1000L)
-                .setBetweenAttemptsTimeoutMillis(100)
-                .setKeepaliveDelay(1000L)
-                .setTcpOnly(true)
-                .setSchemaless(false)
-                .setCredentials(new LoginPasswordBuilder().setUsername("testuser").setPassword("testpassword").build())
-                .build();
-        Node nd = mock(Node.class);
-        when(nd.getAugmentation(NetconfNode.class)).thenReturn(testingNode);
-        topology.connectNode(NODE_ID, nd);
-        assertTrue(topology.activeConnectors.containsKey(NODE_ID));
-    }
-
-    @Test
-    public void testDisconnectNode() {
-        NetconfNode testingNode = new NetconfNodeBuilder()
-                .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
-                .setPort(new PortNumber(9999))
-                .setReconnectOnChangedSchema(true)
-                .setDefaultRequestTimeoutMillis(1000L)
-                .setBetweenAttemptsTimeoutMillis(100)
-                .setKeepaliveDelay(1000L)
-                .setTcpOnly(true)
-                .setSchemaless(false)
-                .setCredentials(new LoginPasswordBuilder().setUsername("testuser").setPassword("testpassword").build())
-                .build();
-        Node nd = mock(Node.class);
-        when(nd.getAugmentation(NetconfNode.class)).thenReturn(testingNode);
-        topology.connectNode(NODE_ID, nd);
-        assertTrue(topology.activeConnectors.containsKey(NODE_ID));
-        assertTrue(topology.disconnectNode(NODE_ID).isDone());
-        assertTrue(!topology.activeConnectors.containsKey(NODE_ID));
-        verify(topology.getFacade()).close();
-    }
-
-    @Test
-    public void testDisconnectNotConnectedNode() throws ExecutionException, InterruptedException {
-        ListenableFuture disconnectFuture = topology.disconnectNode(NODE_ID);
-        assertTrue(disconnectFuture.isDone());
-        try {
-            disconnectFuture.get();
-            fail("Exception expected!");
-        } catch(Exception e) {
-            assertTrue(e instanceof ExecutionException);
-            assertTrue(e.getCause() instanceof  IllegalStateException);
-        }
-    }
-
-    public static class TestingAbstractNetconfTopology extends AbstractNetconfTopology {
-
-        private RemoteDeviceHandler salFacade;
-
-        protected TestingAbstractNetconfTopology(String topologyId, NetconfClientDispatcher clientDispatcher,
-                                                 BindingAwareBroker bindingAwareBroker, Broker domBroker,
-                                                 EventExecutor eventExecutor, ScheduledThreadPool keepaliveExecutor,
-                                                 ThreadPool processingExecutor,
-                                                 SchemaRepositoryProvider schemaRepositoryProvider) {
-            super(topologyId, clientDispatcher, bindingAwareBroker, domBroker, eventExecutor, keepaliveExecutor, processingExecutor, schemaRepositoryProvider);
-            salFacade = mock(RemoteDeviceHandler.class);
-        }
-
-        public RemoteDeviceHandler<NetconfSessionPreferences> getFacade() {
-            return salFacade;
-        }
-
-        @Override
-        public void onSessionInitiated(BindingAwareBroker.ProviderContext session) {
-
-        }
-
-        @Override
-        protected RemoteDeviceHandler<NetconfSessionPreferences> createSalFacade(RemoteDeviceId id, Broker domBroker, BindingAwareBroker bindingBroker) {
-            return salFacade;
-        }
-
-        @Override
-        public TopologyMountPointFacade.ConnectionStatusListenerRegistration registerConnectionStatusListener(NodeId node, RemoteDeviceHandler<NetconfSessionPreferences> listener) {
-            return null;
-        }
-
-        @Override
-        public void registerMountPoint(ActorContext context, NodeId nodeId) {
-
-        }
-
-        @Override
-        public void registerMountPoint(ActorContext context, NodeId nodeId, ActorRef masterRef) {
-
-        }
-
-        @Override
-        public void unregisterMountPoint(NodeId nodeId) {
-
-        }
-    }
-}
diff --git a/netconf/netconf-topology/src/test/java/org/opendaylight/netconf/topology/ActorTest.java b/netconf/netconf-topology/src/test/java/org/opendaylight/netconf/topology/ActorTest.java
deleted file mode 100644 (file)
index ced7d01..0000000
+++ /dev/null
@@ -1,719 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.netconf.topology;
-
-import static com.jayway.awaitility.Awaitility.await;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.when;
-
-import akka.actor.ActorRef;
-import akka.actor.ActorSystem;
-import akka.actor.TypedActor;
-import akka.actor.TypedActorExtension;
-import akka.actor.TypedProps;
-import akka.japi.Creator;
-import com.google.common.base.Function;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Lists;
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.SettableFuture;
-import com.typesafe.config.ConfigFactory;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
-import javassist.ClassPool;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
-import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
-import org.opendaylight.controller.md.sal.dom.api.DOMNotification;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
-import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences;
-import org.opendaylight.netconf.topology.NodeManagerCallback.NodeManagerCallbackFactory;
-import org.opendaylight.netconf.topology.TopologyManagerCallback.TopologyManagerCallbackFactory;
-import org.opendaylight.netconf.topology.example.ExampleNodeManagerCallback;
-import org.opendaylight.netconf.topology.example.ExampleTopologyManagerCallback;
-import org.opendaylight.netconf.topology.example.LoggingSalNodeWriter;
-import org.opendaylight.netconf.topology.impl.NetconfNodeOperationalDataAggregator;
-import org.opendaylight.netconf.topology.util.BaseTopologyManager;
-import org.opendaylight.netconf.topology.util.NoopRoleChangeStrategy;
-import org.opendaylight.netconf.topology.util.TopologyRoleChangeStrategy;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Host;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.$YangModuleInfoImpl;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus.ConnectionStatus;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.AvailableCapabilitiesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.ClusteredConnectionStatusBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.UnavailableCapabilitiesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.clustered.connection.status.NodeStatus.Status;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.clustered.connection.status.NodeStatusBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.unavailable.capabilities.UnavailableCapability;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
-import org.opendaylight.yangtools.binding.data.codec.gen.impl.StreamWriterGenerator;
-import org.opendaylight.yangtools.binding.data.codec.impl.BindingNormalizedNodeCodecRegistry;
-import org.opendaylight.yangtools.sal.binding.generator.impl.ModuleInfoBackedContext;
-import org.opendaylight.yangtools.sal.binding.generator.util.BindingRuntimeContext;
-import org.opendaylight.yangtools.sal.binding.generator.util.JavassistUtils;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ActorTest {
-
-    private static final Logger LOG = LoggerFactory.getLogger(ActorTest.class);
-
-    private static final String TOPOLOGY_NETCONF = "TopologyNetconf";
-
-    @Mock
-    private EntityOwnershipService entityOwnershipService;
-
-    @Mock
-    private DataBroker dataBroker;
-
-    @Mock
-    private ReadOnlyTransaction mockedReadOnlyTx;
-
-    private static final BindingNormalizedNodeCodecRegistry CODEC_REGISTRY;
-
-    static {
-        final ModuleInfoBackedContext moduleInfoBackedContext = ModuleInfoBackedContext.create();
-        moduleInfoBackedContext.addModuleInfos(Collections.singletonList($YangModuleInfoImpl.getInstance()));
-        final Optional<SchemaContext> schemaContextOptional = moduleInfoBackedContext.tryToCreateSchemaContext();
-        Preconditions.checkState(schemaContextOptional.isPresent());
-        final SchemaContext topologySchemaCtx = schemaContextOptional.get();
-
-        final JavassistUtils javassist = JavassistUtils.forClassPool(ClassPool.getDefault());
-        CODEC_REGISTRY = new BindingNormalizedNodeCodecRegistry(StreamWriterGenerator.create(javassist));
-        CODEC_REGISTRY.onBindingRuntimeContextUpdated(BindingRuntimeContext.create(moduleInfoBackedContext, topologySchemaCtx));
-    }
-
-    private static final String PATH_MASTER = "akka.tcp://NetconfNode@127.0.0.1:2552/user/TopologyNetconf";
-    private static final String PATH_SLAVE1 = "akka.tcp://NetconfNode@127.0.0.1:2553/user/TopologyNetconf";
-    private static final String PATH_SLAVE2 = "akka.tcp://NetconfNode@127.0.0.1:2554/user/TopologyNetconf";
-
-    private static final List<String> PATHS_MASTER = Lists.newArrayList(PATH_SLAVE1, PATH_SLAVE2);
-    private static final List<String> PATHS_SLAVE1 = Lists.newArrayList(PATH_MASTER, PATH_SLAVE2);
-    private static final List<String> PATHS_SLAVE2 = Lists.newArrayList(PATH_MASTER, PATH_SLAVE1);
-
-    private static final ActorSystem ACTOR_SYSTEM = ActorSystem.create("NetconfNode", ConfigFactory.load("netconf-node1"));
-    private static final ActorSystem ACTOR_SYSTEM_SLAVE1 = ActorSystem.create("NetconfNode", ConfigFactory.load("netconf-node2"));
-    private static final ActorSystem ACTOR_SYSTEM_SLAVE2 = ActorSystem.create("NetconfNode", ConfigFactory.load("netconf-node3"));
-
-    private static final ExecutorService callbackExecutor = Executors.newFixedThreadPool(8);
-
-    private TopologyManager master = null;
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-        final SettableFuture<Optional<Topology>> settableFuture = SettableFuture.create();
-        final CheckedFuture<Optional<Topology>, ReadFailedException> checkedFuture = Futures.makeChecked(settableFuture, new Function<Exception, ReadFailedException>() {
-            @Nullable
-            @Override
-            public ReadFailedException apply(Exception input) {
-                return new ReadFailedException("Dummy future should never return this");
-            }
-        });
-        settableFuture.set(Optional.<Topology>absent());
-        when(mockedReadOnlyTx.read(any(LogicalDatastoreType.class), any(InstanceIdentifier.class))).thenReturn(checkedFuture);
-        when(dataBroker.registerDataChangeListener(
-                any(LogicalDatastoreType.class),
-                any(InstanceIdentifier.class),
-                any(DataChangeListener.class),
-                any(DataChangeScope.class))).thenReturn(null);
-        when(dataBroker.newReadOnlyTransaction()).thenReturn(mockedReadOnlyTx);
-    }
-
-    private void setMaster(final TopologyManager manager) {
-
-    }
-
-    @Test
-    public void testRealActors() throws Exception {
-
-        EntityOwnershipService topoOwnership = new TestingEntityOwnershipService();
-        // load from config
-        final TopologyManager master = createManagerWithOwnership(ACTOR_SYSTEM, TOPOLOGY_NETCONF, true, createRealTopoTestingNodeCallbackFactory(), new TopologyRoleChangeStrategy(dataBroker, topoOwnership, TOPOLOGY_NETCONF, "topology-manager"));
-        Thread.sleep(1000);
-        final TopologyManager slave1 = createManagerWithOwnership(ACTOR_SYSTEM_SLAVE1, TOPOLOGY_NETCONF, false, createRealTopoTestingNodeCallbackFactory(), new TopologyRoleChangeStrategy(dataBroker, topoOwnership, TOPOLOGY_NETCONF, "topology-manager"));
-        final TopologyManager slave2 = createManagerWithOwnership(ACTOR_SYSTEM_SLAVE2, TOPOLOGY_NETCONF, false, createRealTopoTestingNodeCallbackFactory(), new TopologyRoleChangeStrategy(dataBroker, topoOwnership, TOPOLOGY_NETCONF, "topology-manager"));
-
-        await().atMost(30L, TimeUnit.SECONDS).until(new Callable<Boolean>() {
-            @Override
-            public Boolean call() throws Exception {
-                return master.hasAllPeersUp();
-            }
-        });
-
-        final List<ListenableFuture<Node>> futures = new ArrayList<>();
-        for (int i = 0; i <= 1; i++) {
-            final String nodeid = "testing-node" + i;
-            final Node testingNode = new NodeBuilder()
-                    .setNodeId(new NodeId(nodeid))
-                    .addAugmentation(NetconfNode.class,
-                            new NetconfNodeBuilder()
-                                    .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
-                                    .setPort(new PortNumber(10000 + i))
-                                    .build())
-                    .build();
-            final ListenableFuture<Node> nodeListenableFuture = master.onNodeCreated(new NodeId(nodeid), testingNode);
-            futures.add(nodeListenableFuture);
-            Futures.addCallback(nodeListenableFuture, new FutureCallback<Node>() {
-                @Override
-                public void onSuccess(Node result) {
-                    LOG.warn("Node {} created succesfully on all nodes", result.getNodeId().getValue());
-                }
-
-                @Override
-                public void onFailure(Throwable t) {
-                    LOG.warn("Node creation failed. ", t);
-                }
-            });
-        }
-
-        for (int i = 0; i <= 1; i++) {
-            final String nodeid = "testing-node" + i;
-            final Node testingNode = new NodeBuilder()
-                    .setNodeId(new NodeId(nodeid))
-                    .addAugmentation(NetconfNode.class,
-                            new NetconfNodeBuilder()
-                                    .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
-                                    .setPort(new PortNumber(10000 + i))
-                                    .build())
-                    .build();
-            final ListenableFuture<Node> nodeListenableFuture = master.onNodeUpdated(new NodeId(nodeid), testingNode);
-            futures.add(nodeListenableFuture);
-            Futures.addCallback(nodeListenableFuture, new FutureCallback<Node>() {
-                @Override
-                public void onSuccess(Node result) {
-                    LOG.warn("Node {} updated succesfully on all nodes", result.getNodeId().getValue());
-                }
-
-                @Override
-                public void onFailure(Throwable t) {
-                    LOG.warn("Node update failed. ", t);
-                }
-            });
-        }
-        LOG.debug("Waiting for updates to finish");
-        Futures.allAsList(futures).get();
-
-
-        final List<ListenableFuture<Void>> deleteFutures = new ArrayList<>();
-        for (int i = 0; i <= 1; i++) {
-            final String nodeid = "testing-node" + i;
-            final ListenableFuture<Void> nodeListenableFuture = master.onNodeDeleted(new NodeId(nodeid));
-            deleteFutures.add(nodeListenableFuture);
-            Futures.addCallback(nodeListenableFuture, new FutureCallback<Void>() {
-                @Override
-                public void onSuccess(Void result) {
-                    LOG.warn("Node {} succesfully deleted on all nodes", nodeid);
-                }
-
-                @Override
-                public void onFailure(Throwable t) {
-                    LOG.warn("Node delete failed. ", t);
-                }
-            });
-
-        }
-        LOG.warn("All tasks submitted");
-        Futures.allAsList(futures).get();
-        Futures.allAsList(deleteFutures).get();
-
-        TypedActor.get(ACTOR_SYSTEM).stop(master);
-        TypedActor.get(ACTOR_SYSTEM_SLAVE1).stop(slave1);
-        TypedActor.get(ACTOR_SYSTEM_SLAVE2).stop(slave2);
-
-    }
-
-    // TODO seems like stopping actors is not enough to create an actor with same name, split this into multiple classes?
-    @Ignore
-    @Test
-    public void testWithDummyOwnershipService() throws Exception {
-
-        final TestingEntityOwnershipService ownershipService = new TestingEntityOwnershipService();
-        // load from config
-        final TopologyManager master = createNoopRoleChangeNode(ACTOR_SYSTEM, TOPOLOGY_NETCONF, true, createRealTopoCallbackFactory(ownershipService));
-        final TopologyManager slave1 = createNoopRoleChangeNode(ACTOR_SYSTEM_SLAVE1, TOPOLOGY_NETCONF, false, createRealTopoCallbackFactory(ownershipService));
-        final TopologyManager slave2 = createNoopRoleChangeNode(ACTOR_SYSTEM_SLAVE2, TOPOLOGY_NETCONF, false, createRealTopoCallbackFactory(ownershipService));
-
-        await().atMost(10L, TimeUnit.SECONDS).until(new Callable<Boolean>() {
-            @Override
-            public Boolean call() throws Exception {
-                return master.hasAllPeersUp();
-            }
-        });
-
-        final List<ListenableFuture<Node>> futures = new ArrayList<>();
-        for (int i = 0; i <= 0; i++) {
-            final String nodeid = "testing-node" + i;
-            final Node testingNode = new NodeBuilder()
-                    .setNodeId(new NodeId(nodeid))
-                    .addAugmentation(NetconfNode.class,
-                            new NetconfNodeBuilder()
-                                    .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
-                                    .setPort(new PortNumber(10000 + i))
-                                    .build())
-                    .build();
-            final ListenableFuture<Node> nodeListenableFuture = master.onNodeCreated(new NodeId(nodeid), testingNode);
-            futures.add(nodeListenableFuture);
-            Futures.addCallback(nodeListenableFuture, new FutureCallback<Node>() {
-                @Override
-                public void onSuccess(Node result) {
-                    LOG.warn("Node {} created succesfully on all nodes", result.getNodeId().getValue());
-                }
-
-                @Override
-                public void onFailure(Throwable t) {
-                    LOG.warn("Node creation failed. ", t);
-                }
-            });
-        }
-
-        Futures.allAsList(futures).get();
-        ownershipService.distributeOwnership();
-
-        Thread.sleep(30000);
-        TypedActor.get(ACTOR_SYSTEM).stop(master);
-        TypedActor.get(ACTOR_SYSTEM_SLAVE1).stop(slave1);
-        TypedActor.get(ACTOR_SYSTEM_SLAVE2).stop(slave2);
-    }
-
-    private TopologyManager createNoopRoleChangeNode(final ActorSystem actorSystem, final String topologyId, final boolean isMaster,
-                                                     final TopologyManagerCallbackFactory topologyManagerCallbackFactory) {
-
-        final TypedActorExtension typedActorExtension = TypedActor.get(actorSystem);
-        return typedActorExtension.typedActorOf(new TypedProps<>(TopologyManager.class, new Creator<BaseTopologyManager>() {
-            @Override
-            public BaseTopologyManager create() throws Exception {
-                return new BaseTopologyManager(actorSystem,
-                        CODEC_REGISTRY,
-                        dataBroker,
-                        topologyId,
-                        topologyManagerCallbackFactory,
-                        new TestingSuccesfulStateAggregator(),
-                        new LoggingSalNodeWriter(),
-                        new NoopRoleChangeStrategy(),
-                        isMaster);
-            }
-        }), TOPOLOGY_NETCONF);
-    }
-
-    private TopologyManager createManagerWithOwnership(final ActorSystem actorSystem, final String topologyId, final boolean isMaster,
-                                                       final TopologyManagerCallbackFactory topologyManagerCallbackFactory, final RoleChangeStrategy roleChangeStrategy) {
-        final TypedActorExtension typedActorExtension = TypedActor.get(actorSystem);
-        return typedActorExtension.typedActorOf(new TypedProps<>(TopologyManager.class, new Creator<BaseTopologyManager>() {
-            @Override
-            public BaseTopologyManager create() throws Exception {
-                return new BaseTopologyManager(actorSystem,
-                        CODEC_REGISTRY,
-                        dataBroker,
-                        topologyId,
-                        topologyManagerCallbackFactory,
-                        new NetconfNodeOperationalDataAggregator(),
-                        new LoggingSalNodeWriter(),
-                        roleChangeStrategy,
-                        isMaster);
-            }
-        }), TOPOLOGY_NETCONF);
-    }
-
-    private TopologyManagerCallbackFactory createRealTopoTestingNodeCallbackFactory() {
-        final NodeManagerCallbackFactory nodeManagerCallbackFactory = new NodeManagerCallbackFactory() {
-            @Override
-            public NodeManagerCallback create(String nodeId, String topologyId, ActorSystem actorSystem) {
-                return new LoggingNodeManagerCallback();
-            }
-        };
-
-        return new TopologyManagerCallbackFactory() {
-            @Override
-            public TopologyManagerCallback create(ActorSystem actorSystem, String topologyId) {
-                return new ExampleTopologyManagerCallback(actorSystem, dataBroker, topologyId, nodeManagerCallbackFactory, new LoggingSalNodeWriter());
-            }
-        };
-    }
-
-    private TopologyManagerCallbackFactory createRealTopoCallbackFactory(final EntityOwnershipService entityOwnershipService) {
-        final NodeManagerCallbackFactory nodeManagerCallbackFactory = new NodeManagerCallbackFactory() {
-            @Override
-            public NodeManagerCallback create(String nodeId, String topologyId, ActorSystem actorSystem) {
-                return new ExampleNodeManagerCallback();
-            }
-        };
-
-        return new TopologyManagerCallbackFactory() {
-            @Override
-            public TopologyManagerCallback create(ActorSystem actorSystem, String topologyId) {
-                return new ExampleTopologyManagerCallback(actorSystem, dataBroker, topologyId, nodeManagerCallbackFactory);
-            }
-        };
-    }
-
-    private TopologyManagerCallbackFactory createTestingTopoCallbackFactory() {
-        return new TopologyManagerCallbackFactory() {
-            @Override
-            public TopologyManagerCallback create(ActorSystem actorSystem, String topologyId) {
-                return new TestingTopologyManagerCallback();
-            }
-        };
-    }
-
-    public static class LoggingNodeManagerCallback implements NodeManagerCallback {
-
-        @Nonnull
-        @Override
-        public Node getInitialState(@Nonnull NodeId nodeId, @Nonnull Node configNode) {
-            final NetconfNode netconfNode = configNode.getAugmentation(NetconfNode.class);
-            return new NodeBuilder()
-                    .setNodeId(nodeId)
-                    .addAugmentation(NetconfNode.class,
-                            new NetconfNodeBuilder()
-                                    .setHost(netconfNode.getHost())
-                                    .setPort(netconfNode.getPort())
-                                    .setConnectionStatus(ConnectionStatus.Connecting)
-                                    .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<String>()).build())
-                                    .setUnavailableCapabilities(new UnavailableCapabilitiesBuilder().setUnavailableCapability(new ArrayList<UnavailableCapability>()).build())
-                                    .setClusteredConnectionStatus(
-                                            new ClusteredConnectionStatusBuilder()
-                                                    .setNodeStatus(
-                                                            Lists.newArrayList(
-                                                                    new NodeStatusBuilder()
-                                                                            .setNode("testing-node")
-                                                                            .setStatus(Status.Unavailable)
-                                                                            .build()))
-                                                    .build())
-                                    .build())
-                    .build();
-        }
-
-        @Nonnull
-        @Override
-        public Node getFailedState(@Nonnull NodeId nodeId, @Nonnull Node configNode) {
-            final NetconfNode netconfNode = configNode.getAugmentation(NetconfNode.class);
-            return new NodeBuilder()
-                    .setNodeId(nodeId)
-                    .addAugmentation(NetconfNode.class,
-                            new NetconfNodeBuilder()
-                                    .setHost(netconfNode.getHost())
-                                    .setPort(netconfNode.getPort())
-                                    .setConnectionStatus(ConnectionStatus.UnableToConnect)
-                                    .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<String>()).build())
-                                    .setUnavailableCapabilities(new UnavailableCapabilitiesBuilder().setUnavailableCapability(new ArrayList<UnavailableCapability>()).build())
-                                    .setClusteredConnectionStatus(
-                                            new ClusteredConnectionStatusBuilder()
-                                                    .setNodeStatus(
-                                                            Collections.singletonList(
-                                                                    new NodeStatusBuilder()
-                                                                            .setNode("testing-node")
-                                                                            .setStatus(Status.Failed)
-                                                                            .build()))
-                                                    .build())
-                                    .build())
-                    .build();
-        }
-
-        @Nonnull
-        @Override
-        public ListenableFuture<Node> onNodeCreated(@Nonnull NodeId nodeId, @Nonnull Node configNode) {
-            LOG.debug("Creating node {} with config {}", nodeId, configNode);
-            final NetconfNode augmentation = configNode.getAugmentation(NetconfNode.class);
-            return Futures.immediateFuture(new NodeBuilder()
-                    .setNodeId(nodeId)
-                    .addAugmentation(NetconfNode.class,
-                            new NetconfNodeBuilder()
-                                    .setConnectionStatus(ConnectionStatus.Connected)
-                                    .setHost(augmentation.getHost())
-                                    .setPort(augmentation.getPort())
-                                    .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<String>()).build())
-                                    .setUnavailableCapabilities(new UnavailableCapabilitiesBuilder().setUnavailableCapability(new ArrayList<UnavailableCapability>()).build())
-                                    .setClusteredConnectionStatus(
-                                            new ClusteredConnectionStatusBuilder()
-                                                    .setNodeStatus(
-                                                            Collections.singletonList(
-                                                                    new NodeStatusBuilder()
-                                                                            .setNode("testing-node")
-                                                                            .setStatus(Status.Connected)
-                                                                            .build()))
-                                                    .build())
-                                    .build())
-                    .build());
-        }
-
-        @Nonnull
-        @Override
-        public ListenableFuture<Node> onNodeUpdated(@Nonnull NodeId nodeId, @Nonnull Node configNode) {
-            LOG.debug("Updating node {} with config {}", nodeId, configNode);
-            final NetconfNode augmentation = configNode.getAugmentation(NetconfNode.class);
-            return Futures.immediateFuture(new NodeBuilder()
-                    .setNodeId(nodeId)
-                    .addAugmentation(NetconfNode.class,
-                            new NetconfNodeBuilder()
-                                    .setConnectionStatus(ConnectionStatus.Connected)
-                                    .setHost(augmentation.getHost())
-                                    .setPort(augmentation.getPort())
-                                    .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<String>()).build())
-                                    .setUnavailableCapabilities(new UnavailableCapabilitiesBuilder().setUnavailableCapability(new ArrayList<UnavailableCapability>()).build())
-                                    .setClusteredConnectionStatus(
-                                            new ClusteredConnectionStatusBuilder()
-                                                    .setNodeStatus(
-                                                            Collections.singletonList(
-                                                                    new NodeStatusBuilder()
-                                                                            .setNode("testing-node")
-                                                                            .setStatus(Status.Connected)
-                                                                            .build()))
-                                                    .build())
-                                    .build())
-                    .build());
-        }
-
-        @Nonnull
-        @Override
-        public ListenableFuture<Void> onNodeDeleted(@Nonnull NodeId nodeId) {
-            LOG.debug("Deleting node {}", nodeId);
-            return Futures.immediateFuture(null);
-        }
-
-        @Nonnull
-        @Override
-        public ListenableFuture<Node> getCurrentStatusForNode(@Nonnull NodeId nodeId) {
-            return null;
-        }
-
-        @Override
-        public void onRoleChanged(RoleChangeDTO roleChangeDTO) {
-
-        }
-
-        @Override
-        public void onReceive(Object o, ActorRef actorRef) {
-
-        }
-
-        @Override
-        public void onDeviceConnected(SchemaContext remoteSchemaContext, NetconfSessionPreferences netconfSessionPreferences, DOMRpcService deviceRpc) {
-
-        }
-
-        @Override
-        public void onDeviceDisconnected() {
-
-        }
-
-        @Override
-        public void onDeviceFailed(Throwable throwable) {
-
-        }
-
-        @Override
-        public void onNotification(DOMNotification domNotification) {
-
-        }
-
-        @Override
-        public void close() {
-
-        }
-    }
-
-    public static class TestingTopologyManagerCallback implements TopologyManagerCallback {
-
-        public TestingTopologyManagerCallback() {
-
-        }
-
-        @Override
-        public ListenableFuture<Node> onNodeCreated(NodeId nodeId, Node node) {
-            LOG.warn("Actor system that called this: {}", TypedActor.context().system().settings().toString());
-            return Futures.immediateFuture(new NodeBuilder()
-                    .setNodeId(nodeId)
-                    .addAugmentation(NetconfNode.class,
-                            new NetconfNodeBuilder()
-                                    .setConnectionStatus(ConnectionStatus.Connected)
-                                    .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
-                                    .setPort(new PortNumber(2555))
-                                    .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<String>()).build())
-                                    .setUnavailableCapabilities(new UnavailableCapabilitiesBuilder().setUnavailableCapability(new ArrayList<UnavailableCapability>()).build())
-                                    .build())
-                    .build());
-        }
-
-        @Override
-        public ListenableFuture<Node> onNodeUpdated(NodeId nodeId, Node node) {
-            LOG.warn("Actor system that called this: {}", TypedActor.context().system().settings().toString());
-            LOG.debug("Update called on node {}, with config {}", nodeId.getValue(), node);
-            return Futures.immediateFuture(new NodeBuilder()
-                    .setNodeId(nodeId)
-                    .addAugmentation(NetconfNode.class,
-                            new NetconfNodeBuilder()
-                                    .setConnectionStatus(ConnectionStatus.Connected)
-                                    .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
-                                    .setPort(new PortNumber(65535))
-                                    .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<String>()).build())
-                                    .setUnavailableCapabilities(new UnavailableCapabilitiesBuilder().setUnavailableCapability(new ArrayList<UnavailableCapability>()).build())
-                                    .build())
-                    .build());
-        }
-
-        @Override
-        public ListenableFuture<Void> onNodeDeleted(NodeId nodeId) {
-            LOG.debug("Delete called on node {}", nodeId.getValue());
-            return Futures.immediateFuture(null);
-        }
-
-        @Nonnull
-        @Override
-        public ListenableFuture<Node> getCurrentStatusForNode(@Nonnull NodeId nodeId) {
-            return null;
-        }
-
-        @Override
-        public void onRoleChanged(RoleChangeDTO roleChangeDTO) {
-
-        }
-
-        @Override
-        public void onReceive(Object o, ActorRef actorRef) {
-
-        }
-
-        @Nonnull
-        @Override
-        public Node getInitialState(@Nonnull NodeId nodeId, @Nonnull Node configNode) {
-            return new NodeBuilder()
-                    .setNodeId(nodeId)
-                    .addAugmentation(NetconfNode.class,
-                            new NetconfNodeBuilder()
-                                    .setConnectionStatus(ConnectionStatus.Connecting)
-                                    .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
-                                    .setPort(new PortNumber(65535))
-                                    .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<String>()).build())
-                                    .setUnavailableCapabilities(new UnavailableCapabilitiesBuilder().setUnavailableCapability(new ArrayList<UnavailableCapability>()).build())
-                                    .build())
-                    .build();
-        }
-
-        @Nonnull
-        @Override
-        public Node getFailedState(@Nonnull NodeId nodeId, @Nonnull Node configNode) {
-            return new NodeBuilder()
-                    .setNodeId(nodeId)
-                    .addAugmentation(NetconfNode.class,
-                            new NetconfNodeBuilder()
-                                    .setConnectionStatus(ConnectionStatus.UnableToConnect)
-                                    .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
-                                    .setPort(new PortNumber(65535))
-                                    .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<String>()).build())
-                                    .setUnavailableCapabilities(new UnavailableCapabilitiesBuilder().setUnavailableCapability(new ArrayList<UnavailableCapability>()).build())
-                                    .build())
-                    .build();
-        }
-    }
-
-    public class TestingSuccesfulStateAggregator implements StateAggregator {
-
-        @Override
-        public ListenableFuture<Node> combineCreateAttempts(List<ListenableFuture<Node>> stateFutures) {
-            final SettableFuture<Node> future = SettableFuture.create();
-            final ListenableFuture<List<Node>> allAsList = Futures.allAsList(stateFutures);
-            Futures.addCallback(allAsList, new FutureCallback<List<Node>>() {
-                @Override
-                public void onSuccess(List<Node> result) {
-                    for (int i = 0; i < result.size() - 1; i++) {
-                        if (!result.get(i).equals(result.get(i + 1))) {
-                            LOG.warn("Node 1 {}: {}", result.get(i).getClass(), result.get(i));
-                            LOG.warn("Node 2 {}: {}", result.get(i + 1).getClass(), result.get(i + 1));
-                            future.setException(new IllegalStateException("Create futures have different result"));
-                            LOG.warn("Future1 : {}  Future2 : {}", result.get(i), result.get(i+1));
-                        }
-                    }
-                    future.set(result.get(0));
-                }
-
-                @Override
-                public void onFailure(Throwable t) {
-                    LOG.error("One of the combined create attempts failed {}", t);
-                    future.setException(t);
-                }
-            }, TypedActor.context().dispatcher());
-
-            return future;
-        }
-
-        @Override
-        public ListenableFuture<Node> combineUpdateAttempts(List<ListenableFuture<Node>> stateFutures) {
-            final SettableFuture<Node> future = SettableFuture.create();
-            final ListenableFuture<List<Node>> allAsList = Futures.allAsList(stateFutures);
-            Futures.addCallback(allAsList, new FutureCallback<List<Node>>() {
-                @Override
-                public void onSuccess(List<Node> result) {
-                    for (int i = 0; i < result.size() - 1; i++) {
-                        if (!result.get(i).equals(result.get(i + 1))) {
-                            future.setException(new IllegalStateException("Update futures have different result"));
-                        }
-                    }
-                    future.set(result.get(0));
-                }
-
-                @Override
-                public void onFailure(Throwable t) {
-                    LOG.error("One of the combined update attempts failed {}", t);
-                    future.setException(t);
-                }
-            });
-            return future;
-        }
-
-        @Override
-        public ListenableFuture<Void> combineDeleteAttempts(List<ListenableFuture<Void>> stateFutures) {
-            final SettableFuture<Void> future = SettableFuture.create();
-            final ListenableFuture<List<Void>> allAsList = Futures.allAsList(stateFutures);
-            Futures.addCallback(allAsList, new FutureCallback<List<Void>>() {
-                @Override
-                public void onSuccess(List<Void> result) {
-                    future.set(null);
-                }
-
-                @Override
-                public void onFailure(Throwable t) {
-                    LOG.error("One of the combined delete attempts failed {}", t);
-                    future.setException(t);
-                }
-            });
-            return future;
-        }
-    }
-}
diff --git a/netconf/netconf-topology/src/test/java/org/opendaylight/netconf/topology/TestingEntityOwnershipService.java b/netconf/netconf-topology/src/test/java/org/opendaylight/netconf/topology/TestingEntityOwnershipService.java
deleted file mode 100644 (file)
index 4b0bc31..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.netconf.topology;
-
-import com.google.common.base.Optional;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import javax.annotation.Nonnull;
-import org.opendaylight.controller.md.sal.common.api.clustering.CandidateAlreadyRegisteredException;
-import org.opendaylight.controller.md.sal.common.api.clustering.Entity;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipCandidateRegistration;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipChange;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListener;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListenerRegistration;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipState;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class TestingEntityOwnershipService implements EntityOwnershipService{
-
-    private static final Logger LOG = LoggerFactory.getLogger(TestingEntityOwnershipService.class);
-
-    private final List<EntityOwnershipListener> listeners = new ArrayList<>();
-    private final ExecutorService executorService = Executors.newFixedThreadPool(1);
-
-    private Entity entity;
-    private boolean masterSet = false;
-
-    @Override
-    public EntityOwnershipCandidateRegistration registerCandidate(final Entity entity) throws CandidateAlreadyRegisteredException {
-        LOG.warn("Registering Candidate");
-        this.entity = entity;
-        return new EntityOwnershipCandidateRegistration() {
-            @Override
-            public void close() {
-                LOG.debug("Closing candidate registration");
-            }
-
-            @Override
-            public Entity getInstance() {
-                return entity;
-            }
-        };
-    }
-
-    @Override
-    public EntityOwnershipListenerRegistration registerListener(final String entityType, final EntityOwnershipListener listener) {
-        listeners.add(listener);
-        if (listeners.size() == 3) {
-            distributeOwnership();
-        }
-        return new EntityOwnershipListenerRegistration() {
-            @Nonnull
-            @Override
-            public String getEntityType() {
-                return entityType;
-            }
-
-            @Override
-            public void close() {
-                listeners.remove(listener);
-            }
-
-            @Override
-            public EntityOwnershipListener getInstance() {
-                return listener;
-            }
-        };
-    }
-
-    @Override
-    public Optional<EntityOwnershipState> getOwnershipState(final Entity forEntity) {
-        return null;
-    }
-
-    @Override
-    public boolean isCandidateRegistered(@Nonnull Entity entity) {
-        return true;
-    }
-
-    public void distributeOwnership() {
-        LOG.debug("Distributing ownership");
-        executorService.submit(new Runnable() {
-            @Override
-            public void run() {
-                masterSet = false;
-                LOG.debug("Distributing ownership for {} listeners", listeners.size());
-                for (final EntityOwnershipListener listener : listeners) {
-                    if (!masterSet) {
-                        listener.ownershipChanged(new EntityOwnershipChange(entity, false, true, true));
-                        masterSet = true;
-                    } else {
-                        listener.ownershipChanged(new EntityOwnershipChange(entity, false, false, true));
-                    }
-                }
-
-            }
-        });
-    }
-}
diff --git a/netconf/netconf-topology/src/test/java/org/opendaylight/netconf/topology/TestingTopologyDispatcher.java b/netconf/netconf-topology/src/test/java/org/opendaylight/netconf/topology/TestingTopologyDispatcher.java
deleted file mode 100644 (file)
index 28a1f97..0000000
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.netconf.topology;
-
-import akka.actor.ActorContext;
-import akka.actor.ActorRef;
-import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.SettableFuture;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.netconf.sal.connect.api.RemoteDeviceHandler;
-import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfDeviceCapabilities;
-import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences;
-import org.opendaylight.netconf.topology.pipeline.TopologyMountPointFacade.ConnectionStatusListenerRegistration;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class TestingTopologyDispatcher implements NetconfTopology{
-
-    private static final Logger LOG = LoggerFactory.getLogger(TestingTopologyDispatcher.class);
-
-    private final String topologyId;
-
-    private final ExecutorService executorService = Executors.newSingleThreadExecutor();
-    private final Set<NodeId> connected = new HashSet<>();
-    private final Map<NodeId, RemoteDeviceHandler<NetconfSessionPreferences>> listeners = new HashMap<>();
-
-
-    public TestingTopologyDispatcher(final String topologyId) {
-
-        this.topologyId = topologyId;
-    }
-
-    @Override
-    public String getTopologyId() {
-        return topologyId;
-    }
-
-    @Override
-    public DataBroker getDataBroker() {
-        return null;
-    }
-
-    // log the current connection attempt and return a successful future asynchronously
-    @Override
-    public ListenableFuture<NetconfDeviceCapabilities> connectNode(final NodeId nodeId, final Node configNode) {
-        final NetconfNode augmentation = configNode.getAugmentation(NetconfNode.class);
-        LOG.debug("Connecting node {}, with config: {} ", nodeId.getValue(),
-                augmentation.getHost().getIpAddress().toString() + ":" + augmentation.getPort());
-        connected.add(nodeId);
-        final SettableFuture<NetconfDeviceCapabilities> future = SettableFuture.create();
-        executorService.submit(new Runnable() {
-            @Override
-            public void run() {
-                try {
-                    Thread.sleep(4000);
-                    executorService.submit(new Runnable() {
-                        @Override
-                        public void run() {
-                            future.set(new NetconfDeviceCapabilities());
-                        }
-                    });
-                } catch (InterruptedException e) {
-                    LOG.error("Cannot sleep thread", e);
-                }
-            }
-        });
-        return future;
-    }
-
-    @Override
-    public ListenableFuture<Void> disconnectNode(final NodeId nodeId) {
-        Preconditions.checkState(connected.contains(nodeId), "Node is not connected yet");
-        LOG.debug("Disconnecting node {}", nodeId.getValue());
-        final SettableFuture<Void> future = SettableFuture.create();
-        executorService.submit(new Runnable() {
-            @Override
-            public void run() {
-                try {
-                    Thread.sleep(4000);
-                    executorService.submit(new Runnable() {
-                        @Override
-                        public void run() {
-                            connected.remove(nodeId);
-                            future.set(null);
-                        }
-                    });
-                } catch (InterruptedException e) {
-                    LOG.error("Cannot sleep thread", e);
-                }
-
-            }
-        });
-        return future;
-    }
-
-    @Override
-    public void registerMountPoint(ActorContext context, NodeId nodeId) {
-        LOG.debug("Registering mount point for node {}", nodeId.getValue());
-    }
-
-    @Override
-    public void registerMountPoint(ActorContext context, NodeId nodeId, ActorRef masterRef) {
-        LOG.debug("Registering mount point for node {}", nodeId.getValue());
-    }
-
-    @Override
-    public void unregisterMountPoint(NodeId nodeId) {
-        LOG.debug("Unregistering mount point for node {}", nodeId.getValue());
-    }
-
-    @Override
-    public ConnectionStatusListenerRegistration registerConnectionStatusListener(final NodeId node, final RemoteDeviceHandler<NetconfSessionPreferences> listener) {
-        Preconditions.checkState(connected.contains(node), "Node is not connected yet");
-
-        LOG.debug("Registering a connection status listener for node {}", node.getValue());
-        listeners.put(node, listener);
-        executorService.submit(new Runnable() {
-            @Override
-            public void run() {
-                try {
-                    Thread.sleep(10000);
-
-                    boolean up = false;
-                    for (int i = 0; i < 20; i++) {
-                        if (up) {
-                            LOG.debug("Device has connected {}", node.getValue());
-                            listener.onDeviceConnected(null, null, null);
-                            up = false;
-                        } else {
-                            LOG.debug("Device has diconnected {}", node.getValue());
-                            listener.onDeviceDisconnected();
-                            up = true;
-                        }
-                        try {
-                            Thread.sleep(5000);
-                        } catch (InterruptedException e) {
-                            LOG.error("Cannot sleep thread", e);
-                        }
-                    }
-                } catch (InterruptedException e) {
-                    e.printStackTrace();
-                }
-
-            }
-        });
-
-        return null;
-    }
-}
diff --git a/netconf/netconf-topology/src/test/java/org/opendaylight/netconf/topology/impl/NetconfNodeOperationalDataAggregatorTest.java b/netconf/netconf-topology/src/test/java/org/opendaylight/netconf/topology/impl/NetconfNodeOperationalDataAggregatorTest.java
deleted file mode 100644 (file)
index d0976b4..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.netconf.topology.impl;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import com.google.common.collect.Lists;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import java.util.List;
-import java.util.concurrent.ExecutionException;
-import org.junit.Before;
-import org.junit.Test;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.AvailableCapabilitiesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.ClusteredConnectionStatusBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.clustered.connection.status.NodeStatus;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.clustered.connection.status.NodeStatusBuilder;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
-
-public class NetconfNodeOperationalDataAggregatorTest {
-
-    private List<ListenableFuture<Node>> stateFutures;
-
-    private NetconfNodeOperationalDataAggregator aggregator;
-
-    @Before
-    public void setUp() {
-        aggregator = new NetconfNodeOperationalDataAggregator();
-        stateFutures = Lists.newArrayList();
-    }
-
-    @Test
-    public void testCombineCreateAttempts() throws ExecutionException, InterruptedException {
-        NetconfNode testingNode = new NetconfNodeBuilder().setAvailableCapabilities(
-                new AvailableCapabilitiesBuilder().setAvailableCapability(Lists.<String>newArrayList()).build())
-                .setClusteredConnectionStatus(new ClusteredConnectionStatusBuilder().setNodeStatus(Lists.newArrayList(
-                        new NodeStatusBuilder().setStatus(NodeStatus.Status.Connected).build())).build())
-                .setConnectionStatus(NetconfNodeConnectionStatus.ConnectionStatus.Connected).build();
-        stateFutures.add(Futures.immediateFuture(new NodeBuilder().addAugmentation(NetconfNode.class, testingNode).build()));
-
-        ListenableFuture<Node> aggregatedCreateFuture = aggregator.combineCreateAttempts(stateFutures);
-        assertTrue(aggregatedCreateFuture.isDone());
-
-        NetconfNode aggregatedNode = aggregatedCreateFuture.get().getAugmentation(NetconfNode.class);
-        assertEquals(aggregatedNode.getClusteredConnectionStatus().getNodeStatus().get(0).getStatus(),
-                NodeStatus.Status.Connected);
-    }
-
-    @Test
-    public void testSuccessfulCombineUpdateAttempts() throws ExecutionException, InterruptedException {
-        NetconfNode testingNode = new NetconfNodeBuilder().setAvailableCapabilities(
-                new AvailableCapabilitiesBuilder().setAvailableCapability(Lists.<String>newArrayList()).build())
-                .setClusteredConnectionStatus(new ClusteredConnectionStatusBuilder().setNodeStatus(Lists.newArrayList(
-                        new NodeStatusBuilder().setStatus(NodeStatus.Status.Connected).build())).build())
-                .setConnectionStatus(NetconfNodeConnectionStatus.ConnectionStatus.Connected).build();
-        stateFutures.add(Futures.immediateFuture(new NodeBuilder().addAugmentation(NetconfNode.class, testingNode).build()));
-
-        ListenableFuture<Node> aggregatedUpdateFuture = aggregator.combineUpdateAttempts(stateFutures);
-        assertTrue(aggregatedUpdateFuture.isDone());
-
-        NetconfNode aggregatedNode = aggregatedUpdateFuture.get().getAugmentation(NetconfNode.class);
-        assertEquals(aggregatedNode.getClusteredConnectionStatus().getNodeStatus().get(0).getStatus(),
-                NodeStatus.Status.Connected);
-    }
-
-    @Test
-    public void testSuccessfulCombineDeleteAttempts() throws ExecutionException, InterruptedException {
-        List deleteStateFutures = Lists.newArrayList(Futures.immediateFuture(null), Futures.immediateFuture(null));
-
-        ListenableFuture<Void> deleteFuture = aggregator.combineDeleteAttempts(deleteStateFutures);
-        assertTrue(deleteFuture.isDone());
-        assertEquals(deleteFuture.get(), null);
-    }
-
-    @Test
-    public void testFailedCombineDeleteAttempts() {
-        Exception cause = new Exception("Fail");
-        List deleteStateFutures = Lists.newArrayList(Futures.immediateFuture(null), Futures.immediateFuture(null),
-                Futures.immediateFailedFuture(cause));
-
-        ListenableFuture<Void> deleteFuture = aggregator.combineDeleteAttempts(deleteStateFutures);
-        assertTrue(deleteFuture.isDone());
-
-        try {
-            deleteFuture.get();
-            fail("Exception expected");
-        } catch(Exception e) {
-            assertSame(e.getCause(), cause);
-        }
-    }
-}
index 1db1c3a7e836bed895bc9fe03f8d2daa6d7a5815..2a2f2f4125c6d1fd1e3125972e5de531c199eb80 100644 (file)
@@ -16,7 +16,6 @@ import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-import akka.actor.ActorContext;
 import com.google.common.collect.Sets;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
@@ -42,11 +41,8 @@ import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
 import org.opendaylight.controller.sal.core.api.Broker;
 import org.opendaylight.netconf.client.NetconfClientDispatcher;
 import org.opendaylight.netconf.client.conf.NetconfReconnectingClientConfiguration;
-import org.opendaylight.netconf.sal.connect.api.RemoteDeviceHandler;
 import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfDeviceCapabilities;
-import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences;
 import org.opendaylight.netconf.topology.SchemaRepositoryProvider;
-import org.opendaylight.netconf.topology.util.TopologyUtil;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Host;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
@@ -113,23 +109,6 @@ public class NetconfTopologyImplTest {
         spyTopology = spy(topology);
     }
 
-    @Test(expected = UnsupportedOperationException.class)
-    public void testRegisterMountPointNotSupported() {
-        ActorContext context = mock(ActorContext.class);
-        topology.registerMountPoint(context, NODE_ID);
-    }
-
-    @Test(expected = UnsupportedOperationException.class)
-    public void testUnregisterMountPointNotSupported() {
-        topology.unregisterMountPoint(NODE_ID);
-    }
-
-    @Test(expected = UnsupportedOperationException.class)
-    public void testRegisterConnectionStatusListener() {
-        RemoteDeviceHandler<NetconfSessionPreferences> listener = mock(RemoteDeviceHandler.class);
-        topology.registerConnectionStatusListener(NODE_ID, listener);
-    }
-
     @Test
     public void testOnSessionInitiated() {
         BindingAwareBroker.ProviderContext session = mock(BindingAwareBroker.ProviderContext.class);
diff --git a/netconf/netconf-topology/src/test/java/org/opendaylight/netconf/topology/impl/TopologyNodeWriterTest.java b/netconf/netconf-topology/src/test/java/org/opendaylight/netconf/topology/impl/TopologyNodeWriterTest.java
deleted file mode 100644 (file)
index 4e11457..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.netconf.topology.impl;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.MockitoAnnotations.initMocks;
-
-import com.google.common.collect.Lists;
-import com.google.common.util.concurrent.Futures;
-import java.util.ArrayList;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Host;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus.ConnectionStatus;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.AvailableCapabilitiesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.ClusteredConnectionStatusBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.UnavailableCapabilitiesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.clustered.connection.status.NodeStatus.Status;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.clustered.connection.status.NodeStatusBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.unavailable.capabilities.UnavailableCapability;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopologyBuilder;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyBuilder;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
-
-public class TopologyNodeWriterTest {
-
-    private static final NodeId NODE_ID = new NodeId("testing-node");
-    private static final String TOPOLOGY_ID = "testing-topology";
-
-    private static final InstanceIdentifier<NetworkTopology> NETWORK_TOPOLOGY_IID = InstanceIdentifier.builder(NetworkTopology.class).build();
-    private static final KeyedInstanceIdentifier<Topology, TopologyKey> TOPOLOGY_LIST_IID;
-
-    private static final KeyedInstanceIdentifier<Node, NodeKey> OPERATIONAL_NODE_IID;
-
-    static {
-        TOPOLOGY_LIST_IID = NETWORK_TOPOLOGY_IID.child(Topology.class, new TopologyKey(new TopologyId(TOPOLOGY_ID)));
-        OPERATIONAL_NODE_IID = TOPOLOGY_LIST_IID.child(Node.class, new NodeKey(new NodeId(NODE_ID)));
-    }
-
-    @Mock
-    private DataBroker dataBroker;
-
-    @Mock
-    private BindingTransactionChain txChain;
-
-    @Mock
-    private WriteTransaction wtx;
-
-    private Node operationalNode;
-
-    private TopologyNodeWriter writer;
-
-    @Before
-    public void setUp() throws Exception {
-        initMocks(this);
-        doReturn(txChain).when(dataBroker).createTransactionChain(any(TransactionChainListener.class));
-        doReturn(wtx).when(txChain).newWriteOnlyTransaction();
-        doNothing().when(wtx).put(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(DataObject.class));
-        doReturn(Futures.immediateCheckedFuture(null)).when(wtx).submit();
-        writer = new TopologyNodeWriter(TOPOLOGY_ID, dataBroker);
-
-        operationalNode = new NodeBuilder()
-                .setNodeId(NODE_ID)
-                .addAugmentation(NetconfNode.class,
-                        new NetconfNodeBuilder()
-                                .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
-                                .setPort(new PortNumber(17830))
-                                .setConnectionStatus(ConnectionStatus.Connected)
-                                .setAvailableCapabilities(new AvailableCapabilitiesBuilder().setAvailableCapability(new ArrayList<String>()).build())
-                                .setUnavailableCapabilities(new UnavailableCapabilitiesBuilder().setUnavailableCapability(new ArrayList<UnavailableCapability>()).build())
-                                .setClusteredConnectionStatus(
-                                        new ClusteredConnectionStatusBuilder()
-                                                .setNodeStatus(
-                                                        Lists.newArrayList(
-                                                                new NodeStatusBuilder()
-                                                                        .setNode("10.10.10.10")
-                                                                        .setStatus(Status.Connected)
-                                                                        .build()))
-                                                .build())
-                                .build())
-                .build();
-
-    }
-
-    @Test
-    public void testInit() throws Exception {
-        writer.init(NODE_ID, operationalNode);
-        // once in constructor + once in init
-        verify(txChain, times(2)).newWriteOnlyTransaction();
-        verify(wtx, times(2)).merge(eq(LogicalDatastoreType.OPERATIONAL), eq(NETWORK_TOPOLOGY_IID), eq(new NetworkTopologyBuilder().build()));
-        verify(wtx, times(2)).merge(eq(LogicalDatastoreType.OPERATIONAL), eq(TOPOLOGY_LIST_IID), eq(new TopologyBuilder().setTopologyId(new TopologyId(TOPOLOGY_ID)).build()));
-        // actual write
-        verify(wtx, times(1)).put(eq(LogicalDatastoreType.OPERATIONAL), eq(OPERATIONAL_NODE_IID), eq(operationalNode));
-
-        // once in constructor + once in init()
-        verify(wtx, times(2)).submit();
-    }
-
-    @Test
-    public void testUpdate() throws Exception {
-        writer.update(NODE_ID, operationalNode);
-
-        verify(txChain, times(2)).newWriteOnlyTransaction();
-        verify(wtx, times(1)).merge(eq(LogicalDatastoreType.OPERATIONAL), eq(NETWORK_TOPOLOGY_IID), eq(new NetworkTopologyBuilder().build()));
-        verify(wtx, times(1)).merge(eq(LogicalDatastoreType.OPERATIONAL), eq(TOPOLOGY_LIST_IID), eq(new TopologyBuilder().setTopologyId(new TopologyId(TOPOLOGY_ID)).build()));
-        // actual write
-        verify(wtx, times(1)).put(eq(LogicalDatastoreType.OPERATIONAL), eq(OPERATIONAL_NODE_IID), eq(operationalNode));
-        verify(wtx, times(2)).submit();
-
-    }
-
-    @Test
-    public void testDelete() throws Exception {
-        writer.delete(NODE_ID);
-        verify(txChain, times(2)).newWriteOnlyTransaction();
-        verify(wtx, times(1)).merge(eq(LogicalDatastoreType.OPERATIONAL), eq(NETWORK_TOPOLOGY_IID), eq(new NetworkTopologyBuilder().build()));
-        verify(wtx, times(1)).merge(eq(LogicalDatastoreType.OPERATIONAL), eq(TOPOLOGY_LIST_IID), eq(new TopologyBuilder().setTopologyId(new TopologyId(TOPOLOGY_ID)).build()));
-        verify(wtx, times(1)).delete(eq(LogicalDatastoreType.OPERATIONAL), eq(OPERATIONAL_NODE_IID));
-        verify(wtx, times(2)).submit();
-    }
-}
diff --git a/netconf/netconf-topology/src/test/java/org/opendaylight/netconf/topology/pipeline/ClusteredNetconfDeviceCommunicatorTest.java b/netconf/netconf-topology/src/test/java/org/opendaylight/netconf/topology/pipeline/ClusteredNetconfDeviceCommunicatorTest.java
deleted file mode 100644 (file)
index aa6b69d..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.netconf.topology.pipeline;
-
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-import java.net.InetSocketAddress;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListenerRegistration;
-import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
-import org.opendaylight.netconf.api.NetconfTerminationReason;
-import org.opendaylight.netconf.client.NetconfClientSession;
-import org.opendaylight.netconf.client.NetconfClientSessionListener;
-import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
-
-public class ClusteredNetconfDeviceCommunicatorTest {
-
-    private static final RemoteDeviceId REMOTE_DEVICE_ID = new RemoteDeviceId("testing-device", new InetSocketAddress(9999));
-
-    @Mock
-    private ClusteredNetconfDevice remoteDevice;
-
-    @Mock
-    private EntityOwnershipService ownershipService;
-
-    @Mock
-    private NetconfClientSession session;
-
-    @Mock
-    private NetconfClientSessionListener listener1;
-
-    @Mock
-    private NetconfClientSessionListener listener2;
-
-    @Mock
-    private EntityOwnershipListenerRegistration ownershipListenerRegistration;
-
-    private ClusteredNetconfDeviceCommunicator communicator;
-
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-
-        doReturn(ownershipListenerRegistration).when(ownershipService).registerListener(
-                "netconf-node/" + REMOTE_DEVICE_ID.getName(), remoteDevice);
-
-        communicator = new ClusteredNetconfDeviceCommunicator(REMOTE_DEVICE_ID, remoteDevice, ownershipService, 10);
-        communicator.registerNetconfClientSessionListener(listener1);
-        communicator.registerNetconfClientSessionListener(listener2);
-    }
-
-    @Test
-    public void testOnSessionDown() {
-        communicator.onSessionUp(session);
-
-        Exception exception = mock(Exception.class);
-        communicator.onSessionDown(session, exception);
-
-        verify(ownershipListenerRegistration).close();
-
-        verify(listener1).onSessionDown(eq(session), eq(exception));
-        verify(listener2).onSessionDown(eq(session), eq(exception));
-    }
-
-    @Test
-    public void testOnSessionUp() {
-        communicator.onSessionUp(session);
-
-        verify(ownershipService).registerListener("netconf-node/" + REMOTE_DEVICE_ID.getName(), remoteDevice);
-
-        verify(listener1).onSessionUp(eq(session));
-        verify(listener2).onSessionUp(eq(session));
-    }
-
-    @Test
-    public void testOnSessionTerminated() {
-        communicator.onSessionUp(session);
-
-        NetconfTerminationReason reason = mock(NetconfTerminationReason.class);
-        communicator.onSessionTerminated(session, reason);
-
-        verify(ownershipListenerRegistration).close();
-
-        verify(listener1).onSessionTerminated(eq(session), eq(reason));
-        verify(listener2).onSessionTerminated(eq(session), eq(reason));
-    }
-}
\ No newline at end of file
diff --git a/netconf/netconf-topology/src/test/java/org/opendaylight/netconf/topology/pipeline/NetconfDeviceSlaveDataBrokerTest.java b/netconf/netconf-topology/src/test/java/org/opendaylight/netconf/topology/pipeline/NetconfDeviceSlaveDataBrokerTest.java
deleted file mode 100644 (file)
index 417978d..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.netconf.topology.pipeline;
-
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.mock;
-
-import akka.actor.ActorSystem;
-import java.net.InetSocketAddress;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataChangeListener;
-import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-
-public class NetconfDeviceSlaveDataBrokerTest {
-
-    private static final RemoteDeviceId REMOTE_DEVICE_ID = new RemoteDeviceId("testing-device", new InetSocketAddress(9999));
-
-    @Mock
-    private ProxyNetconfDeviceDataBroker mockedDataBroker;
-
-    @Mock
-    private ActorSystem mockedActorSystem;
-
-    private NetconfDeviceSlaveDataBroker slaveDataBroker;
-
-    @Before
-    public void setUp() {
-        slaveDataBroker = new NetconfDeviceSlaveDataBroker(mockedActorSystem, REMOTE_DEVICE_ID, mockedDataBroker);
-    }
-
-    @Test(expected = UnsupportedOperationException.class)
-    public void testRegisterDataChangeListener() {
-        slaveDataBroker.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.EMPTY,
-                mock(DOMDataChangeListener.class), AsyncDataBroker.DataChangeScope.SUBTREE);
-    }
-
-    @Test(expected = UnsupportedOperationException.class)
-    public void testCreateTransactionChain() {
-        slaveDataBroker.createTransactionChain(mock(TransactionChainListener.class));
-    }
-
-    @Test
-    public void testGetSupportedExtensions() {
-        assertTrue(slaveDataBroker.getSupportedExtensions().isEmpty());
-    }
-}
\ No newline at end of file
diff --git a/netconf/netconf-topology/src/test/java/org/opendaylight/netconf/topology/pipeline/TopologyMountPointFacadeTest.java b/netconf/netconf-topology/src/test/java/org/opendaylight/netconf/topology/pipeline/TopologyMountPointFacadeTest.java
deleted file mode 100644 (file)
index 68342a5..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.netconf.topology.pipeline;
-
-import java.net.InetSocketAddress;
-import java.util.Collections;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
-import org.opendaylight.controller.sal.core.api.Broker;
-import org.opendaylight.netconf.sal.connect.api.RemoteDeviceHandler;
-import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences;
-import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-
-public class TopologyMountPointFacadeTest {
-
-    private static final RemoteDeviceId REMOTE_DEVICE_ID = new RemoteDeviceId("testing-device", new InetSocketAddress(9999));
-    private static final String TOPOLOGY_ID = "testing-topology";
-
-    @Mock
-    Broker domBroker;
-
-    @Mock
-    BindingAwareBroker bindingBroker;
-
-    @Mock
-    RemoteDeviceHandler<NetconfSessionPreferences> connectionStatusListener1;
-
-    @Mock
-    RemoteDeviceHandler<NetconfSessionPreferences> connectionStatusListener2;
-
-
-    private TopologyMountPointFacade mountPointFacade;
-
-    @Before
-    public void setUp() {
-
-        MockitoAnnotations.initMocks(this);
-
-        mountPointFacade = new TopologyMountPointFacade(TOPOLOGY_ID, REMOTE_DEVICE_ID, domBroker, bindingBroker);
-
-        mountPointFacade.registerConnectionStatusListener(connectionStatusListener1);
-        mountPointFacade.registerConnectionStatusListener(connectionStatusListener2);
-
-    }
-
-    @Test
-    public void testOnDeviceConnected() {
-        SchemaContext mockedContext = Mockito.mock(SchemaContext.class);
-        NetconfSessionPreferences mockedPreferences = NetconfSessionPreferences.fromStrings(Collections.<String>emptyList());
-        DOMRpcService mockedRpcService = Mockito.mock(DOMRpcService.class);
-        mountPointFacade.onDeviceConnected(mockedContext, mockedPreferences, mockedRpcService);
-
-        Mockito.verify(connectionStatusListener1).onDeviceConnected(mockedContext, mockedPreferences, mockedRpcService);
-        Mockito.verify(connectionStatusListener2).onDeviceConnected(mockedContext, mockedPreferences, mockedRpcService);
-    }
-
-    @Test
-    public void testOnDeviceDisconnected() {
-        mountPointFacade.onDeviceDisconnected();
-
-        Mockito.verify(connectionStatusListener1).onDeviceDisconnected();
-        Mockito.verify(connectionStatusListener2).onDeviceDisconnected();
-    }
-
-    @Test
-    public void testOnDeviceFailed() {
-        Throwable mockedException = Mockito.mock(Throwable.class);
-        mountPointFacade.onDeviceFailed(mockedException);
-
-        Mockito.verify(connectionStatusListener1).onDeviceFailed(mockedException);
-        Mockito.verify(connectionStatusListener2).onDeviceFailed(mockedException);
-    }
-
-}
diff --git a/netconf/netconf-topology/src/test/java/org/opendaylight/netconf/topology/pipeline/tx/ProxyReadOnlyTransactionTest.java b/netconf/netconf-topology/src/test/java/org/opendaylight/netconf/topology/pipeline/tx/ProxyReadOnlyTransactionTest.java
deleted file mode 100644 (file)
index afde0a0..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.netconf.topology.pipeline.tx;
-
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import akka.actor.ActorSystem;
-import akka.dispatch.ExecutionContexts;
-import akka.dispatch.Futures;
-import com.google.common.base.Optional;
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.MoreExecutors;
-import java.net.InetSocketAddress;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
-import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
-import org.opendaylight.netconf.topology.pipeline.ProxyNetconfDeviceDataBroker;
-import org.opendaylight.netconf.topology.util.messages.NormalizedNodeMessage;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-
-public class ProxyReadOnlyTransactionTest {
-    private static final RemoteDeviceId REMOTE_DEVICE_ID = new RemoteDeviceId("testing-device", new InetSocketAddress(9999));
-    private static final YangInstanceIdentifier path = YangInstanceIdentifier.create();
-
-    @Mock
-    private ProxyNetconfDeviceDataBroker mockedProxyDataBroker;
-
-    @Mock
-    private ActorSystem mockedActorSystem;
-
-    @Mock
-    private NormalizedNodeMessage mockedNodeMessage;
-
-    @Mock
-    private NormalizedNode mockedNode;
-
-    private ProxyReadOnlyTransaction proxyReadOnlyTx;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-
-        when(mockedActorSystem.dispatcher()).thenReturn(ExecutionContexts.fromExecutorService(MoreExecutors.newDirectExecutorService()));
-        when(mockedNodeMessage.getNode()).thenReturn(mockedNode);
-
-        proxyReadOnlyTx = new ProxyReadOnlyTransaction(mockedActorSystem, REMOTE_DEVICE_ID, mockedProxyDataBroker);
-    }
-
-    @Test
-    public void testSuccessfulRead() throws ReadFailedException {
-        when(mockedProxyDataBroker.read(any(LogicalDatastoreType.class), any(YangInstanceIdentifier.class)))
-                .thenReturn(Futures.successful(Optional.of(mockedNodeMessage)));
-        CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> readResultFuture =  proxyReadOnlyTx.read(LogicalDatastoreType.CONFIGURATION, path);
-        verify(mockedProxyDataBroker).read(eq(LogicalDatastoreType.CONFIGURATION), eq(path));
-        assertTrue(readResultFuture.isDone());
-        assertEquals(readResultFuture.checkedGet().get(), mockedNode);
-    }
-
-    @Test
-    public void testFailedRead() {
-        when(mockedProxyDataBroker.read(any(LogicalDatastoreType.class), any(YangInstanceIdentifier.class)))
-                .thenReturn(Futures.<Optional<NormalizedNodeMessage>>failed(new ReadFailedException("Test read failed!")));
-        CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> readResultFuture =  proxyReadOnlyTx.read(LogicalDatastoreType.CONFIGURATION, path);
-        verify(mockedProxyDataBroker).read(eq(LogicalDatastoreType.CONFIGURATION), eq(path));
-        assertTrue(readResultFuture.isDone());
-        try {
-            readResultFuture.checkedGet();
-            fail("Exception expected");
-        } catch(Exception e) {
-            assertTrue(e instanceof ReadFailedException);
-        }
-    }
-
-    @Test
-    public void testDataOnPathDoesNotExistPathRead() throws ReadFailedException {
-        when(mockedProxyDataBroker.read(any(LogicalDatastoreType.class), any(YangInstanceIdentifier.class)))
-                .thenReturn(Futures.successful(Optional.absent()));
-        CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> readResultFuture =  proxyReadOnlyTx.read(LogicalDatastoreType.CONFIGURATION, path);
-        verify(mockedProxyDataBroker).read(eq(LogicalDatastoreType.CONFIGURATION), eq(path));
-        assertTrue(readResultFuture.isDone());
-        assertTrue(!readResultFuture.checkedGet().isPresent());
-    }
-
-    @Test
-    public void testFailedExists() {
-        when(mockedProxyDataBroker.exists(any(LogicalDatastoreType.class), any(YangInstanceIdentifier.class)))
-                .thenReturn(Futures.<Boolean>failed(new ReadFailedException("Test read failed!")));
-        CheckedFuture existsFuture = proxyReadOnlyTx.exists(LogicalDatastoreType.OPERATIONAL, path);
-        verify(mockedProxyDataBroker).exists(eq(LogicalDatastoreType.OPERATIONAL), eq(path));
-        assertTrue(existsFuture.isDone());
-        try {
-            existsFuture.checkedGet();
-            fail("Exception expected");
-        } catch(Exception e) {
-            assertTrue(e instanceof ReadFailedException);
-        }
-    }
-
-    @Test
-    public void testExists() throws Exception {
-        when(mockedProxyDataBroker.exists(any(LogicalDatastoreType.class), any(YangInstanceIdentifier.class)))
-            .thenReturn(Futures.successful(true));
-        CheckedFuture<Boolean, ReadFailedException> existsFuture = proxyReadOnlyTx.exists(LogicalDatastoreType.OPERATIONAL, path);
-        verify(mockedProxyDataBroker).exists(eq(LogicalDatastoreType.OPERATIONAL), eq(path));
-        assertTrue(existsFuture.isDone());
-        assertTrue(existsFuture.checkedGet());
-    }
-}
\ No newline at end of file
diff --git a/netconf/netconf-topology/src/test/java/org/opendaylight/netconf/topology/pipeline/tx/ProxyWriteOnlyTransactionTest.java b/netconf/netconf-topology/src/test/java/org/opendaylight/netconf/topology/pipeline/tx/ProxyWriteOnlyTransactionTest.java
deleted file mode 100644 (file)
index 83c118f..0000000
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.netconf.topology.pipeline.tx;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import akka.actor.ActorSystem;
-import akka.dispatch.ExecutionContexts;
-import akka.dispatch.Futures;
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.MoreExecutors;
-import java.util.concurrent.ExecutionException;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
-import org.opendaylight.netconf.topology.pipeline.ProxyNetconfDeviceDataBroker;
-import org.opendaylight.netconf.topology.util.messages.NormalizedNodeMessage;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-
-public class ProxyWriteOnlyTransactionTest {
-    private static final YangInstanceIdentifier path = YangInstanceIdentifier.create();
-    private ArgumentCaptor<NormalizedNodeMessage> nodeMessageArgumentCaptor;
-
-    @Mock
-    private ProxyNetconfDeviceDataBroker mockedDelegate;
-
-    @Mock
-    private ActorSystem mockedActorSystem;
-
-    @Mock
-    private NormalizedNode<?, ?> normalizedNode;
-
-    private ProxyWriteOnlyTransaction tx;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-
-        when(mockedActorSystem.dispatcher()).thenReturn(ExecutionContexts.fromExecutorService(MoreExecutors.newDirectExecutorService()));
-
-        nodeMessageArgumentCaptor = ArgumentCaptor.forClass(NormalizedNodeMessage.class);
-        tx = new ProxyWriteOnlyTransaction(mockedActorSystem, mockedDelegate);
-    }
-
-    @Test
-    public void testPut() {
-        doNothing().when(mockedDelegate).put(any(LogicalDatastoreType.class), any(NormalizedNodeMessage.class));
-        tx.put(LogicalDatastoreType.OPERATIONAL, path, normalizedNode);
-        verify(mockedDelegate).put(eq(LogicalDatastoreType.OPERATIONAL), nodeMessageArgumentCaptor.capture());
-        assertEquals(path, nodeMessageArgumentCaptor.getValue().getIdentifier());
-        assertEquals(normalizedNode, nodeMessageArgumentCaptor.getValue().getNode());
-    }
-
-    @Test
-    public void testMerge() {
-        doNothing().when(mockedDelegate).merge(any(LogicalDatastoreType.class), any(NormalizedNodeMessage.class));
-        tx.merge(LogicalDatastoreType.CONFIGURATION, path, normalizedNode);
-        verify(mockedDelegate).merge(eq(LogicalDatastoreType.CONFIGURATION), nodeMessageArgumentCaptor.capture());
-        assertEquals(path, nodeMessageArgumentCaptor.getValue().getIdentifier());
-        assertEquals(normalizedNode, nodeMessageArgumentCaptor.getValue().getNode());
-    }
-
-    @Test
-    public void testCancel() {
-        when(mockedDelegate.cancel()).thenReturn(true);
-        assertTrue(tx.cancel());
-        verify(mockedDelegate).cancel();
-    }
-
-    @Test
-    public void testDelete() {
-        doNothing().when(mockedDelegate).delete(any(LogicalDatastoreType.class), any(YangInstanceIdentifier.class));
-        tx.delete(LogicalDatastoreType.OPERATIONAL, path);
-        verify(mockedDelegate).delete(eq(LogicalDatastoreType.OPERATIONAL), eq(path));
-    }
-
-    @Test
-    public void testSuccessfulSubmit() throws Exception {
-        when(mockedDelegate.submit()).thenReturn(Futures.<Void>successful(null));
-        CheckedFuture submitFuture = tx.submit();
-        verify(mockedDelegate).submit();
-        assertTrue(submitFuture.isDone());
-        assertEquals(submitFuture.checkedGet(), null);
-    }
-
-    @Test
-    public void testFailedSubmit() {
-        when(mockedDelegate.submit()).thenReturn(Futures.<Void>failed(new TransactionCommitFailedException("fail")));
-        CheckedFuture submitFuture = tx.submit();
-        verify(mockedDelegate).submit();
-        assertTrue(submitFuture.isDone());
-        try {
-            submitFuture.checkedGet();
-            fail("Exception expected");
-        } catch(Exception e) {
-            assertTrue(e instanceof TransactionCommitFailedException);
-        }
-    }
-
-    @Test
-    public void testSuccessfulCommit() throws ExecutionException, InterruptedException {
-        RpcResult<TransactionStatus> rpcResult = mock(RpcResult.class);
-        when(mockedDelegate.commit()).thenReturn(Futures.successful(rpcResult));
-        ListenableFuture<RpcResult<TransactionStatus>> submitFuture = tx.commit();
-        verify(mockedDelegate).commit();
-        assertTrue(submitFuture.isDone());
-        assertEquals(submitFuture.get(), rpcResult);
-    }
-
-    @Test
-    public void testFailedCommit() {
-        when(mockedDelegate.commit()).thenReturn(Futures.<RpcResult<TransactionStatus>>failed(new TransactionCommitFailedException("faile")));
-        ListenableFuture<RpcResult<TransactionStatus>> submitFuture = tx.commit();
-        verify(mockedDelegate).commit();
-        assertTrue(submitFuture.isDone());
-        try {
-            submitFuture.get();
-            fail("Exception expected");
-        } catch(Exception e) {
-            assertTrue(e.getCause() instanceof TransactionCommitFailedException);
-        }
-    }
-}
\ No newline at end of file
diff --git a/netconf/netconf-topology/src/test/resources/netconf-node1.conf b/netconf/netconf-topology/src/test/resources/netconf-node1.conf
deleted file mode 100644 (file)
index ed0aac1..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-include "test.conf"
-
-akka {
-  # LISTEN on tcp port 2552
-  remote.netty.tcp.port = 2552
-
-  cluster {
-    seed-nodes = [
-      "akka.tcp://NetconfNode@127.0.0.1:2553",
-      "akka.tcp://NetconfNode@127.0.0.1:2554"]
-
-    auto-down-unreachable-after = 10s
-  }
-}
diff --git a/netconf/netconf-topology/src/test/resources/netconf-node2.conf b/netconf/netconf-topology/src/test/resources/netconf-node2.conf
deleted file mode 100644 (file)
index 6090891..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-include "test.conf"
-
-akka {
-  # LISTEN on tcp port 2553
-  remote.netty.tcp.port = 2553
-
-  cluster {
-    seed-nodes = [
-      "akka.tcp://NetconfNode@127.0.0.1:2552",
-      "akka.tcp://NetconfNode@127.0.0.1:2554"]
-
-    auto-down-unreachable-after = 10s
-  }
-}
diff --git a/netconf/netconf-topology/src/test/resources/netconf-node3.conf b/netconf/netconf-topology/src/test/resources/netconf-node3.conf
deleted file mode 100644 (file)
index 620ede3..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-include "test.conf"
-
-akka {
-  # LISTEN on tcp port 2554
-  remote.netty.tcp.port = 2554
-
-  cluster {
-    seed-nodes = [
-      "akka.tcp://NetconfNode@127.0.0.1:2552",
-      "akka.tcp://NetconfNode@127.0.0.1:2553"]
-
-    auto-down-unreachable-after = 10s
-  }
-}
diff --git a/netconf/netconf-topology/src/test/resources/test.conf b/netconf/netconf-topology/src/test/resources/test.conf
deleted file mode 100644 (file)
index b8c7294..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-akka {
-
-  actor {
-    provider = "akka.cluster.ClusterActorRefProvider"
-
-    serializers {
-      java = "akka.serialization.JavaSerializer"
-    }
-
-    serialization-bindings {
-      "[B" = bytes
-      "java.io.Serializable" = java
-    }
-  }
-
-  remote {
-    enabled-transports = ["akka.remote.netty.tcp"]
-    netty.tcp {
-      hostname = "127.0.0.1"
-    }
-  }
-}
index 56108b9d0d12fd7aba1b439272da19ef84bf871a..110872bf88c085de0276dae2089ffa6bddfc46ff 100644 (file)
       <groupId>org.opendaylight.yangtools</groupId>
       <artifactId>yang-data-api</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.osgi</groupId>
+      <artifactId>org.osgi.compendium</artifactId>
+    </dependency>
   </dependencies>
 
   <build>
     <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <configuration>
+          <instructions>
+            <Bundle-Activator>org.opendaylight.netconf.util.osgi.NetconfConfigurationActivator</Bundle-Activator>
+          </instructions>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>build-helper-maven-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>attach-artifacts</id>
+            <goals>
+              <goal>attach-artifact</goal>
+            </goals>
+            <phase>package</phase>
+            <configuration>
+              <artifacts>
+                <artifact>
+                  <file>${project.build.directory}/classes/netconf.cfg</file>
+                  <type>cfg</type>
+                  <classifier>config</classifier>
+                </artifact>
+              </artifacts>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-jar-plugin</artifactId>
index 9a6ff2e054e7e351ee441e00c8bf10fa028036e7..9d4b5a123839fa39eaa39a119560dc116deb7cb3 100644 (file)
@@ -11,8 +11,12 @@ package org.opendaylight.netconf.util.osgi;
 import com.google.common.base.Optional;
 import io.netty.channel.local.LocalAddress;
 import java.net.InetSocketAddress;
+import java.util.Collection;
 import java.util.concurrent.TimeUnit;
 import org.osgi.framework.BundleContext;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.cm.ManagedService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -109,4 +113,21 @@ public final class NetconfConfigUtil {
         }
         return Optional.fromNullable(value);
     }
+
+    public static java.util.Optional<NetconfConfiguration> getNetconfConfigurationService(BundleContext bundleContext) {
+        final Collection<ServiceReference<ManagedService>> serviceReferences;
+        try {
+            serviceReferences = bundleContext.getServiceReferences(ManagedService.class, null);
+            for (final ServiceReference<ManagedService> serviceReference : serviceReferences) {
+                ManagedService service = bundleContext.getService(serviceReference);
+                if (service instanceof NetconfConfiguration){
+                    return java.util.Optional.of((NetconfConfiguration) service);
+                }
+            }
+        } catch (InvalidSyntaxException e) {
+            LOG.error("Unable to retrieve references for ManagedService: {}", e);
+        }
+        LOG.error("Unable to retrieve NetconfConfiguration service. Not found. Bundle netconf-util probably failed.");
+        return java.util.Optional.empty();
+    }
 }
diff --git a/netconf/netconf-util/src/main/java/org/opendaylight/netconf/util/osgi/NetconfConfiguration.java b/netconf/netconf-util/src/main/java/org/opendaylight/netconf/util/osgi/NetconfConfiguration.java
new file mode 100644 (file)
index 0000000..e33f7e2
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.util.osgi;
+
+import java.net.InetSocketAddress;
+import java.util.Dictionary;
+import org.osgi.service.cm.ManagedService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NetconfConfiguration implements ManagedService {
+    private static final Logger LOG = LoggerFactory.getLogger(NetconfConfiguration.class);
+
+    private static final NetconfConfiguration instance = new NetconfConfiguration();
+    private NetconfConfigurationHolder netconfConfiguration;
+
+    public static final String KEY_SSH_ADDRESS = "ssh-address";
+    public static final String KEY_SSH_PORT = "ssh-port";
+    public static final String KEY_TCP_ADDRESS = "tcp-address";
+    public static final String KEY_TCP_PORT = "tcp-port";
+    public static final String KEY_SSH_PK_PATH = "ssh-pk-path";
+
+    public static NetconfConfiguration getInstance() {
+        return instance;
+    }
+
+    private NetconfConfiguration() {
+        netconfConfiguration = new NetconfConfigurationHolder(NetconfConfigUtil.DEFAULT_TCP_SERVER_ADRESS,
+                NetconfConfigUtil.DEFAULT_SSH_SERVER_ADRESS, NetconfConfigUtil.DEFAULT_PRIVATE_KEY_PATH);
+    }
+
+    @Override
+    public void updated(final Dictionary<String, ?> dictionaryConfig) {
+        if (dictionaryConfig == null) {
+            LOG.warn("Netconf configuration cannot be updated.");
+            return;
+        }
+        final InetSocketAddress sshServerAddress = new InetSocketAddress((String) dictionaryConfig.get(KEY_SSH_ADDRESS),
+                Integer.parseInt((String) dictionaryConfig.get(KEY_SSH_PORT)));
+        final InetSocketAddress tcpServerAddress = new InetSocketAddress((String) dictionaryConfig.get(KEY_TCP_ADDRESS),
+                Integer.parseInt((String) dictionaryConfig.get(KEY_TCP_PORT)));
+
+        netconfConfiguration = new NetconfConfigurationHolder(tcpServerAddress, sshServerAddress,
+                (String) dictionaryConfig.get(KEY_SSH_PK_PATH));
+
+        LOG.info("Netconf configuration was updated: {}", dictionaryConfig.toString());
+    }
+
+    public InetSocketAddress getSshServerAddress(){
+        return netconfConfiguration.getSshServerAddress();
+    }
+
+    public InetSocketAddress getTcpServerAddress(){
+        return netconfConfiguration.getTcpServerAddress();
+    }
+
+    public String getPrivateKeyPath() {
+        return netconfConfiguration.getPrivateKeyPath();
+    }
+}
\ No newline at end of file
diff --git a/netconf/netconf-util/src/main/java/org/opendaylight/netconf/util/osgi/NetconfConfigurationActivator.java b/netconf/netconf-util/src/main/java/org/opendaylight/netconf/util/osgi/NetconfConfigurationActivator.java
new file mode 100644 (file)
index 0000000..a752322
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.util.osgi;
+
+import java.util.Hashtable;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.cm.ManagedService;
+
+public class NetconfConfigurationActivator implements BundleActivator {
+    private static final String CONFIG_PID = "netconf";
+    private ServiceRegistration configService;
+
+    @Override
+    public void start(BundleContext bundleContext) {
+        configService = bundleContext.registerService(ManagedService.class,
+                NetconfConfiguration.getInstance(), getNetconfConfigProperties());
+    }
+
+    @Override
+    public void stop(BundleContext bundleContext) {
+        if (configService != null) {
+          configService.unregister();
+          configService = null;
+        }
+    }
+
+    private Hashtable<String, String> getNetconfConfigProperties(){
+        Hashtable<String, String> properties = new Hashtable<>();
+        properties.put(Constants.SERVICE_PID, CONFIG_PID);
+        return properties;
+    }
+}
diff --git a/netconf/netconf-util/src/main/java/org/opendaylight/netconf/util/osgi/NetconfConfigurationHolder.java b/netconf/netconf-util/src/main/java/org/opendaylight/netconf/util/osgi/NetconfConfigurationHolder.java
new file mode 100644 (file)
index 0000000..74b3a08
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.util.osgi;
+
+import java.net.InetSocketAddress;
+
+final class NetconfConfigurationHolder {
+
+    private final InetSocketAddress tcpServerAddress;
+    private final InetSocketAddress sshServerAddress;
+    private final String privateKeyPath;
+
+    NetconfConfigurationHolder(InetSocketAddress tcpServerAddress, InetSocketAddress sshServerAddress, String privateKeyPath){
+        this.tcpServerAddress = tcpServerAddress;
+        this.sshServerAddress = sshServerAddress;
+        this.privateKeyPath = privateKeyPath;
+    }
+
+    String getPrivateKeyPath() {
+        return privateKeyPath;
+    }
+
+    InetSocketAddress getSshServerAddress() {
+        return sshServerAddress;
+    }
+
+    InetSocketAddress getTcpServerAddress() {
+        return tcpServerAddress;
+    }
+
+}
diff --git a/netconf/netconf-util/src/main/resources/netconf.cfg b/netconf/netconf-util/src/main/resources/netconf.cfg
new file mode 100644 (file)
index 0000000..01437d8
--- /dev/null
@@ -0,0 +1,11 @@
+# netconf-tcp:
+
+tcp-address=127.0.0.1
+tcp-port=8383
+
+# netconf-ssh:
+
+ssh-address=0.0.0.0
+ssh-port=1830
+# Use Linux style path
+ssh-pk-path = ./configuration/RSA.pk
\ No newline at end of file
diff --git a/netconf/netconf-util/src/test/resources/netconfMessages/copy-config.xml b/netconf/netconf-util/src/test/resources/netconfMessages/copy-config.xml
new file mode 100644 (file)
index 0000000..ec32fc1
--- /dev/null
@@ -0,0 +1,18 @@
+<!--
+  ~ Copyright (c) 2016 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
+  -->
+
+<rpc message-id="m-0" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+    <copy-config>
+        <target>
+            <candidate/>
+        </target>
+        <source>
+            <running/>
+        </source>
+    </copy-config>
+</rpc>
\ No newline at end of file
diff --git a/netconf/netconf-util/src/test/resources/netconfMessages/edit-config-test-module-running.xml b/netconf/netconf-util/src/test/resources/netconfMessages/edit-config-test-module-running.xml
new file mode 100644 (file)
index 0000000..107121d
--- /dev/null
@@ -0,0 +1,22 @@
+<!--
+  ~ Copyright (c) 2016 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
+  -->
+
+<rpc message-id="m-0" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+    <edit-config>
+        <target>
+            <running/>
+        </target>
+        <default-operation>merge</default-operation>
+        <error-option>rollback-on-error</error-option>
+        <config xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+            <c xmlns="test:namespace">
+                <a xmlns:a="urn:ietf:params:xml:ns:netconf:base:1.0" a:operation="replace">leaf-value</a>
+            </c>
+        </config>
+    </edit-config>
+</rpc>
\ No newline at end of file
diff --git a/netconf/netconf-util/src/test/resources/netconfMessages/edit-config-test-module.xml b/netconf/netconf-util/src/test/resources/netconfMessages/edit-config-test-module.xml
new file mode 100644 (file)
index 0000000..81907d3
--- /dev/null
@@ -0,0 +1,21 @@
+<!--
+  ~ Copyright (c) 2016 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
+  -->
+
+<rpc message-id="m-0" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+    <edit-config>
+        <target>
+            <candidate/>
+        </target>
+        <error-option>rollback-on-error</error-option>
+        <config xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+            <c xmlns="test:namespace">
+                <a xmlns:a="urn:ietf:params:xml:ns:netconf:base:1.0" a:operation="replace">leaf-value</a>
+            </c>
+        </config>
+    </edit-config>
+</rpc>
\ No newline at end of file
diff --git a/netconf/netconf-util/src/test/resources/netconfMessages/getConfig_candidate-filter.xml b/netconf/netconf-util/src/test/resources/netconfMessages/getConfig_candidate-filter.xml
new file mode 100644 (file)
index 0000000..7ebbe15
--- /dev/null
@@ -0,0 +1,18 @@
+<!--
+  ~ Copyright (c) 2016 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
+  -->
+
+<rpc message-id="m-0" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+    <get-config>
+        <source>
+            <candidate/>
+        </source>
+        <filter xmlns:ns0="urn:ietf:params:xml:ns:netconf:base:1.0" ns0:type="subtree">
+            <c xmlns="test:namespace"/>
+        </filter>
+    </get-config>
+</rpc>
\ No newline at end of file
diff --git a/netconf/netconf-util/src/test/resources/netconfMessages/lock-running.xml b/netconf/netconf-util/src/test/resources/netconfMessages/lock-running.xml
new file mode 100644 (file)
index 0000000..9c202ec
--- /dev/null
@@ -0,0 +1,16 @@
+<!--
+  ~ Copyright (c) 2016 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
+  -->
+
+<rpc message-id="101"
+     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+    <lock>
+        <target>
+            <running/>
+        </target>
+    </lock>
+</rpc>
\ No newline at end of file
diff --git a/netconf/netconf-util/src/test/resources/netconfMessages/rpc-reply_get.xml b/netconf/netconf-util/src/test/resources/netconfMessages/rpc-reply_get.xml
new file mode 100644 (file)
index 0000000..b3209d7
--- /dev/null
@@ -0,0 +1,11 @@
+<!--
+  ~ Copyright (c) 2016 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
+  -->
+
+<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" a="64" message-id="a">
+    <data/>
+</rpc-reply>
\ No newline at end of file
diff --git a/netconf/netconf-util/src/test/resources/netconfMessages/unlock-running.xml b/netconf/netconf-util/src/test/resources/netconfMessages/unlock-running.xml
new file mode 100644 (file)
index 0000000..a74377a
--- /dev/null
@@ -0,0 +1,16 @@
+<!--
+  ~ Copyright (c) 2016 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
+  -->
+
+<rpc message-id="101"
+     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+    <unlock>
+        <target>
+            <running/>
+        </target>
+    </unlock>
+</rpc>
\ No newline at end of file
diff --git a/netconf/netconf-util/src/test/resources/netconfMessages/validate-running.xml b/netconf/netconf-util/src/test/resources/netconfMessages/validate-running.xml
new file mode 100644 (file)
index 0000000..783192d
--- /dev/null
@@ -0,0 +1,15 @@
+<!--
+  ~ Copyright (c) 2016 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
+  -->
+
+<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="101">
+    <validate>
+        <source>
+            <running/>
+        </source>
+    </validate>
+</rpc>
index d3e2f76f2ec3de83409cb50488faee278ca98728..925488cc637dd78e57a7df7336610a538a216089 100644 (file)
@@ -47,7 +47,7 @@
     <module>netconf-notifications-impl</module>
     <module>netconf-notifications-api</module>
     <module>netconf-topology</module>
-    <module>abstract-topology</module>
+    <module>netconf-topology-singleton</module>
     <module>netconf-topology-config</module>
     <module>sal-netconf-connector</module>
     <module>messagebus-netconf</module>
index 88eb368b9bb0a3a3a754f9e679f89b87c8876ec9..ffb5c7501763a2bf8b1222158f770591f5c403ba 100644 (file)
@@ -87,7 +87,7 @@ public final class NetconfConnectorModule extends org.opendaylight.controller.co
 
     private boolean isHostAddressPresent(final Host address) {
         return address.getDomainName() != null ||
-               address.getIpAddress() != null && (address.getIpAddress().getIpv4Address() != null || address.getIpAddress().getIpv6Address() != null);
+                address.getIpAddress() != null && (address.getIpAddress().getIpv4Address() != null || address.getIpAddress().getIpv6Address() != null);
     }
 
     @Override
index 31aa51a3b9caaa239d3fd9880b34f6b5072cf6c7..04953133a3506b18e1783d545ba736c3a9d74b33 100644 (file)
@@ -50,6 +50,8 @@ import org.opendaylight.netconf.sal.connect.netconf.schema.mapping.NetconfMessag
 import org.opendaylight.netconf.sal.connect.netconf.util.NetconfMessageTransformUtil;
 import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfCapabilityChange;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.available.capabilities.AvailableCapability;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.available.capabilities.AvailableCapabilityBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.unavailable.capabilities.UnavailableCapability;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
@@ -111,7 +113,7 @@ public class NetconfDevice implements RemoteDevice<NetconfSessionPreferences, Ne
         return new NetconfDeviceRpc(baseSchema.getSchemaContext(), listener, new NetconfMessageTransformer(baseSchema.getSchemaContext(), false, baseSchema));
     }
 
-    protected NetconfDevice(final SchemaResourcesDTO schemaResourcesDTO, final RemoteDeviceId id, final RemoteDeviceHandler<NetconfSessionPreferences> salFacade,
+    public NetconfDevice(final SchemaResourcesDTO schemaResourcesDTO, final RemoteDeviceId id, final RemoteDeviceHandler<NetconfSessionPreferences> salFacade,
                          final ExecutorService globalProcessingExecutor, final boolean reconnectOnSchemasChange) {
         this.id = id;
         this.reconnectOnSchemasChange = reconnectOnSchemasChange;
@@ -203,7 +205,7 @@ public class NetconfDevice implements RemoteDevice<NetconfSessionPreferences, Ne
         return remoteSessionCapabilities.isNotificationsSupported() && reconnectOnSchemasChange;
     }
 
-    protected void handleSalInitializationSuccess(final SchemaContext result, final NetconfSessionPreferences remoteSessionCapabilities, final DOMRpcService deviceRpc) {
+    void handleSalInitializationSuccess(final SchemaContext result, final NetconfSessionPreferences remoteSessionCapabilities, final DOMRpcService deviceRpc) {
         final BaseSchema baseSchema =
                 remoteSessionCapabilities.isNotificationsSupported() ?
                 BaseSchema.BASE_NETCONF_CTX_WITH_NOTIFICATIONS :
@@ -218,7 +220,7 @@ public class NetconfDevice implements RemoteDevice<NetconfSessionPreferences, Ne
         LOG.info("{}: Netconf connector initialized successfully", id);
     }
 
-    protected void handleSalInitializationFailure(final Throwable t, final RemoteDeviceCommunicator<NetconfMessage> listener) {
+    void handleSalInitializationFailure(final Throwable t, final RemoteDeviceCommunicator<NetconfMessage> listener) {
         LOG.error("{}: Initialization in sal failed, disconnecting from device", id, t);
         listener.close();
         onRemoteSessionDown();
@@ -452,8 +454,14 @@ public class NetconfDevice implements RemoteDevice<NetconfSessionPreferences, Ne
                     final SchemaContext result = schemaBuilderFuture.checkedGet();
                     LOG.debug("{}: Schema context built successfully from {}", id, requiredSources);
                     final Collection<QName> filteredQNames = Sets.difference(deviceSources.getRequiredSourcesQName(), capabilities.getUnresolvedCapabilites().keySet());
-                    capabilities.addCapabilities(filteredQNames);
-                    capabilities.addNonModuleBasedCapabilities(remoteSessionCapabilities.getNonModuleCaps());
+                    capabilities.addCapabilities(filteredQNames.stream().map(entry -> new AvailableCapabilityBuilder()
+                            .setCapability(entry.toString()).setCapabilityOrigin(remoteSessionCapabilities.getModuleBasedCapsOrigin().get(entry)).build())
+                            .collect(Collectors.toList()));
+
+                    capabilities.addNonModuleBasedCapabilities(remoteSessionCapabilities.getNonModuleCaps().stream().map(entry -> new AvailableCapabilityBuilder()
+                            .setCapability(entry).setCapabilityOrigin(AvailableCapability.CapabilityOrigin.DeviceAdvertised).build())
+                            .collect(Collectors.toList()));
+
                     handleSalInitializationSuccess(result, remoteSessionCapabilities, getDeviceSpecificRpc(result));
                     return;
                 } catch (final Throwable t) {
index 7f4ecd96db2df88ac1bf9958d4e25cd6fef1a201..d9ca7df3e923572d8acb8aed014450fba92f0163 100644 (file)
@@ -25,9 +25,9 @@ import java.util.Collections;
 import java.util.Set;
 import java.util.concurrent.ExecutionException;
 import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
 import org.opendaylight.netconf.sal.connect.api.NetconfDeviceSchemas;
 import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences;
-import org.opendaylight.netconf.sal.connect.netconf.sal.NetconfDeviceRpc;
 import org.opendaylight.netconf.sal.connect.netconf.schema.mapping.BaseSchema;
 import org.opendaylight.netconf.sal.connect.netconf.util.NetconfMessageTransformUtil;
 import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
@@ -92,7 +92,7 @@ public final class NetconfStateSchemas implements NetconfDeviceSchemas {
     /**
      * Issue get request to remote device and parse response to find all schemas under netconf-state/schemas
      */
-    static NetconfStateSchemas create(final NetconfDeviceRpc deviceRpc, final NetconfSessionPreferences remoteSessionCapabilities, final RemoteDeviceId id) {
+    static NetconfStateSchemas create(final DOMRpcService deviceRpc, final NetconfSessionPreferences remoteSessionCapabilities, final RemoteDeviceId id) {
         if(remoteSessionCapabilities.isMonitoringSupported() == false) {
             // TODO - need to search for get-schema support, not just ietf-netconf-monitoring support
             // issue might be a deviation to ietf-netconf-monitoring where get-schema is unsupported...
index e349a939c29380e5fcb010a069b51f3a0812cc7c..5b1dd458c1144d3562e12eb91e54fb2dc7ccea02 100644 (file)
@@ -13,14 +13,14 @@ import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.available.capabilities.AvailableCapability;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.unavailable.capabilities.UnavailableCapability.FailureReason;
 import org.opendaylight.yangtools.yang.common.QName;
 
 public final class NetconfDeviceCapabilities {
     private final Map<QName, FailureReason> unresolvedCapabilites;
-    private final Set<QName> resolvedCapabilities;
-
-    private final Set<String> nonModuleBasedCapabilities;
+    private final Set<AvailableCapability>  resolvedCapabilities;
+    private final Set<AvailableCapability> nonModuleBasedCapabilities;
 
     public NetconfDeviceCapabilities() {
         this.unresolvedCapabilites = new HashMap<>();
@@ -38,15 +38,15 @@ public final class NetconfDeviceCapabilities {
         }
     }
 
-    public void addCapabilities(Collection<QName> availableSchemas) {
+    public void addCapabilities(Collection<AvailableCapability>  availableSchemas) {
         resolvedCapabilities.addAll(availableSchemas);
     }
 
-    public void addNonModuleBasedCapabilities(Collection<String> nonModuleCapabilities) {
+    public void addNonModuleBasedCapabilities(Collection<AvailableCapability> nonModuleCapabilities) {
         this.nonModuleBasedCapabilities.addAll(nonModuleCapabilities);
     }
 
-    public Set<String> getNonModuleBasedCapabilities() {
+    public Set<AvailableCapability> getNonModuleBasedCapabilities() {
         return nonModuleBasedCapabilities;
     }
 
@@ -54,7 +54,7 @@ public final class NetconfDeviceCapabilities {
         return unresolvedCapabilites;
     }
 
-    public Set<QName> getResolvedCapabilities() {
+    public Set<AvailableCapability>  getResolvedCapabilities() {
         return resolvedCapabilities;
     }
 
index 084481eec736096ff700801aeb2efc1d75a9b75b..7fb1b05db32f32d96622e36fcbfdb6736921e17e 100644 (file)
@@ -14,16 +14,20 @@ import com.google.common.base.Preconditions;
 import com.google.common.base.Predicate;
 import com.google.common.base.Splitter;
 import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterables;
+import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
 import java.net.URI;
 import java.util.Collection;
-import java.util.HashSet;
+import java.util.HashMap;
 import java.util.Iterator;
+import java.util.Map;
 import java.util.Set;
 import org.opendaylight.netconf.client.NetconfClientSession;
 import org.opendaylight.netconf.sal.connect.netconf.util.NetconfMessageTransformUtil;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.available.capabilities.AvailableCapability.CapabilityOrigin;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -67,15 +71,19 @@ public final class NetconfSessionPreferences {
         }
     };
 
-    private final Set<QName> moduleBasedCaps;
+    private final Map<QName, CapabilityOrigin> moduleBasedCaps;
     private final Set<String> nonModuleCaps;
 
-    NetconfSessionPreferences(final Set<String> nonModuleCaps, final Set<QName> moduleBasedCaps) {
+    NetconfSessionPreferences(final Set<String> nonModuleCaps, final Map<QName, CapabilityOrigin> moduleBasedCaps) {
         this.nonModuleCaps = Preconditions.checkNotNull(nonModuleCaps);
         this.moduleBasedCaps = Preconditions.checkNotNull(moduleBasedCaps);
     }
 
     public Set<QName> getModuleBasedCaps() {
+        return moduleBasedCaps.keySet();
+    }
+
+    public Map<QName, CapabilityOrigin> getModuleBasedCapsOrigin() {
         return moduleBasedCaps;
     }
 
@@ -100,7 +108,7 @@ public final class NetconfSessionPreferences {
     }
 
     public boolean containsModuleCapability(final QName capability) {
-        return moduleBasedCaps.contains(capability);
+        return moduleBasedCaps.containsKey(capability);
     }
 
     @Override
@@ -145,9 +153,9 @@ public final class NetconfSessionPreferences {
      * @return new instance of preferences with merged module-based capabilities
      */
     public NetconfSessionPreferences addModuleCaps(final NetconfSessionPreferences netconfSessionModuleCapabilities) {
-        final HashSet<QName> mergedCaps = Sets.newHashSetWithExpectedSize(moduleBasedCaps.size() + netconfSessionModuleCapabilities.getModuleBasedCaps().size());
-        mergedCaps.addAll(moduleBasedCaps);
-        mergedCaps.addAll(netconfSessionModuleCapabilities.getModuleBasedCaps());
+        final Map<QName, CapabilityOrigin> mergedCaps = Maps.newHashMapWithExpectedSize(moduleBasedCaps.size() + netconfSessionModuleCapabilities.getModuleBasedCaps().size());
+        mergedCaps.putAll(moduleBasedCaps);
+        mergedCaps.putAll(netconfSessionModuleCapabilities.getModuleBasedCapsOrigin());
         return new NetconfSessionPreferences(getNonModuleCaps(), mergedCaps);
     }
 
@@ -159,7 +167,11 @@ public final class NetconfSessionPreferences {
      * @return new instance of preferences with replaced module-based capabilities
      */
     public NetconfSessionPreferences replaceModuleCaps(final NetconfSessionPreferences netconfSessionPreferences) {
-        return new NetconfSessionPreferences(getNonModuleCaps(), netconfSessionPreferences.getModuleBasedCaps());
+        return new NetconfSessionPreferences(getNonModuleCaps(), netconfSessionPreferences.getModuleBasedCapsOrigin());
+    }
+
+    public NetconfSessionPreferences replaceModuleCaps(Map<QName, CapabilityOrigin> newModuleBasedCaps) {
+        return new NetconfSessionPreferences(getNonModuleCaps(), newModuleBasedCaps);
     }
 
     public static NetconfSessionPreferences fromNetconfSession(final NetconfClientSession session) {
@@ -175,7 +187,12 @@ public final class NetconfSessionPreferences {
     }
 
     public static NetconfSessionPreferences fromStrings(final Collection<String> capabilities) {
-        final Set<QName> moduleBasedCaps = new HashSet<>();
+        // we do not know origin of capabilities from only Strings, so we set it to default value
+        return fromStrings(capabilities, CapabilityOrigin.DeviceAdvertised);
+    }
+
+    public static NetconfSessionPreferences fromStrings(final Collection<String> capabilities, CapabilityOrigin capabilityOrigin) {
+        final Map<QName, CapabilityOrigin> moduleBasedCaps = new HashMap<>();
         final Set<String> nonModuleCaps = Sets.newHashSet(capabilities);
 
         for (final String capability : capabilities) {
@@ -193,7 +210,7 @@ public final class NetconfSessionPreferences {
 
             String revision = REVISION_PARAM.from(queryParams);
             if (!Strings.isNullOrEmpty(revision)) {
-                addModuleQName(moduleBasedCaps, nonModuleCaps, capability, cachedQName(namespace, revision, moduleName));
+                addModuleQName(moduleBasedCaps, nonModuleCaps, capability, cachedQName(namespace, revision, moduleName), capabilityOrigin);
                 continue;
             }
 
@@ -207,23 +224,22 @@ public final class NetconfSessionPreferences {
                 revision = BROKEN_REVISON_PARAM.from(queryParams);
                 if (Strings.isNullOrEmpty(revision)) {
                     LOG.warn("Netconf device returned revision incorrectly escaped for {}, ignoring it", capability);
-                    addModuleQName(moduleBasedCaps, nonModuleCaps, capability, cachedQName(namespace, moduleName));
+                    addModuleQName(moduleBasedCaps, nonModuleCaps, capability, cachedQName(namespace, moduleName), capabilityOrigin);
                 } else {
-                    addModuleQName(moduleBasedCaps, nonModuleCaps, capability, cachedQName(namespace, revision, moduleName));
+                    addModuleQName(moduleBasedCaps, nonModuleCaps, capability, cachedQName(namespace, revision, moduleName), capabilityOrigin);
                 }
                 continue;
             }
 
             // Fallback, no revision provided for module
-            addModuleQName(moduleBasedCaps, nonModuleCaps, capability, cachedQName(namespace, moduleName));
+            addModuleQName(moduleBasedCaps, nonModuleCaps, capability, cachedQName(namespace, moduleName), capabilityOrigin);
         }
 
-        return new NetconfSessionPreferences(ImmutableSet.copyOf(nonModuleCaps), ImmutableSet.copyOf(moduleBasedCaps));
+        return new NetconfSessionPreferences(ImmutableSet.copyOf(nonModuleCaps), ImmutableMap.copyOf(moduleBasedCaps));
     }
 
-
-    private static void addModuleQName(final Set<QName> moduleBasedCaps, final Set<String> nonModuleCaps, final String capability, final QName qName) {
-        moduleBasedCaps.add(qName);
+    private static void addModuleQName(final Map<QName, CapabilityOrigin> moduleBasedCaps, final Set<String> nonModuleCaps, final String capability, final QName qName, CapabilityOrigin capabilityOrigin) {
+        moduleBasedCaps.put(qName, capabilityOrigin);
         nonModuleCaps.remove(capability);
     }
 
index b440b1d900fa7b81c9419ae68c2e2fa05aa5fad2..b0617cfca91f36a397530f602858a8334580e790 100644 (file)
@@ -18,6 +18,7 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.Map.Entry;
 import java.util.concurrent.ExecutionException;
+import java.util.stream.Collectors;
 import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
@@ -29,8 +30,10 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev15
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus.ConnectionStatus;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.AvailableCapabilitiesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.ClusteredConnectionStatusBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.UnavailableCapabilities;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.UnavailableCapabilitiesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.available.capabilities.AvailableCapability;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.unavailable.capabilities.UnavailableCapability;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.unavailable.capabilities.UnavailableCapability.FailureReason;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.unavailable.capabilities.UnavailableCapabilityBuilder;
@@ -51,7 +54,7 @@ import org.opendaylight.yangtools.yang.common.QName;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-final class NetconfDeviceTopologyAdapter implements AutoCloseable {
+public final class NetconfDeviceTopologyAdapter implements AutoCloseable {
 
     private static final Logger LOG = LoggerFactory.getLogger(NetconfDeviceTopologyAdapter.class);
     public static final Function<Entry<QName, FailureReason>, UnavailableCapability> UNAVAILABLE_CAPABILITY_TRANSFORMER = new Function<Entry<QName, FailureReason>, UnavailableCapability>() {
@@ -62,13 +65,6 @@ final class NetconfDeviceTopologyAdapter implements AutoCloseable {
                     .setFailureReason(input.getValue()).build();
         }
     };
-    public static final Function<QName, String> AVAILABLE_CAPABILITY_TRANSFORMER = new Function<QName, String>() {
-        @Override
-        public String apply(QName qName) {
-            // intern string representation of a capability to avoid duplicates
-            return qName.toString().intern();
-        }
-    };
 
     private final RemoteDeviceId id;
     private BindingTransactionChain txChain;
@@ -134,6 +130,21 @@ final class NetconfDeviceTopologyAdapter implements AutoCloseable {
         commitTransaction(writeTx, "update");
     }
 
+    public void updateClusteredDeviceData(boolean up, String masterAddress, NetconfDeviceCapabilities capabilities) {
+        final NetconfNode data = buildDataForNetconfClusteredNode(up, masterAddress, capabilities);
+
+        final WriteTransaction writeTx = txChain.newWriteOnlyTransaction();
+        LOG.trace(
+                "{}: Update device state transaction {} merging operational data started.",
+                id, writeTx.getIdentifier());
+        writeTx.put(LogicalDatastoreType.OPERATIONAL, id.getTopologyBindingPath().augmentation(NetconfNode.class), data, true);
+        LOG.trace(
+                "{}: Update device state transaction {} merging operational data ended.",
+                id, writeTx.getIdentifier());
+
+        commitTransaction(writeTx, "update");
+    }
+
     public void setDeviceAsFailed(Throwable throwable) {
         String reason = (throwable != null && throwable.getMessage() != null) ? throwable.getMessage() : UNKNOWN_REASON;
 
@@ -152,9 +163,10 @@ final class NetconfDeviceTopologyAdapter implements AutoCloseable {
     }
 
     private NetconfNode buildDataForNetconfNode(boolean up, NetconfDeviceCapabilities capabilities) {
-        List<String> capabilityList = new ArrayList<>();
+        List<AvailableCapability> capabilityList = new ArrayList<>();
         capabilityList.addAll(capabilities.getNonModuleBasedCapabilities());
-        capabilityList.addAll(FluentIterable.from(capabilities.getResolvedCapabilities()).transform(AVAILABLE_CAPABILITY_TRANSFORMER).toList());
+        capabilityList.addAll(capabilities.getResolvedCapabilities());
+
         final AvailableCapabilitiesBuilder avCapabalitiesBuilder = new AvailableCapabilitiesBuilder();
         avCapabalitiesBuilder.setAvailableCapability(capabilityList);
 
@@ -172,6 +184,30 @@ final class NetconfDeviceTopologyAdapter implements AutoCloseable {
         return netconfNodeBuilder.build();
     }
 
+    private NetconfNode buildDataForNetconfClusteredNode(boolean up, String masterNodeAddress, NetconfDeviceCapabilities capabilities) {
+        List<AvailableCapability> capabilityList = new ArrayList<>();
+        capabilityList.addAll(capabilities.getNonModuleBasedCapabilities());
+        capabilityList.addAll(capabilities.getResolvedCapabilities());
+        final AvailableCapabilitiesBuilder avCapabalitiesBuilder = new AvailableCapabilitiesBuilder();
+        avCapabalitiesBuilder.setAvailableCapability(capabilityList);
+
+        final UnavailableCapabilities unavailableCapabilities =
+                new UnavailableCapabilitiesBuilder().setUnavailableCapability(capabilities.getUnresolvedCapabilites()
+                        .entrySet().stream().map(UNAVAILABLE_CAPABILITY_TRANSFORMER::apply)
+                        .collect(Collectors.toList())).build();
+
+        final NetconfNodeBuilder netconfNodeBuilder = new NetconfNodeBuilder()
+                .setHost(id.getHost())
+                .setPort(new PortNumber(id.getAddress().getPort()))
+                .setConnectionStatus(up ? ConnectionStatus.Connected : ConnectionStatus.Connecting)
+                .setAvailableCapabilities(avCapabalitiesBuilder.build())
+                .setUnavailableCapabilities(unavailableCapabilities)
+                .setClusteredConnectionStatus(
+                        new ClusteredConnectionStatusBuilder().setNetconfMasterNode(masterNodeAddress).build());
+
+        return netconfNodeBuilder.build();
+    }
+
     public void removeDeviceConfiguration() {
         final WriteTransaction writeTx = txChain.newWriteOnlyTransaction();
 
index 6df2239f5140698f9072809366524d63ceeffecd..e2cedbc2a47f3737c86f3e1c3188e592bd2e8678 100644 (file)
@@ -22,9 +22,7 @@ import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
 import org.opendaylight.netconf.sal.connect.netconf.util.NetconfBaseOps;
 import org.opendaylight.netconf.sal.connect.netconf.util.NetconfRpcFutureCallback;
 import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
-import org.opendaylight.yangtools.yang.common.RpcError;
 import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
 import org.opendaylight.yangtools.yang.data.api.ModifyAction;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
@@ -56,22 +54,6 @@ public class WriteCandidateTx extends AbstractWriteTx {
 
     private static final Logger LOG  = LoggerFactory.getLogger(WriteCandidateTx.class);
 
-    private static final Function<DOMRpcResult, RpcResult<TransactionStatus>> RPC_RESULT_TO_TX_STATUS = new Function<DOMRpcResult, RpcResult<TransactionStatus>>() {
-        @Override
-        public RpcResult<TransactionStatus> apply(final DOMRpcResult input) {
-            if (isSuccess(input)) {
-                return RpcResultBuilder.success(TransactionStatus.COMMITED).build();
-            } else {
-                final RpcResultBuilder<TransactionStatus> failed = RpcResultBuilder.failed();
-                for (final RpcError rpcError : input.getErrors()) {
-                    failed.withError(rpcError.getErrorType(), rpcError.getTag(), rpcError.getMessage(),
-                            rpcError.getApplicationTag(), rpcError.getInfo(), rpcError.getCause());
-                }
-                return failed.build();
-            }
-        }
-    };
-
     public WriteCandidateTx(final RemoteDeviceId id, final NetconfBaseOps rpc, final boolean rollbackSupport) {
         super(rpc, id, rollbackSupport);
     }
@@ -85,7 +67,7 @@ public class WriteCandidateTx extends AbstractWriteTx {
     private void lock() {
         final FutureCallback<DOMRpcResult> lockCandidateCallback = new FutureCallback<DOMRpcResult>() {
             @Override
-            public void onSuccess(DOMRpcResult result) {
+            public void onSuccess(final DOMRpcResult result) {
                 if (isSuccess(result)) {
                     if (LOG.isTraceEnabled()) {
                         LOG.trace("Lock candidate successful");
@@ -96,7 +78,7 @@ public class WriteCandidateTx extends AbstractWriteTx {
             }
 
             @Override
-            public void onFailure(Throwable t) {
+            public void onFailure(final Throwable t) {
                 LOG.warn("Lock candidate operation failed. {}", t);
                 discardChanges();
             }
@@ -138,16 +120,16 @@ public class WriteCandidateTx extends AbstractWriteTx {
     @Override
     public synchronized ListenableFuture<RpcResult<TransactionStatus>> performCommit() {
         resultsFutures.add(netOps.commit(new NetconfRpcFutureCallback("Commit", id)));
-        ListenableFuture<RpcResult<TransactionStatus>> txResult = resultsToTxStatus();
+        final ListenableFuture<RpcResult<TransactionStatus>> txResult = resultsToTxStatus();
 
         Futures.addCallback(txResult, new FutureCallback<RpcResult<TransactionStatus>>() {
             @Override
-            public void onSuccess(@Nullable RpcResult<TransactionStatus> result) {
+            public void onSuccess(@Nullable final RpcResult<TransactionStatus> result) {
                 cleanupOnSuccess();
             }
 
             @Override
-            public void onFailure(Throwable t) {
+            public void onFailure(final Throwable t) {
                 // TODO If lock is cause of this failure cleanup will issue warning log
                 // cleanup is trying to do unlock, but this will fail
                 cleanup();
@@ -168,7 +150,7 @@ public class WriteCandidateTx extends AbstractWriteTx {
                               final Optional<ModifyAction> defaultOperation,
                               final String operation) {
 
-        NetconfRpcFutureCallback editConfigCallback = new NetconfRpcFutureCallback("Edit candidate", id);
+        final NetconfRpcFutureCallback editConfigCallback = new NetconfRpcFutureCallback("Edit candidate", id);
 
         if (defaultOperation.isPresent()) {
             resultsFutures.add(netOps.editConfigCandidate(
index 62b88b974f2091e575b6a4f70b59ad4b1b7b1e55..169d41961638ae961fc8805c297f29f93a0c7e44 100644 (file)
@@ -153,6 +153,10 @@ module netconf-node-topology {
                     }
                 }
             }
+            leaf netconf-master-node {
+                config false;
+                type string;
+            }
         }
 
         leaf connected-message {
@@ -162,8 +166,16 @@ module netconf-node-topology {
 
         container available-capabilities {
             config false;
-            leaf-list available-capability {
-                type string;
+            list available-capability {
+                leaf capability {
+                    type string;
+                }
+                leaf capability-origin {
+                    type enumeration {
+                        enum user-defined;
+                        enum device-advertised;
+                    }
+                }
             }
         }
 
index ae6726b7802f64efcdde29e272711e85a315af1c..9708888f5d0c44fb24eab62ea88e101f21b0c8fe 100644 (file)
@@ -8,6 +8,7 @@
 
 package org.opendaylight.netconf.sal.connect.netconf;
 
+import static org.junit.Assert.assertEquals;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyCollectionOf;
 import static org.mockito.Matchers.eq;
@@ -30,10 +31,13 @@ import java.net.InetSocketAddress;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import org.junit.Test;
+import org.mockito.ArgumentCaptor;
 import org.mockito.Mockito;
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
@@ -48,11 +52,13 @@ import org.opendaylight.netconf.sal.connect.api.MessageTransformer;
 import org.opendaylight.netconf.sal.connect.api.NetconfDeviceSchemas;
 import org.opendaylight.netconf.sal.connect.api.NetconfDeviceSchemasResolver;
 import org.opendaylight.netconf.sal.connect.api.RemoteDeviceHandler;
+import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfDeviceCapabilities;
 import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfDeviceCommunicator;
 import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences;
 import org.opendaylight.netconf.sal.connect.netconf.sal.NetconfDeviceRpc;
 import org.opendaylight.netconf.sal.connect.netconf.util.NetconfMessageTransformUtil;
 import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.available.capabilities.AvailableCapability;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
@@ -65,8 +71,8 @@ import org.opendaylight.yangtools.yang.model.repo.api.RevisionSourceIdentifier;
 import org.opendaylight.yangtools.yang.model.repo.api.SchemaContextFactory;
 import org.opendaylight.yangtools.yang.model.repo.api.SchemaRepository;
 import org.opendaylight.yangtools.yang.model.repo.api.SchemaResolutionException;
-import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
 import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceRepresentation;
+import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
 import org.opendaylight.yangtools.yang.model.repo.spi.PotentialSchemaSource;
 import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceRegistration;
 import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceRegistry;
@@ -329,6 +335,40 @@ public class NetconfDeviceTest {
         verify(facade, timeout(5000).times(2)).onDeviceConnected(any(SchemaContext.class), any(NetconfSessionPreferences.class), any(DOMRpcService.class));
     }
 
+    @Test
+    public void testNetconfDeviceAvailableCapabilitiesBuilding() throws Exception {
+        final RemoteDeviceHandler<NetconfSessionPreferences> facade = getFacade();
+        final NetconfDeviceCommunicator listener = getListener();
+
+        final SchemaContextFactory schemaContextProviderFactory = getSchemaFactory();
+
+        final NetconfDevice.SchemaResourcesDTO schemaResourcesDTO
+                = new NetconfDevice.SchemaResourcesDTO(getSchemaRegistry(), getSchemaRepository(), schemaContextProviderFactory, stateSchemasResolver);
+        final NetconfDevice device = new NetconfDeviceBuilder()
+                .setReconnectOnSchemasChange(true)
+                .setSchemaResourcesDTO(schemaResourcesDTO)
+                .setGlobalProcessingExecutor(getExecutor())
+                .setId(getId())
+                .setSalFacade(facade)
+                .build();
+        NetconfDevice netconfSpy = Mockito.spy(device);
+
+        final NetconfSessionPreferences sessionCaps = getSessionCaps(true,
+                Lists.newArrayList(TEST_NAMESPACE + "?module=" + TEST_MODULE + "&amp;revision=" + TEST_REVISION));
+        Map<QName, AvailableCapability.CapabilityOrigin> moduleBasedCaps = new HashMap<>();
+        moduleBasedCaps.putAll(sessionCaps.getModuleBasedCapsOrigin());
+        moduleBasedCaps.put(QName.create("test:qname:side:loading"), AvailableCapability.CapabilityOrigin.UserDefined);
+
+        netconfSpy.onRemoteSessionUp(sessionCaps.replaceModuleCaps(moduleBasedCaps), listener);
+
+        ArgumentCaptor argument = ArgumentCaptor.forClass(NetconfSessionPreferences.class);
+        verify(netconfSpy, timeout(5000)).handleSalInitializationSuccess(any(SchemaContext.class), (NetconfSessionPreferences) argument.capture(), any(DOMRpcService.class));
+        NetconfDeviceCapabilities netconfDeviceCaps = ((NetconfSessionPreferences) argument.getValue()).getNetconfDeviceCapabilities();
+
+        netconfDeviceCaps.getResolvedCapabilities().forEach(entry -> assertEquals("Builded 'AvailableCapability' schemas should match input capabilities.",
+                moduleBasedCaps.get(QName.create(entry.getCapability())).getName(), entry.getCapabilityOrigin().getName()));
+    }
+
     private SchemaContextFactory getSchemaFactory() {
         final SchemaContextFactory schemaFactory = mockClass(SchemaContextFactory.class);
         doReturn(Futures.immediateCheckedFuture(getSchema())).when(schemaFactory).createSchemaContext(any(Collection.class));
index 97b9ef33703060f4d3df24320a3ee5520f8c94ee..c8564975b681bfbc519a1ed3fbabbca03dd7c204 100644 (file)
@@ -11,19 +11,48 @@ package org.opendaylight.netconf.sal.connect.netconf;
 import static org.hamcrest.CoreMatchers.hasItem;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertThat;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.opendaylight.netconf.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_GET_QNAME;
+import static org.opendaylight.netconf.sal.connect.netconf.util.NetconfMessageTransformUtil.toPath;
 
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
 import java.net.InetSocketAddress;
 import java.util.Collections;
 import java.util.Set;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import org.junit.Assert;
+import org.junit.Before;
 import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
 import org.opendaylight.controller.config.util.xml.XmlUtil;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcException;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcImplementationNotAvailableException;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
+import org.opendaylight.controller.md.sal.dom.spi.DefaultDOMRpcResult;
+import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences;
 import org.opendaylight.netconf.sal.connect.netconf.schema.mapping.BaseSchema;
+import org.opendaylight.netconf.sal.connect.netconf.util.NetconfMessageTransformUtil;
 import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.NetconfState;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.Schemas;
 import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.RpcError;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
 import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlUtils;
+import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
 import org.opendaylight.yangtools.yang.data.impl.schema.transform.ToNormalizedNodeParser;
 import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser.DomToNormalizedNodeParserFactory;
 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
@@ -34,17 +63,28 @@ import org.w3c.dom.Element;
 
 public class NetconfStateSchemasTest {
 
-    @Test
-    public void testCreate() throws Exception {
+    private static final NetconfSessionPreferences CAPS = NetconfSessionPreferences.fromStrings(Collections.singleton("urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring?module=ietf-netconf-monitoring&amp;revision=2010-10-04"));
+    private final RemoteDeviceId deviceId = new RemoteDeviceId("device", new InetSocketAddress(99));
+    private ContainerNode compositeNodeSchemas;
+    @Mock
+    private DOMRpcService rpc;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
         final SchemaContext schemaContext = BaseSchema.BASE_NETCONF_CTX_WITH_NOTIFICATIONS.getSchemaContext();
         final DataSchemaNode schemasNode =
                 ((ContainerSchemaNode) schemaContext
                         .getDataChildByName(NetconfState.QNAME)).getDataChildByName(Schemas.QNAME);
-
         final Document schemasXml = XmlUtil.readXmlToDocument(getClass().getResourceAsStream("/netconf-state.schemas.payload.xml"));
         final ToNormalizedNodeParser<Element, ContainerNode, ContainerSchemaNode> containerNodeParser = DomToNormalizedNodeParserFactory.getInstance(XmlUtils.DEFAULT_XML_CODEC_PROVIDER, schemaContext, false).getContainerNodeParser();
-        final ContainerNode compositeNodeSchemas = containerNodeParser.parse(Collections.singleton(schemasXml.getDocumentElement()), (ContainerSchemaNode) schemasNode);
-        final NetconfStateSchemas schemas = NetconfStateSchemas.create(new RemoteDeviceId("device", new InetSocketAddress(99)), compositeNodeSchemas);
+        compositeNodeSchemas = containerNodeParser.parse(Collections.singleton(schemasXml.getDocumentElement()), (ContainerSchemaNode) schemasNode);
+
+    }
+
+    @Test
+    public void testCreate() throws Exception {
+        final NetconfStateSchemas schemas = NetconfStateSchemas.create(deviceId, compositeNodeSchemas);
 
         final Set<QName> availableYangSchemasQNames = schemas.getAvailableYangSchemasQNames();
         assertEquals(73, availableYangSchemasQNames.size());
@@ -52,4 +92,88 @@ public class NetconfStateSchemasTest {
         assertThat(availableYangSchemasQNames,
                 hasItem(QName.create("urn:TBD:params:xml:ns:yang:network-topology", "2013-07-12", "network-topology")));
     }
+
+    @Test
+    public void testCreate2() throws Exception {
+        final ContainerNode netconfState = Builders.containerBuilder()
+                .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(NetconfState.QNAME))
+                .withChild(compositeNodeSchemas)
+                .build();
+        final ContainerNode data = Builders.containerBuilder()
+                .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(NetconfMessageTransformUtil.NETCONF_DATA_QNAME))
+                .withChild(netconfState)
+                .build();
+        final ContainerNode rpcReply = Builders.containerBuilder()
+                .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(NetconfMessageTransformUtil.NETCONF_RPC_REPLY_QNAME))
+                .withChild(data)
+                .build();
+        when(rpc.invokeRpc(eq(toPath(NETCONF_GET_QNAME)), any())).thenReturn(Futures.immediateCheckedFuture(new DefaultDOMRpcResult(rpcReply)));
+        final NetconfStateSchemas stateSchemas = NetconfStateSchemas.create(rpc, CAPS, deviceId);
+        final Set<QName> availableYangSchemasQNames = stateSchemas.getAvailableYangSchemasQNames();
+        assertEquals(73, availableYangSchemasQNames.size());
+
+        assertThat(availableYangSchemasQNames,
+                hasItem(QName.create("urn:TBD:params:xml:ns:yang:network-topology", "2013-07-12", "network-topology")));
+    }
+
+    @Test
+    public void testCreateMonitoringNotSupported() throws Exception {
+        final NetconfSessionPreferences caps = NetconfSessionPreferences.fromStrings(Collections.emptySet());
+        final NetconfStateSchemas stateSchemas = NetconfStateSchemas.create(rpc, caps, deviceId);
+        final Set<QName> availableYangSchemasQNames = stateSchemas.getAvailableYangSchemasQNames();
+        Assert.assertTrue(availableYangSchemasQNames.isEmpty());
+    }
+
+    @Test
+    public void testCreateFail() throws Exception {
+        final CheckedFuture<DOMRpcResult, DOMRpcException> resultFuture =
+                Futures.immediateFailedCheckedFuture(new DOMRpcImplementationNotAvailableException("not available"));
+        when(rpc.invokeRpc(eq(toPath(NETCONF_GET_QNAME)), any())).thenReturn(resultFuture);
+        final NetconfStateSchemas stateSchemas = NetconfStateSchemas.create(rpc, CAPS, deviceId);
+        final Set<QName> availableYangSchemasQNames = stateSchemas.getAvailableYangSchemasQNames();
+        Assert.assertTrue(availableYangSchemasQNames.isEmpty());
+    }
+
+    @Test
+    public void testCreateRpcError() throws Exception {
+        final RpcError rpcError = RpcResultBuilder.newError(RpcError.ErrorType.RPC, "fail", "fail");
+        when(rpc.invokeRpc(eq(toPath(NETCONF_GET_QNAME)), any())).thenReturn(Futures.immediateCheckedFuture(new DefaultDOMRpcResult(rpcError)));
+        final NetconfStateSchemas stateSchemas = NetconfStateSchemas.create(rpc, CAPS, deviceId);
+        final Set<QName> availableYangSchemasQNames = stateSchemas.getAvailableYangSchemasQNames();
+        Assert.assertTrue(availableYangSchemasQNames.isEmpty());
+    }
+
+    @Test(expected = RuntimeException.class)
+    public void testCreateInterrupted() throws Throwable {
+        //NetconfStateSchemas.create calls Thread.currentThread().interrupt(), so it must run in its own thread
+        final Future<?> testFuture = Executors.newSingleThreadExecutor().submit(() -> {
+            final ListenableFuture interruptedFuture = mock(ListenableFuture.class);
+            try {
+                when(interruptedFuture.get()).thenThrow(new InterruptedException("interrupted"));
+                final CheckedFuture checkedFuture = Futures.makeChecked(interruptedFuture, ReadFailedException.MAPPER);
+                when(rpc.invokeRpc(eq(toPath(NETCONF_GET_QNAME)), any())).thenReturn(checkedFuture);
+                NetconfStateSchemas.create(rpc, CAPS, deviceId);
+            } catch (final InterruptedException | ExecutionException e) {
+                e.printStackTrace();
+            }
+
+        });
+        try {
+            testFuture.get(3, TimeUnit.SECONDS);
+        } catch (final ExecutionException e) {
+            throw e.getCause();
+        }
+    }
+
+    @Test
+    public void testRemoteYangSchemaEquals() throws Exception {
+        final NetconfStateSchemas.RemoteYangSchema schema1 = new NetconfStateSchemas.RemoteYangSchema(NetconfState.QNAME);
+        final NetconfStateSchemas.RemoteYangSchema schema2 = new NetconfStateSchemas.RemoteYangSchema(NetconfState.QNAME);
+        final NetconfStateSchemas.RemoteYangSchema schema3 = new NetconfStateSchemas.RemoteYangSchema(Schemas.QNAME);
+        Assert.assertEquals(schema1, schema2);
+        Assert.assertEquals(schema2, schema1);
+        Assert.assertNotEquals(schema1, schema3);
+        Assert.assertNotEquals(schema2, schema3);
+
+    }
 }
index 7938f429a65c3b16bf0c6d85329777b04f0661e5..bf18b6f30277059a1012baa336ad51221209092d 100644 (file)
@@ -145,7 +145,7 @@ public class NetconfDeviceCommunicatorTest {
         assertEquals( "containsModuleCapability", false, actualCapabilites.containsNonModuleCapability(testCapability) );
         assertEquals( "getModuleBasedCaps", Sets.newHashSet(
                             QName.create( "urn:opendaylight:params:xml:ns:test", "2014-06-02", "test-module" )),
-                      actualCapabilites.getModuleBasedCaps() );
+                      actualCapabilites.getModuleBasedCaps());
         assertEquals( "isRollbackSupported", true, actualCapabilites.isRollbackSupported() );
         assertEquals( "isMonitoringSupported", true, actualCapabilites.isMonitoringSupported() );
     }
index 7e62990bc7288e619362040c2b04f78e31f11ac9..41305d9c1f9338267d2e01d906399214a82950f8 100644 (file)
@@ -22,6 +22,7 @@ import org.mockito.MockitoAnnotations;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
 import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
 import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
+import org.opendaylight.controller.md.sal.dom.api.DOMNotification;
 import org.opendaylight.controller.md.sal.dom.api.DOMNotificationService;
 import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
 import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
@@ -46,6 +47,8 @@ public class MountInstanceTest {
     private DOMMountPointService.DOMMountPointBuilder mountPointBuilder;
     @Mock
     private ObjectRegistration<DOMMountPoint> registration;
+    @Mock
+    private DOMNotification notification;
 
     private NetconfDeviceSalProvider.MountInstance mountInstance;
 
@@ -84,7 +87,7 @@ public class MountInstanceTest {
         verify(registration).close();
         try {
             mountInstance.onTopologyDeviceConnected(SCHEMA_CONTEXT, broker, rpcService, notificationService);
-        } catch (IllegalStateException e) {
+        } catch (final IllegalStateException e) {
             e.printStackTrace();
             Assert.fail("Topology registration still present after disconnect ");
         }
@@ -97,4 +100,14 @@ public class MountInstanceTest {
         verify(registration).close();
     }
 
+    @Test
+    public void testPublishNotification() throws Exception {
+        mountInstance.onTopologyDeviceConnected(SCHEMA_CONTEXT, broker, rpcService, notificationService);
+        verify(mountPointBuilder).addInitialSchemaContext(SCHEMA_CONTEXT);
+        verify(mountPointBuilder).addService(DOMNotificationService.class, notificationService);
+        mountInstance.publish(notification);
+        verify(notificationService).publishNotification(notification);
+    }
+
+
 }
\ No newline at end of file
diff --git a/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceSalProviderTest.java b/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceSalProviderTest.java
new file mode 100644 (file)
index 0000000..7fd6b96
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.sal.connect.netconf.sal;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import com.google.common.util.concurrent.Futures;
+import java.net.InetSocketAddress;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
+import org.opendaylight.controller.sal.core.api.Broker;
+import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
+
+public class NetconfDeviceSalProviderTest {
+
+    @Mock
+    private Broker.ProviderSession session;
+    @Mock
+    private DOMMountPointService mountpointService;
+    @Mock
+    private BindingAwareBroker.ProviderContext context;
+    @Mock
+    private WriteTransaction tx;
+    @Mock
+    private DataBroker dataBroker;
+    @Mock
+    private BindingTransactionChain chain;
+    private NetconfDeviceSalProvider provider;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        provider = new NetconfDeviceSalProvider(new RemoteDeviceId("device1", InetSocketAddress.createUnresolved("localhost", 17830)));
+        when(session.getService(DOMMountPointService.class)).thenReturn(mountpointService);
+        when(context.getSALService(DataBroker.class)).thenReturn(dataBroker);
+        when(dataBroker.createTransactionChain(any())).thenReturn(chain);
+        when(chain.newWriteOnlyTransaction()).thenReturn(tx);
+        when(tx.submit()).thenReturn(Futures.immediateCheckedFuture(null));
+        when(tx.getIdentifier()).thenReturn(tx);
+    }
+
+    @Test
+    public void onSessionInitiated() throws Exception {
+        provider.onSessionInitiated(session);
+        provider.onSessionInitiated(context);
+        Assert.assertNotNull(provider.getMountInstance());
+        Assert.assertNotNull(provider.getTopologyDatastoreAdapter());
+    }
+
+    @Test
+    public void getProviderFunctionality() throws Exception {
+        Assert.assertTrue(provider.getProviderFunctionality().isEmpty());
+    }
+
+    @Test
+    public void replaceChainIfFailed() throws Exception {
+        provider.onSessionInitiated(session);
+        provider.onSessionInitiated(context);
+        Assert.assertNotNull(provider.getMountInstance());
+        final ArgumentCaptor<TransactionChainListener> captor = ArgumentCaptor.forClass(TransactionChainListener.class);
+        verify(dataBroker).createTransactionChain(captor.capture());
+        try {
+            captor.getValue().onTransactionChainFailed(chain, tx, new Exception("chain failed"));
+        } catch (final IllegalStateException e) {
+            //expected
+        }
+        verify(dataBroker, times(2)).createTransactionChain(any());
+    }
+
+    @Test
+    public void close() throws Exception {
+        provider.onSessionInitiated(session);
+        provider.onSessionInitiated(context);
+        provider.close();
+        verify(chain).close();
+    }
+
+}
\ No newline at end of file
index 1e9c0fcd86f26a632d0d1ebcb76d10139821c6fd..8d67fbc78a234d57282fab1c1dea6e87b9d9edcd 100644 (file)
@@ -14,9 +14,8 @@ import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 
 import com.google.common.util.concurrent.Futures;
-
 import java.net.InetSocketAddress;
-
+import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mock;
@@ -62,4 +61,24 @@ public class ReadOnlyTxTest {
         readOnlyTx.read(LogicalDatastoreType.OPERATIONAL, path);
         verify(rpc).invokeRpc(Mockito.eq(NetconfMessageTransformUtil.toPath(NetconfMessageTransformUtil.NETCONF_GET_QNAME)), any(NormalizedNode.class));
     }
+
+    @Test
+    public void testExists() throws Exception {
+        final NetconfBaseOps netconfOps = new NetconfBaseOps(rpc, mock(SchemaContext.class));
+
+        final ReadOnlyTx readOnlyTx = new ReadOnlyTx(netconfOps, new RemoteDeviceId("a", new InetSocketAddress("localhost", 196)));
+
+        readOnlyTx.exists(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.create());
+        verify(rpc).invokeRpc(Mockito.eq(NetconfMessageTransformUtil.toPath(NetconfMessageTransformUtil.NETCONF_GET_CONFIG_QNAME)), any(NormalizedNode.class));
+        readOnlyTx.exists(LogicalDatastoreType.OPERATIONAL, path);
+        verify(rpc).invokeRpc(Mockito.eq(NetconfMessageTransformUtil.toPath(NetconfMessageTransformUtil.NETCONF_GET_QNAME)), any(NormalizedNode.class));
+    }
+
+    @Test
+    public void testIdentifier() throws Exception {
+        final NetconfBaseOps netconfOps = new NetconfBaseOps(rpc, mock(SchemaContext.class));
+        final ReadOnlyTx tx1 = new ReadOnlyTx(netconfOps, new RemoteDeviceId("a", new InetSocketAddress("localhost", 196)));
+        final ReadOnlyTx tx2 = new ReadOnlyTx(netconfOps, new RemoteDeviceId("a", new InetSocketAddress("localhost", 196)));
+        Assert.assertNotEquals(tx1.getIdentifier(), tx2.getIdentifier());
+    }
 }
\ No newline at end of file
diff --git a/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/sal/tx/ReadWriteTxTest.java b/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/sal/tx/ReadWriteTxTest.java
new file mode 100644 (file)
index 0000000..748c210
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.sal.connect.netconf.sal.tx;
+
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.Futures;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataReadTransaction;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+public class ReadWriteTxTest {
+    @Mock
+    private DOMDataReadTransaction delegateReadTx;
+    @Mock
+    private DOMDataWriteTransaction delegateWriteTx;
+    private ReadWriteTx tx;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        tx = new ReadWriteTx(delegateReadTx, delegateWriteTx);
+    }
+
+    @Test
+    public void submit() throws Exception {
+        final YangInstanceIdentifier id1 = TxTestUtils.getContainerId();
+        final ContainerNode containerNode = TxTestUtils.getContainerNode();
+        tx.put(LogicalDatastoreType.CONFIGURATION, id1, containerNode);
+        verify(delegateWriteTx).put(LogicalDatastoreType.CONFIGURATION, id1, containerNode);
+        final YangInstanceIdentifier id2 = TxTestUtils.getLeafId();
+        final LeafNode<String> leafNode = TxTestUtils.getLeafNode();
+        tx.merge(LogicalDatastoreType.CONFIGURATION, id2, leafNode);
+        verify(delegateWriteTx).merge(LogicalDatastoreType.CONFIGURATION, id2, leafNode);
+        tx.delete(LogicalDatastoreType.CONFIGURATION, id2);
+        verify(delegateWriteTx).delete(LogicalDatastoreType.CONFIGURATION, id2);
+        tx.submit();
+        verify(delegateWriteTx).submit();
+    }
+
+    @Test
+    public void commit() throws Exception {
+        tx.commit();
+        verify(delegateWriteTx).commit();
+    }
+
+    @Test
+    public void cancel() throws Exception {
+        tx.cancel();
+        verify(delegateWriteTx).cancel();
+    }
+
+    @Test
+    public void read() throws Exception {
+        tx.read(LogicalDatastoreType.CONFIGURATION, TxTestUtils.getContainerId());
+        verify(delegateReadTx).read(LogicalDatastoreType.CONFIGURATION, TxTestUtils.getContainerId());
+    }
+
+    @Test
+    public void exists() throws Exception {
+        final YangInstanceIdentifier id = TxTestUtils.getContainerId();
+        final CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> resultFuture =
+                Futures.immediateCheckedFuture(Optional.of(TxTestUtils.getContainerNode()));
+        when(delegateReadTx.read(LogicalDatastoreType.CONFIGURATION, id)).thenReturn(resultFuture);
+        final CheckedFuture<Boolean, ReadFailedException> exists = tx.exists(LogicalDatastoreType.CONFIGURATION, id);
+        Assert.assertTrue(exists.get());
+    }
+
+    @Test
+    public void getIdentifier() throws Exception {
+        final ReadWriteTx tx2 = new ReadWriteTx(null, null);
+        Assert.assertNotEquals(tx.getIdentifier(), tx2.getIdentifier());
+    }
+
+}
\ No newline at end of file
diff --git a/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/sal/tx/TxTestUtils.java b/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/sal/tx/TxTestUtils.java
new file mode 100644 (file)
index 0000000..4b4481e
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.sal.connect.netconf.sal.tx;
+
+import com.google.common.collect.ImmutableList;
+import java.io.InputStream;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
+import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor;
+import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangInferencePipeline;
+
+class TxTestUtils {
+
+    private static final QName Q_NAME_1 = QName.create("test:namespace", "2013-07-22", "c");
+    private static final QName Q_NAME_2 = QName.create(Q_NAME_1, "a");
+
+    static YangInstanceIdentifier getContainerId() {
+        return YangInstanceIdentifier.builder()
+                .node(Q_NAME_1)
+                .build();
+    }
+
+    static YangInstanceIdentifier getLeafId() {
+        return YangInstanceIdentifier.builder()
+                .node(Q_NAME_1)
+                .node(Q_NAME_2)
+                .build();
+    }
+
+    static ContainerNode getContainerNode() {
+        return Builders.containerBuilder()
+                .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(Q_NAME_1))
+                .build();
+    }
+
+    static LeafNode<String> getLeafNode() {
+        return Builders.<String>leafBuilder()
+                .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(Q_NAME_2))
+                .withValue("data")
+                .build();
+    }
+
+    static SchemaContext parseYangStreams(final InputStream... streams) {
+        final CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR
+                .newBuild();
+        final SchemaContext schemaContext;
+        try {
+            schemaContext = reactor.buildEffective(ImmutableList.copyOf(streams));
+        } catch (final ReactorException e) {
+            throw new RuntimeException("Unable to build schema context from " + streams, e);
+        }
+        return schemaContext;
+    }
+
+}
diff --git a/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/sal/tx/WriteCandidateRunningTxTest.java b/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/sal/tx/WriteCandidateRunningTxTest.java
new file mode 100644 (file)
index 0000000..5f3c986
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.sal.connect.netconf.sal.tx;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.opendaylight.netconf.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_LOCK_QNAME;
+import static org.opendaylight.netconf.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_TARGET_QNAME;
+import static org.opendaylight.netconf.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_UNLOCK_QNAME;
+import static org.opendaylight.netconf.sal.connect.netconf.util.NetconfMessageTransformUtil.toId;
+
+import com.google.common.util.concurrent.Futures;
+import java.net.InetSocketAddress;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
+import org.opendaylight.controller.md.sal.dom.spi.DefaultDOMRpcResult;
+import org.opendaylight.netconf.sal.connect.netconf.util.NetconfBaseOps;
+import org.opendaylight.netconf.sal.connect.netconf.util.NetconfMessageTransformUtil;
+import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.base._1._0.rev110601.copy.config.input.target.ConfigTarget;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+
+public class WriteCandidateRunningTxTest {
+    @Mock
+    private DOMRpcService rpc;
+    private NetconfBaseOps netconfOps;
+    private RemoteDeviceId id;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        final SchemaContext schemaContext = TxTestUtils.parseYangStreams(getClass().getResourceAsStream("/schemas/test-module.yang"));
+        doReturn(Futures.immediateCheckedFuture(new DefaultDOMRpcResult())).when(rpc).invokeRpc(any(), any());
+        netconfOps = new NetconfBaseOps(rpc, schemaContext);
+        id = new RemoteDeviceId("device1", InetSocketAddress.createUnresolved("0.0.0.0", 17830));
+    }
+
+    @Test
+    public void testSubmit() throws Exception {
+        final WriteCandidateRunningTx tx = new WriteCandidateRunningTx(id, netconfOps, true);
+        //check, if lock is called
+        final ContainerNode candidateLock = getLockContent(NETCONF_LOCK_QNAME, NetconfMessageTransformUtil.NETCONF_RUNNING_QNAME);
+        final ContainerNode runningLock = getLockContent(NETCONF_LOCK_QNAME, NetconfMessageTransformUtil.NETCONF_CANDIDATE_QNAME);
+        verify(rpc).invokeRpc(SchemaPath.create(true, NetconfMessageTransformUtil.NETCONF_LOCK_QNAME), runningLock);
+        verify(rpc).invokeRpc(SchemaPath.create(true, NetconfMessageTransformUtil.NETCONF_LOCK_QNAME), candidateLock);
+        tx.put(LogicalDatastoreType.CONFIGURATION, TxTestUtils.getContainerId(), TxTestUtils.getContainerNode());
+        tx.merge(LogicalDatastoreType.CONFIGURATION, TxTestUtils.getLeafId(), TxTestUtils.getLeafNode());
+        //check, if both edits are called
+        verify(rpc, times(2)).invokeRpc(eq(SchemaPath.create(true, NetconfMessageTransformUtil.NETCONF_EDIT_CONFIG_QNAME)), any());
+        tx.submit().get();
+        //check, if unlock is called
+        verify(rpc).invokeRpc(SchemaPath.create(true, NetconfMessageTransformUtil.NETCONF_COMMIT_QNAME), NetconfMessageTransformUtil.COMMIT_RPC_CONTENT);
+        final ContainerNode candidateUnlock = getLockContent(NETCONF_UNLOCK_QNAME, NetconfMessageTransformUtil.NETCONF_RUNNING_QNAME);
+        final ContainerNode runningUnlock = getLockContent(NETCONF_UNLOCK_QNAME, NetconfMessageTransformUtil.NETCONF_CANDIDATE_QNAME);
+        verify(rpc).invokeRpc(SchemaPath.create(true, NETCONF_UNLOCK_QNAME), candidateUnlock);
+        verify(rpc).invokeRpc(SchemaPath.create(true, NETCONF_UNLOCK_QNAME), runningUnlock);
+    }
+
+    private static ContainerNode getLockContent(final QName op, final QName datastore) {
+        final LeafNode<Object> datastoreLeaf = Builders.leafBuilder().withNodeIdentifier(toId(datastore)).build();
+        final ChoiceNode choice = Builders.choiceBuilder()
+                .withNodeIdentifier(toId(ConfigTarget.QNAME))
+                .withChild(datastoreLeaf)
+                .build();
+        final ContainerNode target = Builders.containerBuilder()
+                .withNodeIdentifier(toId(NETCONF_TARGET_QNAME))
+                .withChild(choice).build();
+        return Builders.containerBuilder()
+                .withNodeIdentifier(toId(op))
+                .withChild(target)
+                .build();
+    }
+
+}
\ No newline at end of file
diff --git a/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/sal/tx/WriteCandidateTxTest.java b/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/sal/tx/WriteCandidateTxTest.java
new file mode 100644 (file)
index 0000000..3214505
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.sal.connect.netconf.sal.tx;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import com.google.common.util.concurrent.Futures;
+import java.net.InetSocketAddress;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
+import org.opendaylight.controller.md.sal.dom.spi.DefaultDOMRpcResult;
+import org.opendaylight.netconf.sal.connect.netconf.util.NetconfBaseOps;
+import org.opendaylight.netconf.sal.connect.netconf.util.NetconfMessageTransformUtil;
+import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+
+public class WriteCandidateTxTest {
+
+    @Mock
+    private DOMRpcService rpc;
+    private NetconfBaseOps netconfOps;
+    private RemoteDeviceId id;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        final SchemaContext schemaContext = TxTestUtils.parseYangStreams(getClass().getResourceAsStream("/schemas/test-module.yang"));
+        doReturn(Futures.immediateCheckedFuture(new DefaultDOMRpcResult())).when(rpc).invokeRpc(any(), any());
+        netconfOps = new NetconfBaseOps(rpc, schemaContext);
+        id = new RemoteDeviceId("device1", InetSocketAddress.createUnresolved("0.0.0.0", 17830));
+    }
+
+    @Test
+    public void testSubmit() throws Exception {
+        final WriteCandidateTx tx = new WriteCandidateTx(id, netconfOps, true);
+        //check, if lock is called
+        verify(rpc).invokeRpc(eq(SchemaPath.create(true, NetconfMessageTransformUtil.NETCONF_LOCK_QNAME)), any());
+
+        tx.put(LogicalDatastoreType.CONFIGURATION, TxTestUtils.getContainerId(), TxTestUtils.getContainerNode());
+        tx.merge(LogicalDatastoreType.CONFIGURATION, TxTestUtils.getLeafId(), TxTestUtils.getLeafNode());
+        //check, if both edits are called
+        verify(rpc, times(2)).invokeRpc(eq(SchemaPath.create(true, NetconfMessageTransformUtil.NETCONF_EDIT_CONFIG_QNAME)), any());
+        tx.submit().get();
+        //check, if unlock is called
+        verify(rpc).invokeRpc(SchemaPath.create(true, NetconfMessageTransformUtil.NETCONF_COMMIT_QNAME), NetconfMessageTransformUtil.COMMIT_RPC_CONTENT);
+        verify(rpc).invokeRpc(eq(SchemaPath.create(true, NetconfMessageTransformUtil.NETCONF_UNLOCK_QNAME)), any());
+    }
+
+}
\ No newline at end of file
index 67e390410b71e4f2fc194ed0833011a6269c6f10..9668bb158a793641d44f5b76ac1e494b0f53f768 100644 (file)
@@ -15,9 +15,7 @@ import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
-import com.google.common.collect.ImmutableList;
 import com.google.common.util.concurrent.Futures;
-import java.io.InputStream;
 import java.net.InetSocketAddress;
 import org.junit.Before;
 import org.junit.Test;
@@ -29,16 +27,8 @@ import org.opendaylight.controller.md.sal.dom.spi.DefaultDOMRpcResult;
 import org.opendaylight.netconf.sal.connect.netconf.util.NetconfBaseOps;
 import org.opendaylight.netconf.sal.connect.netconf.util.NetconfMessageTransformUtil;
 import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
-import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
-import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor;
-import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangInferencePipeline;
 
 public class WriteRunningTxTest {
 
@@ -50,7 +40,7 @@ public class WriteRunningTxTest {
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
-        final SchemaContext schemaContext = parseYangStreams(getClass().getResourceAsStream("/schemas/test-module.yang"));
+        final SchemaContext schemaContext = TxTestUtils.parseYangStreams(getClass().getResourceAsStream("/schemas/test-module.yang"));
         doReturn(Futures.immediateCheckedFuture(new DefaultDOMRpcResult())).when(rpc).invokeRpc(any(), any());
         netconfOps = new NetconfBaseOps(rpc, schemaContext);
         id = new RemoteDeviceId("device1", InetSocketAddress.createUnresolved("0.0.0.0", 17830));
@@ -61,24 +51,8 @@ public class WriteRunningTxTest {
         final WriteRunningTx tx = new WriteRunningTx(id, netconfOps, true);
         //check, if lock is called
         verify(rpc).invokeRpc(eq(SchemaPath.create(true, NetconfMessageTransformUtil.NETCONF_LOCK_QNAME)), any());
-        final QName qName1 = QName.create("test:namespace", "2013-07-22", "c");
-        final YangInstanceIdentifier yid1 = YangInstanceIdentifier.builder()
-                .node(qName1)
-                .build();
-        final QName qName2 = QName.create(qName1, "a");
-        final YangInstanceIdentifier yid2 = YangInstanceIdentifier.builder()
-                .node(qName1)
-                .node(qName2)
-                .build();
-        final ContainerNode data1 = Builders.containerBuilder()
-                .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(qName1))
-                .build();
-        final LeafNode<String> data2 = Builders.<String>leafBuilder()
-                .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(qName2))
-                .withValue("data")
-                .build();
-        tx.put(LogicalDatastoreType.CONFIGURATION, yid1, data1);
-        tx.merge(LogicalDatastoreType.CONFIGURATION, yid2, data2);
+        tx.put(LogicalDatastoreType.CONFIGURATION, TxTestUtils.getContainerId(), TxTestUtils.getContainerNode());
+        tx.merge(LogicalDatastoreType.CONFIGURATION, TxTestUtils.getLeafId(), TxTestUtils.getLeafNode());
         //check, if no edit-config is called before submit
         verify(rpc, never()).invokeRpc(eq(SchemaPath.create(true, NetconfMessageTransformUtil.NETCONF_EDIT_CONFIG_QNAME)), any());
         tx.submit().get();
@@ -87,16 +61,4 @@ public class WriteRunningTxTest {
         //check, if unlock is called
         verify(rpc).invokeRpc(eq(SchemaPath.create(true, NetconfMessageTransformUtil.NETCONF_UNLOCK_QNAME)), any());
     }
-
-    private static SchemaContext parseYangStreams(final InputStream... streams) {
-        final CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR
-                .newBuild();
-        final SchemaContext schemaContext;
-        try {
-            schemaContext = reactor.buildEffective(ImmutableList.copyOf(streams));
-        } catch (final ReactorException e) {
-            throw new RuntimeException("Unable to build schema context from " + streams, e);
-        }
-        return schemaContext;
-    }
 }
\ No newline at end of file
diff --git a/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/util/NetconfBaseOpsTest.java b/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/util/NetconfBaseOpsTest.java
new file mode 100644 (file)
index 0000000..6b47a72
--- /dev/null
@@ -0,0 +1,330 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.sal.connect.netconf.util;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.argThat;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import com.google.common.base.Optional;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.InetSocketAddress;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import org.custommonkey.xmlunit.Diff;
+import org.custommonkey.xmlunit.XMLUnit;
+import org.hamcrest.BaseMatcher;
+import org.hamcrest.Description;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
+import org.opendaylight.netconf.api.NetconfMessage;
+import org.opendaylight.netconf.sal.connect.api.MessageTransformer;
+import org.opendaylight.netconf.sal.connect.api.RemoteDeviceCommunicator;
+import org.opendaylight.netconf.sal.connect.netconf.sal.NetconfDeviceRpc;
+import org.opendaylight.netconf.sal.connect.netconf.schema.mapping.NetconfMessageTransformer;
+import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+import org.opendaylight.yangtools.yang.data.api.ModifyAction;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
+import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor;
+import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangInferencePipeline;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.xml.sax.SAXException;
+
+public class NetconfBaseOpsTest {
+
+    static {
+        XMLUnit.setIgnoreWhitespace(true);
+        XMLUnit.setIgnoreComments(true);
+    }
+
+    private static final QName CONTAINER_Q_NAME = QName.create("test:namespace", "2013-07-22", "c");
+
+    @Mock
+    private RemoteDeviceCommunicator<NetconfMessage> listener;
+    private NetconfRpcFutureCallback callback;
+    private NetconfBaseOps baseOps;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        final InputStream okStream = getClass().getResourceAsStream("/netconfMessages/rpc-reply_ok.xml");
+        final InputStream dataStream = getClass().getResourceAsStream("/netconfMessages/rpc-reply_get.xml");
+        final NetconfMessage ok = new NetconfMessage(XmlUtil.readXmlToDocument(okStream));
+        final NetconfMessage data = new NetconfMessage(XmlUtil.readXmlToDocument(dataStream));
+        when(listener.sendRequest(any(), eq(NetconfMessageTransformUtil.NETCONF_GET_CONFIG_QNAME)))
+                .thenReturn(RpcResultBuilder.success(data).buildFuture());
+        when(listener.sendRequest(any(), eq(NetconfMessageTransformUtil.NETCONF_GET_QNAME)))
+                .thenReturn(RpcResultBuilder.success(data).buildFuture());
+        when(listener.sendRequest(any(), eq(NetconfMessageTransformUtil.NETCONF_EDIT_CONFIG_QNAME)))
+                .thenReturn(RpcResultBuilder.success(ok).buildFuture());
+        when(listener.sendRequest(any(), eq(NetconfMessageTransformUtil.NETCONF_COPY_CONFIG_QNAME)))
+                .thenReturn(RpcResultBuilder.success(ok).buildFuture());
+        when(listener.sendRequest(any(), eq(NetconfMessageTransformUtil.NETCONF_DISCARD_CHANGES_QNAME)))
+                .thenReturn(RpcResultBuilder.success(ok).buildFuture());
+        when(listener.sendRequest(any(), eq(NetconfMessageTransformUtil.NETCONF_VALIDATE_QNAME)))
+                .thenReturn(RpcResultBuilder.success(ok).buildFuture());
+        when(listener.sendRequest(any(), eq(NetconfMessageTransformUtil.NETCONF_LOCK_QNAME)))
+                .thenReturn(RpcResultBuilder.success(ok).buildFuture());
+        when(listener.sendRequest(any(), eq(NetconfMessageTransformUtil.NETCONF_UNLOCK_QNAME)))
+                .thenReturn(RpcResultBuilder.success(ok).buildFuture());
+        when(listener.sendRequest(any(), eq(NetconfMessageTransformUtil.NETCONF_COMMIT_QNAME)))
+                .thenReturn(RpcResultBuilder.success(ok).buildFuture());
+        final SchemaContext schemaContext =
+                parseYangStreams(getClass().getResourceAsStream("/schemas/test-module.yang"));
+        final MessageTransformer<NetconfMessage> transformer = new NetconfMessageTransformer(schemaContext, true);
+        final DOMRpcService rpc = new NetconfDeviceRpc(schemaContext, listener, transformer);
+        final RemoteDeviceId id =
+                new RemoteDeviceId("device-1", InetSocketAddress.createUnresolved("localhost", 17830));
+        callback = new NetconfRpcFutureCallback("prefix", id);
+        baseOps = new NetconfBaseOps(rpc, schemaContext);
+    }
+
+    @Test
+    public void testLock() throws Exception {
+        baseOps.lock(callback, NetconfMessageTransformUtil.NETCONF_CANDIDATE_QNAME);
+        verifyMessageSent("lock", NetconfMessageTransformUtil.NETCONF_LOCK_QNAME);
+    }
+
+    @Test
+    public void testLockCandidate() throws Exception {
+        baseOps.lockCandidate(callback);
+        verifyMessageSent("lock", NetconfMessageTransformUtil.NETCONF_LOCK_QNAME);
+    }
+
+    @Test
+    public void testUnlock() throws Exception {
+        baseOps.unlock(callback, NetconfMessageTransformUtil.NETCONF_CANDIDATE_QNAME);
+        verifyMessageSent("unlock", NetconfMessageTransformUtil.NETCONF_UNLOCK_QNAME);
+    }
+
+    @Test
+    public void testUnlockCandidate() throws Exception {
+        baseOps.unlockCandidate(callback);
+        verifyMessageSent("unlock", NetconfMessageTransformUtil.NETCONF_UNLOCK_QNAME);
+    }
+
+    @Test
+    public void testLockRunning() throws Exception {
+        baseOps.lockRunning(callback);
+        verifyMessageSent("lock-running", NetconfMessageTransformUtil.NETCONF_LOCK_QNAME);
+    }
+
+    @Test
+    public void testUnlockRunning() throws Exception {
+        baseOps.unlockRunning(callback);
+        verifyMessageSent("unlock-running", NetconfMessageTransformUtil.NETCONF_UNLOCK_QNAME);
+    }
+
+    @Test
+    public void testDiscardChanges() throws Exception {
+        baseOps.discardChanges(callback);
+        verifyMessageSent("discardChanges", NetconfMessageTransformUtil.NETCONF_DISCARD_CHANGES_QNAME);
+    }
+
+    @Test
+    public void testCommit() throws Exception {
+        baseOps.commit(callback);
+        verifyMessageSent("commit", NetconfMessageTransformUtil.NETCONF_COMMIT_QNAME);
+    }
+
+    @Test
+    public void testValidateCandidate() throws Exception {
+        baseOps.validateCandidate(callback);
+        verifyMessageSent("validate", NetconfMessageTransformUtil.NETCONF_VALIDATE_QNAME);
+    }
+
+    @Test
+    public void testValidateRunning() throws Exception {
+        baseOps.validateRunning(callback);
+        verifyMessageSent("validate-running", NetconfMessageTransformUtil.NETCONF_VALIDATE_QNAME);
+    }
+
+
+    @Test
+    public void testCopyConfig() throws Exception {
+        baseOps.copyConfig(callback, NetconfMessageTransformUtil.NETCONF_RUNNING_QNAME,
+                NetconfMessageTransformUtil.NETCONF_CANDIDATE_QNAME);
+        verifyMessageSent("copy-config", NetconfMessageTransformUtil.NETCONF_COPY_CONFIG_QNAME);
+    }
+
+    @Test
+    public void testCopyRunningToCandidate() throws Exception {
+        baseOps.copyRunningToCandidate(callback);
+        verifyMessageSent("copy-config", NetconfMessageTransformUtil.NETCONF_COPY_CONFIG_QNAME);
+    }
+
+
+    @Test
+    public void testGetConfigRunningData() throws Exception {
+        final Optional<NormalizedNode<?, ?>> dataOpt =
+                baseOps.getConfigRunningData(callback, Optional.of(YangInstanceIdentifier.EMPTY)).get();
+        Assert.assertTrue(dataOpt.isPresent());
+        Assert.assertEquals(NetconfMessageTransformUtil.NETCONF_DATA_QNAME, dataOpt.get().getNodeType());
+    }
+
+    @Test
+    public void testGetData() throws Exception {
+        final Optional<NormalizedNode<?, ?>> dataOpt =
+                baseOps.getData(callback, Optional.of(YangInstanceIdentifier.EMPTY)).get();
+        Assert.assertTrue(dataOpt.isPresent());
+        Assert.assertEquals(NetconfMessageTransformUtil.NETCONF_DATA_QNAME, dataOpt.get().getNodeType());
+    }
+
+    @Test
+    public void testGetConfigRunning() throws Exception {
+        baseOps.getConfigRunning(callback, Optional.absent());
+        verifyMessageSent("getConfig", NetconfMessageTransformUtil.NETCONF_GET_CONFIG_QNAME);
+    }
+
+    @Test
+    public void testGetConfigCandidate() throws Exception {
+        baseOps.getConfigCandidate(callback, Optional.absent());
+        verifyMessageSent("getConfig_candidate", NetconfMessageTransformUtil.NETCONF_GET_CONFIG_QNAME);
+    }
+
+    @Test
+    public void testGetConfigCandidateWithFilter() throws Exception {
+        final YangInstanceIdentifier id = YangInstanceIdentifier.builder()
+                .node(CONTAINER_Q_NAME)
+                .build();
+        baseOps.getConfigCandidate(callback, Optional.of(id));
+        verifyMessageSent("getConfig_candidate-filter", NetconfMessageTransformUtil.NETCONF_GET_CONFIG_QNAME);
+    }
+
+    @Test
+    public void testGet() throws Exception {
+        baseOps.get(callback, Optional.absent());
+        verifyMessageSent("get", NetconfMessageTransformUtil.NETCONF_GET_QNAME);
+    }
+
+    @Test
+    public void testEditConfigCandidate() throws Exception {
+        final QName leafQName = QName.create(CONTAINER_Q_NAME, "a");
+        final LeafNode<Object> leaf = Builders.leafBuilder()
+                .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(leafQName))
+                .withValue("leaf-value")
+                .build();
+        final YangInstanceIdentifier leafId = YangInstanceIdentifier.builder()
+                .node(CONTAINER_Q_NAME)
+                .node(leafQName)
+                .build();
+        final DataContainerChild<?, ?> structure = baseOps.createEditConfigStrcture(Optional.of(leaf),
+                Optional.of(ModifyAction.REPLACE), leafId);
+        baseOps.editConfigCandidate(callback, structure, true);
+        verifyMessageSent("edit-config-test-module", NetconfMessageTransformUtil.NETCONF_EDIT_CONFIG_QNAME);
+    }
+
+    @Test
+    public void testEditConfigRunning() throws Exception {
+        final QName containerQName = QName.create("test:namespace", "2013-07-22", "c");
+        final QName leafQName = QName.create(containerQName, "a");
+        final LeafNode<Object> leaf = Builders.leafBuilder()
+                .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(leafQName))
+                .withValue("leaf-value")
+                .build();
+        final YangInstanceIdentifier leafId = YangInstanceIdentifier.builder()
+                .node(containerQName)
+                .node(leafQName)
+                .build();
+        final DataContainerChild<?, ?> structure = baseOps.createEditConfigStrcture(Optional.of(leaf),
+                Optional.of(ModifyAction.REPLACE), leafId);
+        baseOps.editConfigRunning(callback, structure, ModifyAction.MERGE, true);
+        verifyMessageSent("edit-config-test-module-running", NetconfMessageTransformUtil.NETCONF_EDIT_CONFIG_QNAME);
+    }
+
+    private static SchemaContext parseYangStreams(final InputStream... streams) {
+        final CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR
+                .newBuild();
+        final SchemaContext schemaContext;
+        try {
+            schemaContext = reactor.buildEffective(Arrays.asList(streams));
+        } catch (final ReactorException e) {
+            throw new RuntimeException("Unable to build schema context from " + streams, e);
+        }
+        return schemaContext;
+    }
+
+    private void verifyMessageSent(final String fileName, final QName name) {
+        final String path = "/netconfMessages/" + fileName + ".xml";
+        verify(listener).sendRequest(msg(path), eq(name));
+    }
+
+    private static NetconfMessage msg(final String name) {
+        final InputStream stream = NetconfBaseOpsTest.class.getResourceAsStream(name);
+        try {
+            return argThat(new NetconfMessageMatcher(XmlUtil.readXmlToDocument(stream)));
+        } catch (SAXException | IOException e) {
+            throw new IllegalStateException("Failed to read xml file " + name, e);
+        }
+    }
+
+    private static class NetconfMessageMatcher extends BaseMatcher<NetconfMessage> {
+
+        private final Document expected;
+
+        private NetconfMessageMatcher(final Document expected) {
+            this.expected = removeAttrs(expected);
+        }
+
+        @Override
+        public boolean matches(final Object item) {
+            if (!(item instanceof NetconfMessage)) {
+                return false;
+            }
+            final NetconfMessage message = (NetconfMessage) item;
+            final Document actualDoc = removeAttrs(message.getDocument());
+            actualDoc.normalizeDocument();
+            expected.normalizeDocument();
+            final Diff diff = XMLUnit.compareXML(expected, actualDoc);
+            return diff.similar();
+        }
+
+        @Override
+        public void describeTo(final Description description) {
+            description.appendText(XmlUtil.toString(expected));
+        }
+
+        private static Document removeAttrs(final Document input) {
+            final Document copy = XmlUtil.newDocument();
+            copy.appendChild(copy.importNode(input.getDocumentElement(), true));
+            final Element element = copy.getDocumentElement();
+            final List<String> attrNames = new ArrayList<>();
+            final NamedNodeMap attributes = element.getAttributes();
+            for (int i = 0; i < attributes.getLength(); i++) {
+                final String nodeName = attributes.item(i).getNodeName();
+                if ("xmlns".equals(nodeName)) {
+                    continue;
+                }
+                attrNames.add(nodeName);
+            }
+            attrNames.forEach(element::removeAttribute);
+            return copy;
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/util/NodeContainerProxyTest.java b/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/util/NodeContainerProxyTest.java
new file mode 100644 (file)
index 0000000..534a952
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.sal.connect.netconf.util;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+
+public class NodeContainerProxyTest {
+
+    private static final QName QNAME = QName.create("ns", "2016-10-19", "name");
+    private static final QName NODE_1_QNAME = QName.create(QNAME, "node-1");
+    private static final QName NODE_2_QNAME = QName.create(QNAME, "node-2");
+    @Mock
+    private AugmentationSchema augSchema1;
+    @Mock
+    private AugmentationSchema augSchema2;
+    @Mock
+    private DataSchemaNode schemaNode1;
+    @Mock
+    private DataSchemaNode schemaNode2;
+    private NodeContainerProxy proxy;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        final Map<QName, DataSchemaNode> childNodes = new HashMap<>();
+        childNodes.put(NODE_1_QNAME, schemaNode1);
+        childNodes.put(NODE_2_QNAME, schemaNode2);
+        final Set<AugmentationSchema> augmentations = new HashSet<>();
+        augmentations.add(augSchema1);
+        augmentations.add(augSchema2);
+        proxy = new NodeContainerProxy(QNAME, childNodes, augmentations);
+    }
+
+    @Test
+    public void testGetQName() throws Exception {
+        Assert.assertEquals(QNAME, proxy.getQName());
+    }
+
+    @Test
+    public void testGetChildNodes() throws Exception {
+        Assert.assertEquals(2, proxy.getChildNodes().size());
+    }
+
+    @Test
+    public void testGetAvailableAugmentations() throws Exception {
+        final Set<AugmentationSchema> augmentations = proxy.getAvailableAugmentations();
+        Assert.assertEquals(2, augmentations.size());
+        Assert.assertTrue(augmentations.contains(augSchema1));
+        Assert.assertTrue(augmentations.contains(augSchema2));
+    }
+
+    @Test
+    public void testGetDataChildByName() throws Exception {
+        final DataSchemaNode schemaNode = proxy.getDataChildByName(NODE_1_QNAME);
+        Assert.assertEquals(schemaNode1, schemaNode);
+    }
+
+    @Test
+    public void testGetTypeDefinitions() throws Exception {
+        Assert.assertTrue(proxy.getTypeDefinitions().isEmpty());
+    }
+
+    @Test
+    public void testGetGroupings() throws Exception {
+        Assert.assertTrue(proxy.getGroupings().isEmpty());
+    }
+
+    @Test
+    public void testGetUses() throws Exception {
+        Assert.assertTrue(proxy.getUses().isEmpty());
+    }
+
+    @Test
+    public void testGetUnknownSchemaNodes() throws Exception {
+        Assert.assertTrue(proxy.getUnknownSchemaNodes().isEmpty());
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testIsPresenceContainer() throws Exception {
+        proxy.isPresenceContainer();
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testIsAugmenting() throws Exception {
+        proxy.isAugmenting();
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testIsAddedByUses() throws Exception {
+        proxy.isAddedByUses();
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testIsConfiguration() throws Exception {
+        proxy.isConfiguration();
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testGetConstraints() throws Exception {
+        proxy.getConstraints();
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testGetPath() throws Exception {
+        proxy.getPath();
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testGetDescription() throws Exception {
+        proxy.getDescription();
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testGetReference() throws Exception {
+        proxy.getReference();
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testGetStatus() throws Exception {
+        proxy.getStatus();
+    }
+
+}
\ No newline at end of file
index 62b88b974f2091e575b6a4f70b59ad4b1b7b1e55..81fe494e615508101e482caa97e69f55c2f6ad96 100644 (file)
@@ -162,8 +162,16 @@ module netconf-node-topology {
 
         container available-capabilities {
             config false;
-            leaf-list available-capability {
-                type string;
+            list available-capability {
+                leaf capability {
+                    type string;
+                }
+                leaf capability-origin {
+                    type enumeration {
+                        enum user-defined;
+                        enum device-advertised;
+                    }
+                }
             }
         }
 
@@ -240,4 +248,4 @@ module netconf-node-topology {
 
         uses netconf-node-fields;
     }
-}
+}
\ No newline at end of file
index b8033bbacebfc487d26ad4009d3951cafe02b881..9857c4493ff68d25d6c6b6acb91d08a11125a4b1 100644 (file)
@@ -163,7 +163,7 @@ class ModuleImpl implements Module {
 
     @Override
     public Set<Module> getSubmodules() {
-        throw new UnsupportedOperationException("Not supported operations.");
+        return new HashSet<>();
     }
 
     @Override
index fc9c676c4ea36a4bcaeb60bd591765d019a57813..f0958d79e9345a77d1ec25756802d57c26ef0b34 100644 (file)
@@ -17,20 +17,10 @@ import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFaile
 import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
 import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
 import org.opendaylight.netconf.sal.restconf.impl.NormalizedNodeContext;
-import org.opendaylight.netconf.sal.restconf.impl.RestconfDocumentedException;
-import org.opendaylight.netconf.sal.restconf.impl.RestconfError;
-import org.opendaylight.restconf.RestConnectorProvider;
 import org.opendaylight.restconf.common.references.SchemaContextRef;
 import org.opendaylight.restconf.restful.transaction.TransactionVarsWrapper;
 import org.opendaylight.restconf.utils.parser.ParserIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
-import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
@@ -93,64 +83,35 @@ public final class PostDataTransactionUtil {
             final SchemaContext schemaContext) {
         final DOMTransactionChain transactionChain = transactionNode.getTransactionChain();
         final DOMDataReadWriteTransaction transaction = transactionChain.newReadWriteTransaction();
-        final NormalizedNode<?, ?> node = ImmutableNodes.fromInstanceId(schemaContext, path);
-        transaction.put(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.create(node.getIdentifier()), node);
-        TransactionUtil.ensureParentsByMerge(path, schemaContext, transaction);
 
         if (data instanceof MapNode) {
+            boolean merge = false;
             for (final MapEntryNode child : ((MapNode) data).getValue()) {
-                putChild(child, transactionChain, transaction, path);
-            }
-        } else if (data instanceof AugmentationNode) {
-            for (final DataContainerChild<? extends PathArgument, ?> child : ((AugmentationNode) data).getValue()) {
-                putChild(child, transactionChain, transaction, path);
-            }
-        } else if (data instanceof ChoiceNode) {
-            for (final DataContainerChild<? extends PathArgument, ?> child : ((ChoiceNode) data).getValue()) {
-                putChild(child, transactionChain, transaction, path);
-            }
-        } else if (data instanceof LeafSetNode<?>) {
-            for (final LeafSetEntryNode<?> child : ((LeafSetNode<?>) data).getValue()) {
-                putChild(child, transactionChain, transaction, path);
-            }
-        } else if (data instanceof ContainerNode) {
-            for (final DataContainerChild<? extends PathArgument, ?> child : ((ContainerNode) data).getValue()) {
-                putChild(child, transactionChain, transaction, path);
+                final YangInstanceIdentifier childPath = path.node(child.getIdentifier());
+                TransactionUtil.checkItemDoesNotExists(
+                        transactionChain, transaction, LogicalDatastoreType.CONFIGURATION, childPath,
+                        RestconfDataServiceConstant.PostData.POST_TX_TYPE);
+                if (!merge) {
+                    merge = true;
+                    TransactionUtil.ensureParentsByMerge(path, schemaContext, transaction);
+                    final NormalizedNode<?, ?> emptySubTree = ImmutableNodes.fromInstanceId(schemaContext, path);
+                    transaction.merge(LogicalDatastoreType.CONFIGURATION,
+                            YangInstanceIdentifier.create(emptySubTree.getIdentifier()), emptySubTree);
+                }
+                transaction.put(LogicalDatastoreType.CONFIGURATION, childPath, child);
             }
         } else {
-            transaction.cancel();
-            RestConnectorProvider.resetTransactionChainForAdapaters(transactionChain);
+            TransactionUtil.checkItemDoesNotExists(
+                    transactionChain, transaction, LogicalDatastoreType.CONFIGURATION, path,
+                    RestconfDataServiceConstant.PostData.POST_TX_TYPE);
 
-            final String errMsg = "Only Map, Choice, Augmentation, LeafSet and Container nodes are supported";
-            LOG.trace("{}:{}", errMsg, path);
-            throw new RestconfDocumentedException(
-                    "Node not supported", RestconfError.ErrorType.PROTOCOL, RestconfError.ErrorTag.BAD_ELEMENT, path);
+            TransactionUtil.ensureParentsByMerge(path, schemaContext, transaction);
+            transaction.put(LogicalDatastoreType.CONFIGURATION, path, data);
         }
 
         return transaction.submit();
     }
 
-    /**
-     * Prepare data for submit
-     *
-     * @param child
-     *            - data
-     * @param transactionChain
-     *            - transaction chain
-     * @param readWriteTx
-     *            - transaction
-     * @param path
-     *            - path to data
-     */
-    private static void putChild(final NormalizedNode<?, ?> child, final DOMTransactionChain transactionChain,
-                                 final DOMDataReadWriteTransaction readWriteTx, final YangInstanceIdentifier path) {
-        final YangInstanceIdentifier childPath = path.node(child.getIdentifier());
-        TransactionUtil.checkItemDoesNotExists(
-                transactionChain, readWriteTx, LogicalDatastoreType.CONFIGURATION, childPath,
-                RestconfDataServiceConstant.PostData.POST_TX_TYPE);
-        readWriteTx.put(LogicalDatastoreType.CONFIGURATION, childPath, child);
-    }
-
     /**
      * Get location from {@link YangInstanceIdentifier} and {@link UriInfo}
      *
index 51270bc51b220858dd629739c2ef4724f3268e9d..a86d9ce7a84a23d26aa0a91e5a0ad60aeef849b2 100644 (file)
@@ -12,7 +12,7 @@ import static org.junit.Assert.assertEquals;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.verify;
-import com.google.common.base.Optional;
+
 import com.google.common.util.concurrent.Futures;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriBuilder;
@@ -38,7 +38,6 @@ import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
 import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
@@ -125,7 +124,7 @@ public class PostDataTransactionUtilTest {
         final InstanceIdentifierContext<? extends SchemaNode> iidContext = new InstanceIdentifierContext<>(this.iid2, null, null, this.schema);
         final NormalizedNodeContext payload = new NormalizedNodeContext(iidContext, this.buildBaseCont);
 
-        doReturn(Futures.immediateCheckedFuture(Optional.absent())).when(this.read).read(LogicalDatastoreType.CONFIGURATION, this.iid2);
+        doReturn(Futures.immediateCheckedFuture(false)).when(this.readWrite).exists(LogicalDatastoreType.CONFIGURATION, this.iid2);
         final YangInstanceIdentifier.NodeIdentifier identifier = ((ContainerNode) ((SingletonSet) payload.getData().getValue()).iterator().next()).getIdentifier();
         final YangInstanceIdentifier node = payload.getInstanceIdentifierContext().getInstanceIdentifier().node(identifier);
         doReturn(Futures.immediateCheckedFuture(false)).when(this.readWrite).exists(LogicalDatastoreType.CONFIGURATION, node);
@@ -134,8 +133,8 @@ public class PostDataTransactionUtilTest {
         final TransactionVarsWrapper wrapper = new TransactionVarsWrapper(payload.getInstanceIdentifierContext(), null, this.transactionChain);
         final Response response = PostDataTransactionUtil.postData(this.uriInfo, payload, wrapper, this.refSchemaCtx);
         assertEquals(201, response.getStatus());
-        verify(this.readWrite).exists(LogicalDatastoreType.CONFIGURATION, node);
-        verify(this.readWrite).put(LogicalDatastoreType.CONFIGURATION, node, (NormalizedNode<?, ?>) ((SingletonSet) payload.getData().getValue()).iterator().next());
+        verify(this.readWrite).exists(LogicalDatastoreType.CONFIGURATION, this.iid2);
+        verify(this.readWrite).put(LogicalDatastoreType.CONFIGURATION, payload.getInstanceIdentifierContext().getInstanceIdentifier(), payload.getData());
     }
 
     @Test
@@ -143,7 +142,6 @@ public class PostDataTransactionUtilTest {
         final InstanceIdentifierContext<? extends SchemaNode> iidContext = new InstanceIdentifierContext<>(this.iid2, null, null, this.schema);
         final NormalizedNodeContext payload = new NormalizedNodeContext(iidContext, this.buildList);
 
-        doReturn(Futures.immediateCheckedFuture(Optional.absent())).when(this.read).read(LogicalDatastoreType.CONFIGURATION, this.iid2);
         final MapNode data = (MapNode) payload.getData();
         final YangInstanceIdentifier.NodeIdentifierWithPredicates identifier = data.getValue().iterator().next().getIdentifier();
         final YangInstanceIdentifier node = payload.getInstanceIdentifierContext().getInstanceIdentifier().node(identifier);
@@ -162,7 +160,7 @@ public class PostDataTransactionUtilTest {
         final InstanceIdentifierContext<? extends SchemaNode> iidContext = new InstanceIdentifierContext<>(this.iid2, null, null, this.schema);
         final NormalizedNodeContext payload = new NormalizedNodeContext(iidContext, this.buildBaseCont);
 
-        doReturn(Futures.immediateCheckedFuture(Optional.absent())).when(this.read).read(LogicalDatastoreType.CONFIGURATION, this.iid2);
+        doReturn(Futures.immediateCheckedFuture(false)).when(this.readWrite).exists(LogicalDatastoreType.CONFIGURATION, this.iid2);
         final YangInstanceIdentifier.NodeIdentifier identifier = ((ContainerNode) ((SingletonSet) payload.getData().getValue()).iterator().next()).getIdentifier();
         final YangInstanceIdentifier node = payload.getInstanceIdentifierContext().getInstanceIdentifier().node(identifier);
         doReturn(Futures.immediateCheckedFuture(false)).when(this.readWrite).exists(LogicalDatastoreType.CONFIGURATION, node);
@@ -172,8 +170,8 @@ public class PostDataTransactionUtilTest {
         final TransactionVarsWrapper wrapper = new TransactionVarsWrapper(payload.getInstanceIdentifierContext(), null, this.transactionChain);
         final Response response = PostDataTransactionUtil.postData(this.uriInfo, payload, wrapper, this.refSchemaCtx);
         assertEquals(Response.Status.INTERNAL_SERVER_ERROR, response.getStatusInfo());
-        verify(this.readWrite).exists(LogicalDatastoreType.CONFIGURATION, node);
-        verify(this.readWrite).put(LogicalDatastoreType.CONFIGURATION, node, (NormalizedNode<?, ?>) ((SingletonSet) payload.getData().getValue()).iterator().next());
+        verify(this.readWrite).exists(LogicalDatastoreType.CONFIGURATION, iid2);
+        verify(this.readWrite).put(LogicalDatastoreType.CONFIGURATION, payload.getInstanceIdentifierContext().getInstanceIdentifier(), payload.getData());
     }
 
 }