Decouple config and netconf subsystems.
authorTomas Cere <tcere@cisco.com>
Thu, 13 Aug 2015 09:06:54 +0000 (11:06 +0200)
committerTomas Cere <tcere@cisco.com>
Thu, 13 Aug 2015 09:06:54 +0000 (11:06 +0200)
Extract a common mapping for config pusher and config subsystem netconf
Add a ConfigPersisterFacade for XML that allows reads/writes from/to config
subsystem using XML format
Push notifications from YangStoreService to NetconfNotificationManager instead
of using custom listeners
Migrate netconf features from controller features, untangle features

Change-Id: I71e4ca6e0258e0b1f0d6c19119f93eb9d68b7bca
Signed-off-by: Tomas Cere <tcere@cisco.com>
Signed-off-by: Maros Marsalek <mmarsale@cisco.com>
Signed-off-by: Ed Warnicke <hagbard@gmail.com>
446 files changed:
opendaylight/netconf/config-netconf-connector/pom.xml
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/exception/NetconfConfigHandlingException.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/exception/NoTransactionFoundException.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/exception/OperationNotPermittedException.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/AttributeIfcSwitchStatement.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/AbstractAttributeReadingStrategy.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ArrayAttributeReadingStrategy.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/AttributeConfigElement.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/AttributeReadingStrategy.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/CompositeAttributeReadingStrategy.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ObjectNameAttributeReadingStrategy.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ObjectXmlReader.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleAttributeReadingStrategy.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleBinaryAttributeReadingStrategy.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleCompositeAttributeReadingStrategy.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleIdentityRefAttributeReadingStrategy.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleUnionAttributeReadingStrategy.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/AbstractAttributeMappingStrategy.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ArrayAttributeMappingStrategy.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/AttributeMappingStrategy.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/CompositeAttributeMappingStrategy.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/EnumAttributeMappingStrategy.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectMapper.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectNameAttributeMappingStrategy.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/SimpleAttributeMappingStrategy.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/UnionCompositeAttributeMappingStrategy.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/AbstractAttributeResolvingStrategy.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ArrayAttributeResolvingStrategy.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/AttributeResolvingStrategy.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/CompositeAttributeResolvingStrategy.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/EnumAttributeResolvingStrategy.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectNameAttributeResolvingStrategy.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectResolver.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/SimpleAttributeResolvingStrategy.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/UnionCompositeAttributeResolvingStrategy.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/ArrayAttributeWritingStrategy.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/AttributeWritingStrategy.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/CompositeAttributeWritingStrategy.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/ObjectNameAttributeWritingStrategy.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/ObjectXmlWriter.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/RuntimeBeanEntryWritingStrategy.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleAttributeWritingStrategy.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleBinaryAttributeWritingStrategy.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleCompositeAttributeWritingStrategy.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleIdentityRefAttributeWritingStrategy.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleUnionAttributeWritingStrategy.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Config.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfig.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfigElementResolved.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleConfig.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleElementDefinition.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleElementResolved.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ServiceRegistryWrapper.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Services.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/rpc/InstanceRuntimeRpc.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/rpc/ModuleRpcs.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/rpc/Rpcs.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/InstanceRuntime.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/ModuleRuntime.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/Runtime.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/AbstractConfigNetconfOperation.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/Commit.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/Datastore.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/DiscardChanges.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/Lock.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/UnLock.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/Validate.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/AbstractEditConfigStrategy.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/DeleteEditConfigStrategy.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfig.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigStrategy.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigXmlParser.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditStrategyType.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MergeEditConfigStrategy.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MissingInstanceHandlingStrategy.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/NoneEditConfigStrategy.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/RemoveEditConfigStrategy.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/ReplaceEditConfigStrategy.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/get/Get.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/getconfig/CandidateDatastoreQueryStrategy.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/getconfig/DatastoreQueryStrategy.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/getconfig/GetConfig.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/getconfig/RunningDatastoreQueryStrategy.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpc.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpcElementResolved.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/Activator.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/EnumResolver.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationProvider.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationServiceFactoryImpl.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationServiceImpl.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/YangStoreContext.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/YangStoreService.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/YangStoreSnapshot.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/transactions/TransactionProvider.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/util/Util.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java
opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/ServiceTrackerTest.java
opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleIdentityRefAttributeReadingStrategyTest.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/ValidateTest.java
opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigTest.java
opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MergeEditConfigStrategyTest.java
opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/ReplaceEditConfigStrategyTest.java
opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpcElementResolvedTest.java [deleted file]
opendaylight/netconf/config-persister-impl/pom.xml [deleted file]
opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/CapabilityStrippingConfigSnapshotHolder.java [deleted file]
opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/ConfigPersisterNotificationHandler.java [deleted file]
opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/ConfigPusherImpl.java [deleted file]
opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/NoOpStorageAdapter.java [deleted file]
opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/PersisterAggregator.java [deleted file]
opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/PropertiesProviderAdapterImpl.java [deleted file]
opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/osgi/ConfigPersisterActivator.java [deleted file]
opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/osgi/PropertiesProviderBaseImpl.java [deleted file]
opendaylight/netconf/config-persister-impl/src/main/resources/netconfOp/client_hello.xml [deleted file]
opendaylight/netconf/config-persister-impl/src/main/resources/netconfOp/commit.xml [deleted file]
opendaylight/netconf/config-persister-impl/src/main/resources/netconfOp/editConfig.xml [deleted file]
opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/CapabilityStrippingConfigSnapshotHolderTest.java [deleted file]
opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/ConfigPersisterNotificationHandlerTest.java [deleted file]
opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/ConfigPersisterNotificationListenerTest.java [deleted file]
opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/DummyAdapter.java [deleted file]
opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/PersisterAggregatorTest.java [deleted file]
opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/osgi/ConfigPersisterTest.java [deleted file]
opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/osgi/MockedBundleContext.java [deleted file]
opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/osgi/TestingExceptionHandler.java [deleted file]
opendaylight/netconf/config-persister-impl/src/test/resources/capabilities-all.txt [deleted file]
opendaylight/netconf/config-persister-impl/src/test/resources/capabilities-stripped.txt [deleted file]
opendaylight/netconf/config-persister-impl/src/test/resources/logback-test.xml [deleted file]
opendaylight/netconf/config-persister-impl/src/test/resources/snapshot.xml [deleted file]
opendaylight/netconf/config-persister-impl/src/test/resources/test1.properties [deleted file]
opendaylight/netconf/config-persister-impl/src/test/resources/test2.properties [deleted file]
opendaylight/netconf/config-persister-impl/src/test/resources/test3.properties [deleted file]
opendaylight/netconf/features/netconf-connector/pom.xml [new file with mode: 0644]
opendaylight/netconf/features/netconf-connector/src/main/resources/features.xml [new file with mode: 0644]
opendaylight/netconf/features/netconf/pom.xml [new file with mode: 0644]
opendaylight/netconf/features/netconf/src/main/resources/features.xml [new file with mode: 0644]
opendaylight/netconf/features/pom.xml [new file with mode: 0644]
opendaylight/netconf/mdsal-netconf-connector/pom.xml
opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/CurrentSchemaContext.java
opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/MdsalNetconfOperationServiceFactory.java
opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/TransactionProvider.java
opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/ops/Commit.java
opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/ops/DiscardChanges.java
opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/ops/EditConfig.java
opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/ops/Lock.java
opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/ops/RuntimeRpc.java
opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/ops/Unlock.java
opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/ops/get/AbstractGet.java
opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/ops/get/Get.java
opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/ops/get/GetConfig.java
opendaylight/netconf/mdsal-netconf-connector/src/test/java/org/opendaylight/controller/netconf/mdsal/connector/ops/NetconfMDSalMappingTest.java
opendaylight/netconf/mdsal-netconf-connector/src/test/java/org/opendaylight/controller/netconf/mdsal/connector/ops/RuntimeRpcTest.java
opendaylight/netconf/mdsal-netconf-monitoring/pom.xml
opendaylight/netconf/mdsal-netconf-monitoring/src/main/java/org/opendaylight/controller/config/yang/netconf/mdsal/monitoring/NetconfMdsalMonitoringMapperModule.java
opendaylight/netconf/mdsal-netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/NetconfMonitoringOperationServiceFactory.java
opendaylight/netconf/models/ietf-netconf-monitoring-extension/pom.xml [moved from opendaylight/netconf/ietf-netconf-monitoring-extension/pom.xml with 96% similarity]
opendaylight/netconf/models/ietf-netconf-monitoring-extension/src/main/yang/ietf-netconf-monitoring-extension.yang [moved from opendaylight/netconf/ietf-netconf-monitoring-extension/src/main/yang/ietf-netconf-monitoring-extension.yang with 100% similarity]
opendaylight/netconf/models/ietf-netconf-monitoring/pom.xml [moved from opendaylight/netconf/ietf-netconf-monitoring/pom.xml with 97% similarity]
opendaylight/netconf/models/ietf-netconf-monitoring/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/netconf/monitoring/rev101004/netconf/state/schemas/LocationBuilder.java [moved from opendaylight/netconf/ietf-netconf-monitoring/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/netconf/monitoring/rev101004/netconf/state/schemas/LocationBuilder.java with 100% similarity]
opendaylight/netconf/models/ietf-netconf-monitoring/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/netconf/monitoring/rev101004/netconf/state/schemas/SchemaLocationBuilder.java [moved from opendaylight/netconf/ietf-netconf-monitoring/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/netconf/monitoring/rev101004/netconf/state/schemas/SchemaLocationBuilder.java with 100% similarity]
opendaylight/netconf/models/ietf-netconf-monitoring/src/main/yang/ietf-netconf-monitoring.yang [moved from opendaylight/netconf/ietf-netconf-monitoring/src/main/yang/ietf-netconf-monitoring.yang with 100% similarity]
opendaylight/netconf/models/ietf-netconf-notifications/pom.xml [moved from opendaylight/netconf/ietf-netconf-notifications/pom.xml with 97% similarity]
opendaylight/netconf/models/ietf-netconf-notifications/src/main/yang/ietf-netconf-notifications@2012-02-06.yang [moved from opendaylight/netconf/ietf-netconf-notifications/src/main/yang/ietf-netconf-notifications@2012-02-06.yang with 100% similarity]
opendaylight/netconf/models/ietf-netconf-notifications/src/main/yang/nc-notifications@2008-07-14.yang [moved from opendaylight/netconf/ietf-netconf-notifications/src/main/yang/nc-notifications@2008-07-14.yang with 100% similarity]
opendaylight/netconf/models/ietf-netconf-notifications/src/main/yang/notifications@2008-07-14.yang [moved from opendaylight/netconf/ietf-netconf-notifications/src/main/yang/notifications@2008-07-14.yang with 100% similarity]
opendaylight/netconf/models/ietf-netconf/pom.xml [moved from opendaylight/netconf/ietf-netconf/pom.xml with 97% similarity]
opendaylight/netconf/models/ietf-netconf/src/main/yang/ietf-netconf@2011-06-01.yang [moved from opendaylight/netconf/ietf-netconf/src/main/yang/ietf-netconf@2011-06-01.yang with 100% similarity]
opendaylight/netconf/models/pom.xml [new file with mode: 0644]
opendaylight/netconf/netconf-api/pom.xml
opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/Capability.java [deleted file]
opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/NetconfDocumentedException.java
opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/jmx/CommitJMXNotification.java [deleted file]
opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/jmx/DefaultCommitOperationMXBean.java [deleted file]
opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/jmx/NetconfJMXNotification.java [deleted file]
opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/monitoring/CapabilityListener.java
opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/util/NetconfConstants.java
opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/xml/XmlNetconfConstants.java
opendaylight/netconf/netconf-api/src/test/java/org/opendaylight/controller/netconf/api/NetconfDocumentedExceptionTest.java
opendaylight/netconf/netconf-artifacts/pom.xml
opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClientSessionNegotiator.java
opendaylight/netconf/netconf-config-dispatcher/pom.xml [new file with mode: 0644]
opendaylight/netconf/netconf-config-dispatcher/src/main/java/org/opendaylight/controller/config/yang/config/netconf/client/dispatcher/NetconfClientDispatcherModule.java [new file with mode: 0644]
opendaylight/netconf/netconf-config-dispatcher/src/main/java/org/opendaylight/controller/config/yang/config/netconf/client/dispatcher/NetconfClientDispatcherModuleFactory.java [new file with mode: 0644]
opendaylight/netconf/netconf-config-dispatcher/src/main/yang/odl-netconf-cfg.yang [new file with mode: 0644]
opendaylight/netconf/netconf-config-dispatcher/src/main/yang/odl-netconfig-client-cfg.yang [new file with mode: 0644]
opendaylight/netconf/netconf-config-dispatcher/src/test/java/org/opendaylight/controller/config/yang/config/netconf/client/dispatcher/NetconfClientDispatcherModuleTest.java [new file with mode: 0644]
opendaylight/netconf/netconf-impl/pom.xml
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/config/yang/config/netconf/northbound/impl/NetconfServerDispatcherModule.java
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/CommitNotifier.java [deleted file]
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/DefaultCommitNotificationProducer.java [deleted file]
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionListener.java
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionNegotiatorFactory.java
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/SubtreeFilter.java
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultCloseSession.java
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultCommit.java [deleted file]
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultStartExi.java
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultStopExi.java
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/AggregatedNetconfOperationServiceFactory.java
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfImplActivator.java
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfMonitoringServiceImpl.java
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfOperationRouter.java
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfOperationRouterImpl.java
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/util/DeserializerExceptionHandler.java
opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/ConcurrentClientsTest.java
opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/NetconfDispatcherImplTest.java
opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/SubtreeFilterTest.java
opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultCloseSessionTest.java
opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultCommitTest.java [deleted file]
opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultStopExiTest.java
opendaylight/netconf/netconf-it/pom.xml
opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/AbstractNetconfConfigTest.java
opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfConfigPersisterITTest.java
opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITMonitoringTest.java
opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITSecureTest.java
opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java
opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/SSLUtil.java [deleted file]
opendaylight/netconf/netconf-mapping-api/pom.xml
opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/NetconfOperation.java
opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/NetconfOperationChainedExecution.java
opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/NetconfOperationServiceFactory.java
opendaylight/netconf/netconf-mapping-api/src/main/test/java/org/opendaylight/controller/netconf/mapping/api/HandlingPriorityTest.java [moved from opendaylight/netconf/netconf-mapping-api/src/test/java/org/opendaylight/controller/netconf/mapping/api/HandlingPriorityTest.java with 60% similarity]
opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/Get.java
opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/GetSchema.java
opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/osgi/NetconfMonitoringActivator.java
opendaylight/netconf/netconf-monitoring/src/test/java/org/opendaylight/controller/netconf/monitoring/GetSchemaTest.java
opendaylight/netconf/netconf-monitoring/src/test/java/org/opendaylight/controller/netconf/monitoring/GetTest.java
opendaylight/netconf/netconf-monitoring/src/test/java/org/opendaylight/controller/netconf/monitoring/xml/JaxBSerializerTest.java
opendaylight/netconf/netconf-netty-util/pom.xml
opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/AbstractNetconfSession.java
opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/NetconfXMLToHelloMessageDecoder.java
opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/NetconfXMLToMessageDecoder.java
opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/exi/EXIParameters.java
opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/exi/NetconfStartExiMessage.java
opendaylight/netconf/netconf-netty-util/src/test/java/org/opendaylight/controller/netconf/nettyutil/handler/NetconfEXIHandlersTest.java
opendaylight/netconf/netconf-netty-util/src/test/java/org/opendaylight/controller/netconf/nettyutil/handler/NetconfHelloMessageToXMLEncoderTest.java
opendaylight/netconf/netconf-netty-util/src/test/java/org/opendaylight/controller/netconf/nettyutil/handler/NetconfXMLToHelloMessageDecoderTest.java
opendaylight/netconf/netconf-netty-util/src/test/java/org/opendaylight/controller/netconf/nettyutil/handler/exi/EXIParametersTest.java
opendaylight/netconf/netconf-notifications-api/pom.xml
opendaylight/netconf/netconf-notifications-api/src/main/java/org/opendaylight/controller/netconf/notifications/BaseNetconfNotificationListener.java
opendaylight/netconf/netconf-notifications-api/src/main/java/org/opendaylight/controller/netconf/notifications/NetconfNotificationCollector.java
opendaylight/netconf/netconf-notifications-impl/pom.xml
opendaylight/netconf/netconf-notifications-impl/src/main/java/org/opendaylight/controller/netconf/notifications/impl/NetconfNotificationManager.java
opendaylight/netconf/netconf-notifications-impl/src/main/java/org/opendaylight/controller/netconf/notifications/impl/ops/CreateSubscription.java
opendaylight/netconf/netconf-notifications-impl/src/main/java/org/opendaylight/controller/netconf/notifications/impl/ops/Get.java
opendaylight/netconf/netconf-notifications-impl/src/main/java/org/opendaylight/controller/netconf/notifications/impl/ops/NotificationsTransformUtil.java
opendaylight/netconf/netconf-notifications-impl/src/main/java/org/opendaylight/controller/netconf/notifications/impl/osgi/Activator.java
opendaylight/netconf/netconf-notifications-impl/src/test/java/org/opendaylight/controller/netconf/notifications/impl/ops/CreateSubscriptionTest.java
opendaylight/netconf/netconf-notifications-impl/src/test/java/org/opendaylight/controller/netconf/notifications/impl/ops/GetTest.java
opendaylight/netconf/netconf-notifications-impl/src/test/java/org/opendaylight/controller/netconf/notifications/impl/ops/NotificationsTransformUtilTest.java
opendaylight/netconf/netconf-ssh/pom.xml
opendaylight/netconf/netconf-tcp/pom.xml
opendaylight/netconf/netconf-util/pom.xml
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/NetconfUtil.java
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/capability/BasicCapability.java [deleted file]
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/capability/YangModuleCapability.java [deleted file]
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/exception/MissingNameSpaceException.java [deleted file]
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/exception/UnexpectedElementException.java [deleted file]
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/exception/UnexpectedNamespaceException.java [deleted file]
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/mapping/AbstractLastNetconfOperation.java
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/mapping/AbstractNetconfOperation.java
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/mapping/AbstractSingletonNetconfOperation.java
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/messages/NetconfHelloMessage.java
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/messages/NetconfMessageUtil.java
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/messages/SendErrorExceptionUtil.java
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlElement.java [deleted file]
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlNetconfValidator.java
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlUtil.java [deleted file]
opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/NetconfUtilTest.java
opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/mapping/AbstractLastNetconfOperationTest.java
opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/mapping/AbstractNetconfOperationTest.java
opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/mapping/AbstractSingletonNetconfOperationTest.java
opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/messages/SendErrorExceptionUtilTest.java
opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/test/XmlFileLoader.java
opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/test/XmlUnitUtil.java
opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/xml/XMLNetconfUtilTest.java [new file with mode: 0644]
opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/xml/XmlElementTest.java [deleted file]
opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/xml/XmlUtilTest.java [deleted file]
opendaylight/netconf/pom.xml
opendaylight/netconf/sal-netconf-connector/pom.xml [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/connector/netconf/NetconfConnectorModule.java [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/connector/netconf/NetconfConnectorModuleFactory.java [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/api/MessageTransformer.java [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/api/RemoteDevice.java [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/api/RemoteDeviceCommunicator.java [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/api/RemoteDeviceHandler.java [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/api/SchemaContextProviderFactory.java [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/api/package-info.java [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDevice.java [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfStateSchemas.java [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NotificationHandler.java [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/listener/NetconfDeviceCapabilities.java [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/listener/NetconfDeviceCommunicator.java [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/listener/NetconfSessionPreferences.java [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/listener/UncancellableFuture.java [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/package-info.java [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/KeepaliveSalFacade.java [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceDataBroker.java [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceNotificationService.java [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceRpc.java [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceSalFacade.java [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceSalProvider.java [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceTopologyAdapter.java [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/AbstractWriteTx.java [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/ReadOnlyTx.java [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/ReadWriteTx.java [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/WriteCandidateRunningTx.java [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/WriteCandidateTx.java [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/WriteRunningTx.java [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/schema/NetconfRemoteSchemaYangSourceProvider.java [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/schema/mapping/NetconfMessageTransformer.java [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/util/NetconfBaseOps.java [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/util/NetconfMessageTransformUtil.java [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/util/NetconfRpcFutureCallback.java [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/util/NodeContainerProxy.java [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/util/MessageCounter.java [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/util/RemoteDeviceId.java [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/util/package-info.java [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/main/yang/netconf-node-topology.yang [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/main/yang/odl-sal-netconf-connector-cfg.yang [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceTest.java [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/NetconfStateSchemasTest.java [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/NetconfToNotificationTest.java [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/NetconfToRpcRequestTest.java [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/listener/NetconfDeviceCommunicatorTest.java [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/listener/NetconfSessionPreferencesTest.java [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/sal/KeepaliveSalFacadeTest.java [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceTopologyAdapterTest.java [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/NetconfDeviceWriteOnlyTxTest.java [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/ReadOnlyTxTest.java [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/schema/mapping/NetconfMessageTransformerTest.java [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/test/resources/netconf-state.schemas.payload.xml [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/test/resources/notification-payload.xml [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/test/resources/schemas/config-test-rpc.yang [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/test/resources/schemas/rpc-notification-subscription.yang [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/test/resources/schemas/test-module.yang [new file with mode: 0644]
opendaylight/netconf/sal-netconf-connector/src/test/resources/schemas/user-notification.yang [new file with mode: 0644]
opendaylight/netconf/tools/netconf-cli/.gitignore [moved from opendaylight/netconf/netconf-cli/.gitignore with 100% similarity]
opendaylight/netconf/tools/netconf-cli/README [moved from opendaylight/netconf/netconf-cli/README with 100% similarity]
opendaylight/netconf/tools/netconf-cli/README_ODL [moved from opendaylight/netconf/netconf-cli/README_ODL with 100% similarity]
opendaylight/netconf/tools/netconf-cli/pom.xml [moved from opendaylight/netconf/netconf-cli/pom.xml with 98% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/Cli.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/Cli.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/CommandArgHandlerRegistry.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/CommandArgHandlerRegistry.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/Main.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/Main.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/NetconfDeviceConnectionHandler.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/NetconfDeviceConnectionHandler.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/NetconfDeviceConnectionManager.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/NetconfDeviceConnectionManager.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/SchemaContextRegistry.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/SchemaContextRegistry.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/AbstractCommand.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/AbstractCommand.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/Command.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/Command.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/CommandConstants.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/CommandConstants.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/CommandDispatcher.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/CommandDispatcher.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/CommandInvocationException.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/CommandInvocationException.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/input/Input.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/input/Input.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/input/InputDefinition.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/input/InputDefinition.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/local/Close.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/local/Close.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/local/Connect.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/local/Connect.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/local/Disconnect.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/local/Disconnect.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/local/Help.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/local/Help.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/output/Output.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/output/Output.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/output/OutputDefinition.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/output/OutputDefinition.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/remote/RemoteCommand.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/remote/RemoteCommand.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/io/BaseConsoleContext.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/io/BaseConsoleContext.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/io/ConsoleContext.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/io/ConsoleContext.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/io/ConsoleIO.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/io/ConsoleIO.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/io/ConsoleIOImpl.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/io/ConsoleIOImpl.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/io/IOUtil.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/io/IOUtil.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/AbstractReader.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/AbstractReader.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/GenericListEntryReader.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/GenericListEntryReader.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/Reader.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/Reader.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/ReadingException.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/ReadingException.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/custom/ConfigReader.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/custom/ConfigReader.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/custom/EditContentReader.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/custom/EditContentReader.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/custom/FilterReader.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/custom/FilterReader.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/custom/PasswordReader.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/custom/PasswordReader.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/AnyXmlReader.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/AnyXmlReader.java with 98% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/BasicDataHolderReader.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/BasicDataHolderReader.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/ChoiceReader.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/ChoiceReader.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/ContainerReader.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/ContainerReader.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/DecisionReader.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/DecisionReader.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/GenericListReader.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/GenericListReader.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/GenericReader.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/GenericReader.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/LeafListEntryReader.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/LeafListEntryReader.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/LeafReader.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/LeafReader.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/ListEntryReader.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/ListEntryReader.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/SeparatedNodes.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/SeparatedNodes.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/UnionTypeReader.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/UnionTypeReader.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/OutFormatter.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/OutFormatter.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/WriteException.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/WriteException.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/Writer.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/Writer.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/custom/DataWriter.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/custom/DataWriter.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/AbstractWriter.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/AbstractWriter.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/AugmentationNodeCliSerializer.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/AugmentationNodeCliSerializer.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/ChoiceNodeCliSerializer.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/ChoiceNodeCliSerializer.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/CliOutputFromNormalizedNodeSerializerFactory.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/CliOutputFromNormalizedNodeSerializerFactory.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/ContainerNodeCliSerializer.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/ContainerNodeCliSerializer.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/LeafNodeCliSerializer.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/LeafNodeCliSerializer.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/LeafSetEntryNodeCliSerializer.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/LeafSetEntryNodeCliSerializer.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/LeafSetNodeCliSerializer.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/LeafSetNodeCliSerializer.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/MapEntryNodeCliSerializer.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/MapEntryNodeCliSerializer.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/MapNodeCliSerializer.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/MapNodeCliSerializer.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/NodeCliSerializerDispatcher.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/NodeCliSerializerDispatcher.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/NormalizedNodeWriter.java [moved from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/NormalizedNodeWriter.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/resources/logback.xml [moved from opendaylight/netconf/netconf-cli/src/main/resources/logback.xml with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/resources/schema/common/ietf-inet-types.yang [moved from opendaylight/netconf/netconf-cli/src/main/resources/schema/common/ietf-inet-types.yang with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/resources/schema/common/netconf-cli-ext.yang [moved from opendaylight/netconf/netconf-cli/src/main/resources/schema/common/netconf-cli-ext.yang with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/resources/schema/local/netconf-cli.yang [moved from opendaylight/netconf/netconf-cli/src/main/resources/schema/local/netconf-cli.yang with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/main/resources/schema/remote/ietf-netconf.yang [moved from opendaylight/netconf/netconf-cli/src/main/resources/schema/remote/ietf-netconf.yang with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/test/java/org/opendaylight/controller/netconf/cli/ConsoleIOTestImpl.java [moved from opendaylight/netconf/netconf-cli/src/test/java/org/opendaylight/controller/netconf/cli/ConsoleIOTestImpl.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/test/java/org/opendaylight/controller/netconf/cli/NetconfCliTest.java [moved from opendaylight/netconf/netconf-cli/src/test/java/org/opendaylight/controller/netconf/cli/NetconfCliTest.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/test/java/org/opendaylight/controller/netconf/cli/ValueForMessages.java [moved from opendaylight/netconf/netconf-cli/src/test/java/org/opendaylight/controller/netconf/cli/ValueForMessages.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/test/java/org/opendaylight/controller/netconf/cli/io/IOUtilTest.java [moved from opendaylight/netconf/netconf-cli/src/test/java/org/opendaylight/controller/netconf/cli/io/IOUtilTest.java with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/test/resources/schema-context/ietf-inet-types.yang [moved from opendaylight/netconf/netconf-cli/src/test/resources/schema-context/ietf-inet-types.yang with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/test/resources/schema-context/ietf-netconf.yang [moved from opendaylight/netconf/netconf-cli/src/test/resources/schema-context/ietf-netconf.yang with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/test/resources/schema-context/model1.yang [moved from opendaylight/netconf/netconf-cli/src/test/resources/schema-context/model1.yang with 100% similarity]
opendaylight/netconf/tools/netconf-cli/src/test/resources/schema-context/model2.yang [moved from opendaylight/netconf/netconf-cli/src/test/resources/schema-context/model2.yang with 100% similarity]
opendaylight/netconf/tools/netconf-testtool/edit.txt [moved from opendaylight/netconf/netconf-testtool/edit.txt with 100% similarity]
opendaylight/netconf/tools/netconf-testtool/pom.xml [moved from opendaylight/netconf/netconf-testtool/pom.xml with 99% similarity]
opendaylight/netconf/tools/netconf-testtool/src/main/assembly/stress-client.xml [moved from opendaylight/netconf/netconf-testtool/src/main/assembly/stress-client.xml with 100% similarity]
opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/AcceptingAuthProvider.java [moved from opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/AcceptingAuthProvider.java with 100% similarity]
opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/DummyMonitoringService.java [moved from opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/DummyMonitoringService.java with 96% similarity]
opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/FakeModuleBuilderCapability.java [moved from opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/FakeModuleBuilderCapability.java with 100% similarity]
opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/Main.java [moved from opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/Main.java with 99% similarity]
opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/ModuleBuilderCapability.java [moved from opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/ModuleBuilderCapability.java with 93% similarity]
opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/NetconfDeviceSimulator.java [moved from opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/NetconfDeviceSimulator.java with 97% similarity]
opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/TestToolUtils.java [moved from opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/TestToolUtils.java with 100% similarity]
opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/http/perf/AsyncExecutionStrategy.java [moved from opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/http/perf/AsyncExecutionStrategy.java with 100% similarity]
opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/http/perf/Parameters.java [moved from opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/http/perf/Parameters.java with 100% similarity]
opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/http/perf/PerfClientCallable.java [moved from opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/http/perf/PerfClientCallable.java with 100% similarity]
opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/http/perf/RestPerfClient.java [moved from opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/http/perf/RestPerfClient.java with 100% similarity]
opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/http/perf/SyncExecutionStrategy.java [moved from opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/http/perf/SyncExecutionStrategy.java with 100% similarity]
opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/AsyncExecutionStrategy.java [moved from opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/AsyncExecutionStrategy.java with 98% similarity]
opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/ConfigurableClientDispatcher.java [moved from opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/ConfigurableClientDispatcher.java with 100% similarity]
opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/ExecutionStrategy.java [moved from opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/ExecutionStrategy.java with 100% similarity]
opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/Parameters.java [moved from opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/Parameters.java with 100% similarity]
opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/StressClient.java [moved from opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/StressClient.java with 99% similarity]
opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/StressClientCallable.java [moved from opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/StressClientCallable.java with 100% similarity]
opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/SyncExecutionStrategy.java [moved from opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/SyncExecutionStrategy.java with 98% similarity]
opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/DataList.java [moved from opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/DataList.java with 92% similarity]
opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedCommit.java [moved from opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedCommit.java with 79% similarity]
opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedCreateSubscription.java [moved from opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedCreateSubscription.java with 96% similarity]
opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedEditConfig.java [moved from opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedEditConfig.java with 89% similarity]
opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedGet.java [moved from opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedGet.java with 83% similarity]
opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedGetConfig.java [moved from opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedGetConfig.java with 84% similarity]
opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedLock.java [moved from opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedLock.java with 79% similarity]
opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedUnLock.java [moved from opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedUnLock.java with 79% similarity]
opendaylight/netconf/tools/netconf-testtool/src/main/resources/99-netconf-connector-simulated.xml [moved from opendaylight/netconf/netconf-testtool/src/main/resources/99-netconf-connector-simulated.xml with 100% similarity]
opendaylight/netconf/tools/netconf-testtool/src/main/resources/logback.xml [moved from opendaylight/netconf/netconf-testtool/src/main/resources/logback.xml with 100% similarity]
opendaylight/netconf/tools/netconf-testtool/src/main/resources/org.ops4j.pax.url.mvn.cfg [moved from opendaylight/netconf/netconf-testtool/src/main/resources/org.ops4j.pax.url.mvn.cfg with 100% similarity]
opendaylight/netconf/tools/pom.xml [new file with mode: 0644]

index d8b2ea1c1d9c44e26d3195cfdf45d4b90e162e34..71b9efb7ad4ad35e72c0257488a17ddf43afd56a 100644 (file)
       <groupId>${project.groupId}</groupId>
       <artifactId>config-api</artifactId>
     </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>config-manager-facade-xml</artifactId>
+      <version>0.4.0-SNAPSHOT</version>
+    </dependency>
     <dependency>
       <groupId>${project.groupId}</groupId>
       <artifactId>config-util</artifactId>
       <groupId>${project.groupId}</groupId>
       <artifactId>netconf-api</artifactId>
     </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>netconf-impl</artifactId>
+    </dependency>
     <dependency>
       <groupId>${project.groupId}</groupId>
       <artifactId>netconf-mapping-api</artifactId>
       <artifactId>binding-generator-impl</artifactId>
     </dependency>
     <dependency>
-      <groupId>org.osgi</groupId>
-      <artifactId>org.osgi.core</artifactId>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
     </dependency>
     <dependency>
       <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-api</artifactId>
+      <artifactId>slf4j-simple</artifactId>
     </dependency>
     <dependency>
       <groupId>xmlunit</groupId>
       <artifactId>config-manager</artifactId>
       <scope>test</scope>
     </dependency>
-    <dependency>
-      <groupId>${project.groupId}</groupId>
-      <artifactId>netconf-impl</artifactId>
-      <scope>test</scope>
-    </dependency>
 
     <dependency>
       <groupId>${project.groupId}</groupId>
         <configuration>
           <instructions>
             <Bundle-Activator>org.opendaylight.controller.netconf.confignetconfconnector.osgi.Activator</Bundle-Activator>
-            <Private-Package>org.opendaylight.controller.netconf.confignetconfconnector.mapping.*,
-                            org.opendaylight.controller.netconf.confignetconfconnector.operations.*,
-                            org.opendaylight.controller.netconf.confignetconfconnector.transactions,
-                            org.opendaylight.controller.netconf.confignetconfconnector.util,
-                            org.opendaylight.controller.netconf.confignetconfconnector.osgi,
-                            org.opendaylight.controller.netconf.confignetconfconnector.exception,</Private-Package>
           </instructions>
         </configuration>
       </plugin>
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/exception/NetconfConfigHandlingException.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/exception/NetconfConfigHandlingException.java
deleted file mode 100644 (file)
index 9bcd075..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.confignetconfconnector.exception;
-
-import java.util.Collections;
-import java.util.Map;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-
-public class NetconfConfigHandlingException extends NetconfDocumentedException {
-    private static final long serialVersionUID = 1L;
-
-    public NetconfConfigHandlingException(final String message, final ErrorType errorType, final ErrorTag errorTag,
-                                          final ErrorSeverity errorSeverity) {
-        this(message, errorType, errorTag, errorSeverity, Collections.<String, String>emptyMap());
-    }
-
-    public NetconfConfigHandlingException(final String message, final ErrorType errorType, final ErrorTag errorTag,
-                                          final ErrorSeverity errorSeverity, final Map<String, String> errorInfo){
-        super(message,errorType,errorTag,errorSeverity,errorInfo);
-    }
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/exception/NoTransactionFoundException.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/exception/NoTransactionFoundException.java
deleted file mode 100644 (file)
index 2724757..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.confignetconfconnector.exception;
-
-import java.util.Collections;
-import java.util.Map;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-
-public class NoTransactionFoundException extends NetconfDocumentedException {
-    private static final long serialVersionUID = 1L;
-
-    public NoTransactionFoundException(final String message, final ErrorType errorType, final ErrorTag errorTag,
-                                          final ErrorSeverity errorSeverity) {
-        this(message, errorType, errorTag, errorSeverity, Collections.<String, String> emptyMap());
-    }
-
-    public NoTransactionFoundException(final String message, final ErrorType errorType, final ErrorTag errorTag,
-                                          final ErrorSeverity errorSeverity, final Map<String, String> errorInfo){
-        super(message,errorType,errorTag,errorSeverity,errorInfo);
-    }
-
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/exception/OperationNotPermittedException.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/exception/OperationNotPermittedException.java
deleted file mode 100644 (file)
index d92ea45..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.confignetconfconnector.exception;
-
-import java.util.Collections;
-import java.util.Map;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-
-public class OperationNotPermittedException extends NetconfDocumentedException {
-    private static final long serialVersionUID = 1L;
-
-    public OperationNotPermittedException(final String message, final ErrorType errorType, final ErrorTag errorTag,
-                                       final ErrorSeverity errorSeverity) {
-        this(message, errorType, errorTag, errorSeverity, Collections.<String, String> emptyMap());
-    }
-
-    public OperationNotPermittedException(final String message, final ErrorType errorType, final ErrorTag errorTag,
-                                       final ErrorSeverity errorSeverity, final Map<String, String> errorInfo){
-        super(message,errorType,errorTag,errorSeverity,errorInfo);
-    }
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/AttributeIfcSwitchStatement.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/AttributeIfcSwitchStatement.java
deleted file mode 100644 (file)
index 38c0b06..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes;
-
-import javax.management.openmbean.ArrayType;
-import javax.management.openmbean.CompositeType;
-import javax.management.openmbean.OpenType;
-import javax.management.openmbean.SimpleType;
-import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIfc;
-import org.opendaylight.controller.config.yangjmxgenerator.attribute.DependencyAttribute;
-import org.opendaylight.controller.config.yangjmxgenerator.attribute.JavaAttribute;
-import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListAttribute;
-import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListDependenciesAttribute;
-import org.opendaylight.controller.config.yangjmxgenerator.attribute.TOAttribute;
-import org.opendaylight.yangtools.yang.model.api.type.BinaryTypeDefinition;
-
-public abstract class AttributeIfcSwitchStatement<T> {
-
-    private AttributeIfc lastAttribute;
-
-    public T switchAttribute(AttributeIfc attributeIfc) {
-
-        this.lastAttribute = attributeIfc;
-
-        OpenType<?> openType = attributeIfc.getOpenType();
-
-        if (attributeIfc instanceof JavaAttribute) {
-            try {
-                if(((JavaAttribute)attributeIfc).getTypeDefinition() instanceof BinaryTypeDefinition) {
-                    return caseJavaBinaryAttribute(openType);
-                } else if(((JavaAttribute)attributeIfc).isUnion()) {
-                    return caseJavaUnionAttribute(openType);
-                } else if(((JavaAttribute)attributeIfc).isIdentityRef()) {
-                    return caseJavaIdentityRefAttribute(openType);
-                } else if(((JavaAttribute)attributeIfc).isEnum()) {
-                    return caseJavaEnumAttribute(openType);
-                } else {
-                    return caseJavaAttribute(openType);
-                }
-            } catch (UnknownOpenTypeException e) {
-                throw getIllegalArgumentException(attributeIfc);
-            }
-
-        } else if (attributeIfc instanceof DependencyAttribute) {
-            return caseDependencyAttribute(((DependencyAttribute) attributeIfc).getOpenType());
-        } else if (attributeIfc instanceof ListAttribute) {
-            return caseListAttribute((ArrayType<?>) openType);
-        } else if (attributeIfc instanceof ListDependenciesAttribute) {
-            return caseListDependeciesAttribute((ArrayType<?>) openType);
-        } else if (attributeIfc instanceof TOAttribute) {
-            return caseTOAttribute(((TOAttribute) attributeIfc).getOpenType());
-        }
-
-        throw getIllegalArgumentException(attributeIfc);
-    }
-
-    public AttributeIfc getLastAttribute() {
-        return lastAttribute;
-    }
-
-    protected T caseJavaIdentityRefAttribute(OpenType<?> openType) {
-        return caseJavaAttribute(openType);
-    }
-
-    protected T caseJavaUnionAttribute(OpenType<?> openType) {
-        return caseJavaAttribute(openType);
-    }
-
-    protected T caseJavaEnumAttribute(OpenType<?> openType) {
-        return caseJavaAttribute(openType);
-    }
-
-    protected T caseJavaBinaryAttribute(OpenType<?> openType) {
-        return caseJavaAttribute(openType);
-    }
-
-    private IllegalArgumentException getIllegalArgumentException(AttributeIfc attributeIfc) {
-        return new IllegalArgumentException("Unknown attribute type " + attributeIfc.getClass() + ", " + attributeIfc
-                + " with open type:" + attributeIfc.getOpenType());
-    }
-
-    public final T caseJavaAttribute(OpenType<?> openType) {
-        if (openType instanceof SimpleType<?>) {
-            return caseJavaSimpleAttribute((SimpleType<?>) openType);
-        } else if (openType instanceof ArrayType<?>) {
-            return caseJavaArrayAttribute((ArrayType<?>) openType);
-        } else if (openType instanceof CompositeType) {
-            return caseJavaCompositeAttribute((CompositeType) openType);
-        }
-
-        throw new UnknownOpenTypeException("Unknown attribute open type " + openType);
-    }
-
-    protected abstract T caseJavaSimpleAttribute(SimpleType<?> openType);
-
-    protected abstract T caseJavaArrayAttribute(ArrayType<?> openType);
-
-    protected abstract T caseJavaCompositeAttribute(CompositeType openType);
-
-    protected abstract T caseDependencyAttribute(SimpleType<?> attributeIfc);
-
-    protected abstract T caseTOAttribute(CompositeType openType);
-
-    protected abstract T caseListAttribute(ArrayType<?> openType);
-
-    protected abstract T caseListDependeciesAttribute(ArrayType<?> openType);
-
-    private static class UnknownOpenTypeException extends RuntimeException {
-        private static final long serialVersionUID = 1L;
-
-        public UnknownOpenTypeException(String message) {
-            super(message);
-        }
-    }
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/AbstractAttributeReadingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/AbstractAttributeReadingStrategy.java
deleted file mode 100644 (file)
index cf42686..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml;
-
-import java.util.List;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-
-public abstract class AbstractAttributeReadingStrategy implements AttributeReadingStrategy {
-
-    private final String nullableDefault;
-
-    public AbstractAttributeReadingStrategy(String nullableDefault) {
-        this.nullableDefault = nullableDefault;
-    }
-
-    public String getNullableDefault() {
-        return nullableDefault;
-    }
-
-    @Override
-    public AttributeConfigElement readElement(List<XmlElement> configNodes) throws NetconfDocumentedException {
-        if (configNodes.size() == 0){
-            return AttributeConfigElement.createNullValue(postprocessNullableDefault(nullableDefault));
-        }
-        return readElementHook(configNodes);
-    }
-
-    abstract AttributeConfigElement readElementHook(List<XmlElement> configNodes) throws NetconfDocumentedException;
-
-    protected Object postprocessNullableDefault(String nullableDefault) {
-        return nullableDefault;
-    }
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ArrayAttributeReadingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ArrayAttributeReadingStrategy.java
deleted file mode 100644 (file)
index 80e549e..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml;
-
-import com.google.common.collect.Lists;
-import java.util.List;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditStrategyType;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-
-public class ArrayAttributeReadingStrategy extends AbstractAttributeReadingStrategy {
-
-    private final AttributeReadingStrategy innerStrategy;
-
-    /**
-     * @param attributeIfc
-     * @param innerStrategy
-     */
-    public ArrayAttributeReadingStrategy(String nullableDefault, AttributeReadingStrategy innerStrategy) {
-        super(nullableDefault);
-        this.innerStrategy = innerStrategy;
-    }
-
-    @Override
-    AttributeConfigElement readElementHook(List<XmlElement> configNodes) throws NetconfDocumentedException {
-        List<Object> innerList = Lists.newArrayList();
-        EditStrategyType innerEditStrategy= null;
-        for (XmlElement configNode : configNodes) {
-            final AttributeConfigElement attributeConfigElement = innerStrategy.readElement(Lists.newArrayList(configNode));
-            if(attributeConfigElement.getEditStrategy().isPresent()) {
-                // TODO this sets the last operation for the entire array
-                innerEditStrategy = attributeConfigElement.getEditStrategy().get();
-            }
-            innerList.add(attributeConfigElement.getValue());
-        }
-        return innerEditStrategy == null ? AttributeConfigElement.create(getNullableDefault(), innerList) :
-                AttributeConfigElement.create(getNullableDefault(), innerList, innerEditStrategy);
-    }
-
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/AttributeConfigElement.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/AttributeConfigElement.java
deleted file mode 100644 (file)
index fac1b35..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml;
-
-import com.google.common.base.Optional;
-import javax.management.openmbean.OpenType;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.resolving.AttributeResolvingStrategy;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditStrategyType;
-
-/**
- * Parsed xml element containing configuration for one attribute of an instance
- * of some module. Contains default value extracted from yang file.
- */
-public class AttributeConfigElement {
-    private final Object defaultValue;
-    private final Object value;
-    private final Optional<EditStrategyType> editStrategy;
-
-    private Optional<?> resolvedValue;
-    private Object resolvedDefaultValue;
-    private String jmxName;
-
-    public AttributeConfigElement(Object defaultValue, Object value, final EditStrategyType editStrategyType) {
-        this.defaultValue = defaultValue;
-        this.value = value;
-        this.editStrategy = Optional.fromNullable(editStrategyType);
-    }
-
-    public void setJmxName(String jmxName) {
-        this.jmxName = jmxName;
-    }
-
-    public String getJmxName() {
-        return jmxName;
-    }
-
-    public void resolveValue(AttributeResolvingStrategy<?, ? extends OpenType<?>> attributeResolvingStrategy,
-            String attrName) throws NetconfDocumentedException {
-        resolvedValue = attributeResolvingStrategy.parseAttribute(attrName, value);
-        Optional<?> resolvedDefault = attributeResolvingStrategy.parseAttribute(attrName, defaultValue);
-        resolvedDefaultValue = resolvedDefault.isPresent() ? resolvedDefault.get() : null;
-    }
-
-    public Optional<EditStrategyType> getEditStrategy() {
-        return editStrategy;
-    }
-
-    public static AttributeConfigElement create(Object nullableDefault, Object value) {
-        return new AttributeConfigElement(nullableDefault, value, null);
-    }
-
-    public static AttributeConfigElement createNullValue(Object nullableDefault) {
-        return new AttributeConfigElement(nullableDefault, null, null);
-    }
-
-    public static AttributeConfigElement create(final String nullableDefault, final Object value, final EditStrategyType editStrategyType) {
-        return new AttributeConfigElement(nullableDefault, value, editStrategyType);
-    }
-
-    public Object getValue() {
-        return value;
-    }
-
-    public Object getDefaultValue() {
-        return defaultValue;
-    }
-
-    public Optional<?> getResolvedValue() {
-        return resolvedValue;
-    }
-
-    public Object getResolvedDefaultValue() {
-        return resolvedDefaultValue;
-    }
-
-    @Override
-    public String toString() {
-        return "AttributeConfigElement [defaultValue=" + defaultValue + ", value=" + value + "]";
-    }
-
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/AttributeReadingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/AttributeReadingStrategy.java
deleted file mode 100644 (file)
index 359a4c4..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml;
-
-import java.util.List;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-
-public interface AttributeReadingStrategy {
-
-    public abstract AttributeConfigElement readElement(List<XmlElement> element) throws NetconfDocumentedException;
-
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/CompositeAttributeReadingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/CompositeAttributeReadingStrategy.java
deleted file mode 100644 (file)
index 3e4957b..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml;
-
-import com.google.common.base.Preconditions;
-import com.google.common.base.Strings;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditStrategyType;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-
-public class CompositeAttributeReadingStrategy extends AbstractAttributeReadingStrategy {
-
-    private final Map<String, AttributeReadingStrategy> innerStrategies;
-
-    public CompositeAttributeReadingStrategy(String nullableDefault,
-            Map<String, AttributeReadingStrategy> innerStrategies) {
-        super(nullableDefault);
-        this.innerStrategies = innerStrategies;
-    }
-
-    @Override
-    AttributeConfigElement readElementHook(List<XmlElement> configNodes) throws NetconfDocumentedException {
-
-        Preconditions.checkState(configNodes.size() == 1, "This element should be present only once %s", configNodes);
-
-        XmlElement complexElement = configNodes.get(0);
-
-        Map<String, Object> innerMap = Maps.newHashMap();
-
-        List<XmlElement> recognisedChildren = Lists.newArrayList();
-        for (Entry<String, AttributeReadingStrategy> innerAttrEntry : innerStrategies.entrySet()) {
-            List<XmlElement> childItem = complexElement.getChildElementsWithSameNamespace(
-                    innerAttrEntry.getKey());
-            recognisedChildren.addAll(childItem);
-
-            AttributeConfigElement resolvedInner = innerAttrEntry.getValue().readElement(childItem);
-
-            Object value = resolvedInner.getValue();
-            if(value == null) {
-                value = resolvedInner.getDefaultValue();
-            }
-
-            innerMap.put(innerAttrEntry.getKey(), value);
-        }
-
-        complexElement.checkUnrecognisedElements(recognisedChildren);
-
-        String perInstanceEditStrategy = complexElement.getAttribute(XmlNetconfConstants.OPERATION_ATTR_KEY,
-                XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
-
-        return Strings.isNullOrEmpty(perInstanceEditStrategy) ? AttributeConfigElement.create(getNullableDefault(), innerMap) :
-                AttributeConfigElement.create(getNullableDefault(), innerMap, EditStrategyType.valueOf(perInstanceEditStrategy));
-    }
-
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ObjectNameAttributeReadingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ObjectNameAttributeReadingStrategy.java
deleted file mode 100644 (file)
index 709c8d2..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml;
-
-import com.google.common.base.Preconditions;
-import java.util.List;
-import java.util.Map;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.mapping.ObjectNameAttributeMappingStrategy;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-
-public class ObjectNameAttributeReadingStrategy extends AbstractAttributeReadingStrategy {
-
-    private static final Object PREFIX_SEPARATOR = ":";
-
-    public ObjectNameAttributeReadingStrategy(String nullableDefault) {
-        super(nullableDefault);
-    }
-
-    @Override
-    AttributeConfigElement readElementHook(List<XmlElement> configNodes) throws NetconfDocumentedException {
-
-        XmlElement firstChild = configNodes.get(0);
-        Preconditions.checkState(configNodes.size() == 1, "This element should be present only once " + firstChild
-                + " but was " + configNodes.size());
-
-        Preconditions.checkNotNull(firstChild, "Element %s should be present", firstChild);
-        return AttributeConfigElement.create(getNullableDefault(), resolve(firstChild));
-    }
-
-    private ObjectNameAttributeMappingStrategy.MappedDependency resolve(XmlElement firstChild) throws NetconfDocumentedException{
-        XmlElement typeElement = firstChild.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.TYPE_KEY);
-        Map.Entry<String, String> prefixNamespace = typeElement.findNamespaceOfTextContent();
-
-        String serviceName = checkPrefixAndExtractServiceName(typeElement, prefixNamespace);
-
-        XmlElement nameElement = firstChild.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.NAME_KEY);
-        String dependencyName = nameElement.getTextContent();
-
-        return new ObjectNameAttributeMappingStrategy.MappedDependency(prefixNamespace.getValue(), serviceName,
-                dependencyName);
-    }
-
-    public static String checkPrefixAndExtractServiceName(XmlElement typeElement, Map.Entry<String, String> prefixNamespace) throws NetconfDocumentedException {
-        String serviceName = typeElement.getTextContent();
-        Preconditions.checkNotNull(prefixNamespace.getKey(), "Service %s value cannot be linked to namespace",
-                XmlNetconfConstants.TYPE_KEY);
-        if(prefixNamespace.getKey().isEmpty()) {
-            return serviceName;
-        } else {
-            String prefix = prefixNamespace.getKey() + PREFIX_SEPARATOR;
-            Preconditions.checkState(serviceName.startsWith(prefix),
-                    "Service %s not correctly prefixed, expected %s, but was %s", XmlNetconfConstants.TYPE_KEY, prefix,
-                    serviceName);
-            serviceName = serviceName.substring(prefix.length());
-            return serviceName;
-        }
-    }
-
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ObjectXmlReader.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ObjectXmlReader.java
deleted file mode 100644 (file)
index 15d4d08..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml;
-
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Maps;
-import java.util.Date;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import javax.management.openmbean.ArrayType;
-import javax.management.openmbean.CompositeType;
-import javax.management.openmbean.OpenType;
-import javax.management.openmbean.SimpleType;
-import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIfc;
-import org.opendaylight.controller.config.yangjmxgenerator.attribute.JavaAttribute;
-import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListAttribute;
-import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListDependenciesAttribute;
-import org.opendaylight.controller.config.yangjmxgenerator.attribute.TOAttribute;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.AttributeIfcSwitchStatement;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfig;
-
-public class ObjectXmlReader extends AttributeIfcSwitchStatement<AttributeReadingStrategy> {
-
-    private String key;
-    private Map<String, Map<Date, EditConfig.IdentityMapping>> identityMap;
-
-    public Map<String, AttributeReadingStrategy> prepareReading(Map<String, AttributeIfc> yangToAttrConfig, Map<String, Map<Date,EditConfig.IdentityMapping>> identityMap) {
-        Map<String, AttributeReadingStrategy> strategies = Maps.newHashMap();
-        this.identityMap = identityMap;
-
-        for (Entry<String, AttributeIfc> attributeEntry : yangToAttrConfig.entrySet()) {
-            AttributeReadingStrategy strat = prepareReadingStrategy(attributeEntry.getKey(), attributeEntry.getValue());
-            strategies.put(attributeEntry.getKey(), strat);
-        }
-        return strategies;
-    }
-
-    private AttributeReadingStrategy prepareReadingStrategy(String key, AttributeIfc attributeIfc) {
-        this.key = key;
-        return switchAttribute(attributeIfc);
-    }
-
-    @Override
-    protected AttributeReadingStrategy caseJavaBinaryAttribute(OpenType<?> openType) {
-        return new SimpleBinaryAttributeReadingStrategy(getLastAttribute().getNullableDefault());
-    }
-
-    @Override
-    protected AttributeReadingStrategy caseJavaUnionAttribute(OpenType<?> openType) {
-        String mappingKey = JavaAttribute.DESCRIPTION_OF_VALUE_ATTRIBUTE_FOR_UNION;
-        return new SimpleUnionAttributeReadingStrategy(getLastAttribute().getNullableDefault(), mappingKey);
-    }
-
-    @Override
-    public AttributeReadingStrategy caseJavaSimpleAttribute(SimpleType<?> openType) {
-        return new SimpleAttributeReadingStrategy(getLastAttribute().getNullableDefault());
-    }
-
-    @Override
-    public AttributeReadingStrategy caseJavaArrayAttribute(ArrayType<?> openType) {
-        SimpleAttributeReadingStrategy innerStrategy = new SimpleAttributeReadingStrategy(getLastAttribute().getNullableDefault());
-        return new ArrayAttributeReadingStrategy(getLastAttribute().getNullableDefault(), innerStrategy);
-    }
-
-    @Override
-    public AttributeReadingStrategy caseJavaCompositeAttribute(CompositeType openType) {
-        Preconditions.checkState(openType.keySet().size() == 1, "Unexpected number of elements for open type %s, should be 1", openType);
-        String mappingKey = openType.keySet().iterator().next();
-        return new SimpleCompositeAttributeReadingStrategy(getLastAttribute().getNullableDefault(), mappingKey);
-    }
-
-    @Override
-    protected AttributeReadingStrategy caseJavaIdentityRefAttribute(OpenType<?> openType) {
-        Preconditions.checkState(openType instanceof CompositeType);
-        Set<String> keys = ((CompositeType) openType).keySet();
-        Preconditions.checkState(keys.size() == 1, "Unexpected number of elements for open type %s, should be 1", openType);
-        String mappingKey = keys.iterator().next();
-        return new SimpleIdentityRefAttributeReadingStrategy(getLastAttribute().getNullableDefault(), mappingKey, identityMap);
-    }
-
-    @Override
-    protected AttributeReadingStrategy caseDependencyAttribute(SimpleType<?> openType) {
-        return new ObjectNameAttributeReadingStrategy(getLastAttribute().getNullableDefault());
-    }
-
-    @Override
-    protected AttributeReadingStrategy caseTOAttribute(CompositeType openType) {
-        AttributeIfc lastAttribute = getLastAttribute();
-        Preconditions.checkState(lastAttribute instanceof TOAttribute);
-        Map<String, AttributeIfc> inner = ((TOAttribute)lastAttribute).getYangPropertiesToTypesMap();
-
-        Map<String, AttributeReadingStrategy> innerStrategies = Maps.newHashMap();
-
-        for (Entry<String, AttributeIfc> innerAttrEntry : inner.entrySet()) {
-            AttributeReadingStrategy innerStrat = prepareReadingStrategy(innerAttrEntry.getKey(),
-                    innerAttrEntry.getValue());
-            innerStrategies.put(innerAttrEntry.getKey(), innerStrat);
-        }
-
-        return new CompositeAttributeReadingStrategy(lastAttribute.getNullableDefault(), innerStrategies);
-    }
-
-    @Override
-    protected AttributeReadingStrategy caseListAttribute(ArrayType<?> openType) {
-        AttributeIfc lastAttribute = getLastAttribute();
-        Preconditions.checkState(lastAttribute instanceof ListAttribute);
-        AttributeReadingStrategy innerStrategy = prepareReadingStrategy(key, ((ListAttribute) lastAttribute).getInnerAttribute());
-        return new ArrayAttributeReadingStrategy(lastAttribute.getNullableDefault(), innerStrategy);
-    }
-
-    @Override
-    protected AttributeReadingStrategy caseListDependeciesAttribute(ArrayType<?> openType) {
-        AttributeIfc lastAttribute = getLastAttribute();
-        Preconditions.checkState(lastAttribute instanceof ListDependenciesAttribute);
-        AttributeReadingStrategy innerStrategy = caseDependencyAttribute(SimpleType.OBJECTNAME);
-        return new ArrayAttributeReadingStrategy(lastAttribute.getNullableDefault(), innerStrategy);
-    }
-
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleAttributeReadingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleAttributeReadingStrategy.java
deleted file mode 100644 (file)
index 8f6a7cd..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml;
-
-import com.google.common.base.Preconditions;
-import java.util.List;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-
-public class SimpleAttributeReadingStrategy extends AbstractAttributeReadingStrategy {
-    public SimpleAttributeReadingStrategy(String nullableDefault) {
-        super(nullableDefault);
-    }
-
-    @Override
-    AttributeConfigElement readElementHook(List<XmlElement> configNodes) throws NetconfDocumentedException {
-        XmlElement xmlElement = configNodes.get(0);
-        Preconditions.checkState(configNodes.size() == 1, "This element should be present only once " + xmlElement
-                + " but was " + configNodes.size());
-
-        String textContent = readElementContent(xmlElement);
-        return AttributeConfigElement.create(postprocessNullableDefault(getNullableDefault()),
-                postprocessParsedValue(textContent));
-    }
-
-    protected String readElementContent(XmlElement xmlElement) throws NetconfDocumentedException {
-        return xmlElement.getTextContent();
-    }
-
-    @Override
-    protected Object postprocessNullableDefault(String nullableDefault) {
-        return nullableDefault;
-    }
-
-    protected Object postprocessParsedValue(String textContent) {
-        return textContent;
-    }
-
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleBinaryAttributeReadingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleBinaryAttributeReadingStrategy.java
deleted file mode 100644 (file)
index 3a62672..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml;
-
-import com.google.common.collect.Lists;
-import com.google.common.io.BaseEncoding;
-import java.util.List;
-
-public class SimpleBinaryAttributeReadingStrategy extends SimpleAttributeReadingStrategy {
-
-    public SimpleBinaryAttributeReadingStrategy(String nullableDefault) {
-        super(nullableDefault);
-    }
-
-    @Override
-    protected Object postprocessParsedValue(String textContent) {
-        BaseEncoding en = BaseEncoding.base64();
-        byte[] decode = en.decode(textContent);
-        List<String> parsed = Lists.newArrayListWithCapacity(decode.length);
-        for (byte b : decode) {
-            parsed.add(Byte.toString(b));
-        }
-        return parsed;
-    }
-
-    @Override
-    protected Object postprocessNullableDefault(String nullableDefault) {
-        return nullableDefault == null ? null : postprocessParsedValue(nullableDefault);
-    }
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleCompositeAttributeReadingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleCompositeAttributeReadingStrategy.java
deleted file mode 100644 (file)
index 7d78e7d..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml;
-
-import com.google.common.collect.Maps;
-import java.util.HashMap;
-
-public class SimpleCompositeAttributeReadingStrategy extends SimpleAttributeReadingStrategy {
-
-    private final String key;
-
-    public SimpleCompositeAttributeReadingStrategy(String nullableDefault, String key) {
-        super(nullableDefault);
-        this.key = key;
-    }
-
-    @Override
-    protected Object postprocessParsedValue(String textContent) {
-        HashMap<String,String> map = Maps.newHashMap();
-        map.put(key, textContent);
-        return map;
-    }
-
-    @Override
-    protected Object postprocessNullableDefault(String nullableDefault) {
-        return nullableDefault == null ? null : postprocessParsedValue(nullableDefault);
-    }
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleIdentityRefAttributeReadingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleIdentityRefAttributeReadingStrategy.java
deleted file mode 100644 (file)
index 6d702ef..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml;
-
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Maps;
-import java.net.URI;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfig;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-import org.opendaylight.yangtools.yang.common.QName;
-
-
-public class SimpleIdentityRefAttributeReadingStrategy extends SimpleAttributeReadingStrategy {
-
-    private final String key;
-    private final Map<String, Map<Date, EditConfig.IdentityMapping>> identityMap;
-
-    public SimpleIdentityRefAttributeReadingStrategy(String nullableDefault, String key, Map<String, Map<Date,EditConfig.IdentityMapping>> identityMap) {
-        super(nullableDefault);
-        this.key = key;
-        this.identityMap = identityMap;
-    }
-
-    @Override
-    protected String readElementContent(XmlElement xmlElement) throws NetconfDocumentedException {
-        Map.Entry<String, String> namespaceOfTextContent = xmlElement.findNamespaceOfTextContent();
-        String content = xmlElement.getTextContent();
-
-        final String namespace;
-        final String localName;
-        if(namespaceOfTextContent.getKey().isEmpty()) {
-            localName = content;
-            namespace = xmlElement.getNamespace();
-        } else {
-            String prefix = namespaceOfTextContent.getKey() + ":";
-            Preconditions.checkArgument(content.startsWith(prefix), "Identity ref should be prefixed with \"%s\"", prefix);
-            localName = content.substring(prefix.length());
-            namespace = namespaceOfTextContent.getValue();
-        }
-
-        Date revision = null;
-        Map<Date, EditConfig.IdentityMapping> revisions = identityMap.get(namespace);
-        if(revisions.keySet().size() > 1) {
-            for (Map.Entry<Date, EditConfig.IdentityMapping> revisionToIdentityEntry : revisions.entrySet()) {
-                if(revisionToIdentityEntry.getValue().containsIdName(localName)) {
-                    Preconditions.checkState(revision == null, "Duplicate identity %s, in namespace %s, with revisions: %s, %s detected. Cannot map attribute",
-                            localName, namespace, revision, revisionToIdentityEntry.getKey());
-                    revision = revisionToIdentityEntry.getKey();
-                }
-            }
-        } else {
-            revision = revisions.keySet().iterator().next();
-        }
-
-        return QName.create(URI.create(namespace), revision, localName).toString();
-    }
-
-    @Override
-    protected Object postprocessParsedValue(String textContent) {
-        HashMap<String,String> map = Maps.newHashMap();
-        map.put(key, textContent);
-        return map;
-    }
-
-    @Override
-    protected Object postprocessNullableDefault(String nullableDefault) {
-        return nullableDefault == null ? null : postprocessParsedValue(nullableDefault);
-    }
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleUnionAttributeReadingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleUnionAttributeReadingStrategy.java
deleted file mode 100644 (file)
index 605542f..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml;
-
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import java.util.List;
-import java.util.Map;
-
-public class SimpleUnionAttributeReadingStrategy extends SimpleAttributeReadingStrategy {
-
-    private final String key;
-
-    public SimpleUnionAttributeReadingStrategy(String nullableDefault, String key) {
-        super(nullableDefault);
-        this.key = key;
-    }
-
-    @Override
-    protected Object postprocessParsedValue(String textContent) {
-        char[] charArray = textContent.toCharArray();
-        List<String> chars = Lists.newArrayListWithCapacity(charArray.length);
-
-        for (char c : charArray) {
-            chars.add(Character.toString(c));
-        }
-
-        Map<String, Object> map = Maps.newHashMap();
-        map.put(key, chars);
-        return map;
-    }
-
-    @Override
-    protected Object postprocessNullableDefault(String nullableDefault) {
-        return nullableDefault == null ? null : postprocessParsedValue(nullableDefault);
-    }
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/AbstractAttributeMappingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/AbstractAttributeMappingStrategy.java
deleted file mode 100644 (file)
index 0d5fcb9..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.mapping;
-
-import javax.management.openmbean.OpenType;
-
-public abstract class AbstractAttributeMappingStrategy<T, O extends OpenType<?>> implements
-        AttributeMappingStrategy<T, O> {
-
-    private final O attrOpenType;
-
-    public AbstractAttributeMappingStrategy(O attributeIfc) {
-        this.attrOpenType = attributeIfc;
-    }
-
-    @Override
-    public O getOpenType() {
-        return attrOpenType;
-    }
-
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ArrayAttributeMappingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ArrayAttributeMappingStrategy.java
deleted file mode 100644 (file)
index a4eeb0c..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.mapping;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Lists;
-import java.lang.reflect.Array;
-import java.util.List;
-import javax.management.openmbean.ArrayType;
-import javax.management.openmbean.OpenType;
-
-public class ArrayAttributeMappingStrategy extends AbstractAttributeMappingStrategy<List<Object>, ArrayType<?>> {
-
-    private final AttributeMappingStrategy<?, ? extends OpenType<?>> innerElementStrategy;
-
-    public ArrayAttributeMappingStrategy(ArrayType<?> arrayType,
-            AttributeMappingStrategy<?, ? extends OpenType<?>> innerElementStrategy) {
-        super(arrayType);
-        this.innerElementStrategy = innerElementStrategy;
-    }
-
-    @Override
-    public Optional<List<Object>> mapAttribute(Object value) {
-        if (value == null){
-            return Optional.absent();
-        }
-
-        Preconditions.checkArgument(value.getClass().isArray(), "Value has to be instanceof Array ");
-
-        List<Object> retVal = Lists.newArrayList();
-
-        for (int i = 0; i < Array.getLength(value); i++) {
-            Object innerValue = Array.get(value, i);
-            Optional<?> mapAttribute = innerElementStrategy.mapAttribute(innerValue);
-
-            if (mapAttribute.isPresent()){
-                retVal.add(mapAttribute.get());
-            }
-        }
-
-        return Optional.of(retVal);
-    }
-
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/AttributeMappingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/AttributeMappingStrategy.java
deleted file mode 100644 (file)
index d36b13b..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.mapping;
-
-import com.google.common.base.Optional;
-import javax.management.openmbean.OpenType;
-
-public interface AttributeMappingStrategy<T, O extends OpenType<?>> {
-
-    O getOpenType();
-
-    Optional<T> mapAttribute(Object o);
-
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/CompositeAttributeMappingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/CompositeAttributeMappingStrategy.java
deleted file mode 100644 (file)
index 16421d5..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.mapping;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Maps;
-import java.util.Map;
-import java.util.Set;
-import javax.management.openmbean.CompositeDataSupport;
-import javax.management.openmbean.CompositeType;
-import javax.management.openmbean.OpenType;
-import org.opendaylight.controller.netconf.confignetconfconnector.util.Util;
-
-public class CompositeAttributeMappingStrategy extends
-        AbstractAttributeMappingStrategy<Map<String, Object>, CompositeType> {
-
-    private final Map<String, AttributeMappingStrategy<?, ? extends OpenType<?>>> innerStrategies;
-    private final Map<String, String> jmxToJavaNameMapping;
-
-    public CompositeAttributeMappingStrategy(CompositeType compositeType,
-            Map<String, AttributeMappingStrategy<?, ? extends OpenType<?>>> innerStrategies,
-            Map<String, String> jmxToJavaNameMapping) {
-        super(compositeType);
-        this.innerStrategies = innerStrategies;
-        this.jmxToJavaNameMapping = jmxToJavaNameMapping;
-    }
-
-    @Override
-    public Optional<Map<String, Object>> mapAttribute(Object value) {
-        if (value == null){
-            return Optional.absent();
-        }
-
-        Util.checkType(value, CompositeDataSupport.class);
-
-        CompositeDataSupport compositeData = (CompositeDataSupport) value;
-        CompositeType currentType = compositeData.getCompositeType();
-        CompositeType expectedType = getOpenType();
-
-        Set<String> expectedCompositeTypeKeys = expectedType.keySet();
-        Set<String> currentCompositeTypeKeys = currentType.keySet();
-        Preconditions.checkArgument(expectedCompositeTypeKeys.equals(currentCompositeTypeKeys),
-                "Composite type mismatch, expected composite type with attributes " + expectedCompositeTypeKeys
-                        + " but was " + currentCompositeTypeKeys);
-
-        Map<String, Object> retVal = Maps.newHashMap();
-
-        for (String jmxName : jmxToJavaNameMapping.keySet()) {
-            Optional<?> mapped = mapInnerAttribute(compositeData, jmxName, expectedType.getDescription(jmxName));
-            if(mapped.isPresent()){
-                retVal.put(jmxToJavaNameMapping.get(jmxName), mapped.get());
-            }
-        }
-
-        return Optional.of(retVal);
-    }
-
-    protected Optional<?> mapInnerAttribute(CompositeDataSupport compositeData, String jmxName, String description) {
-        Object innerValue = compositeData.get(jmxName);
-
-        AttributeMappingStrategy<?, ? extends OpenType<?>> attributeMappingStrategy = innerStrategies
-                .get(jmxName);
-        return attributeMappingStrategy.mapAttribute(innerValue);
-    }
-
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/EnumAttributeMappingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/EnumAttributeMappingStrategy.java
deleted file mode 100644 (file)
index 052438b..0000000
+++ /dev/null
@@ -1,34 +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.netconf.confignetconfconnector.mapping.attributes.mapping;
-
-import com.google.common.base.Optional;
-import javax.management.openmbean.CompositeType;
-import org.opendaylight.controller.netconf.confignetconfconnector.osgi.EnumResolver;
-
-public class EnumAttributeMappingStrategy extends AbstractAttributeMappingStrategy<String, CompositeType> {
-
-    private final EnumResolver enumResolver;
-
-    public EnumAttributeMappingStrategy(CompositeType openType, final EnumResolver enumResolver) {
-        super(openType);
-        this.enumResolver = enumResolver;
-    }
-
-    @Override
-    public Optional<String> mapAttribute(Object value) {
-        if (value == null){
-            return Optional.absent();
-        }
-
-        String expectedClass = getOpenType().getTypeName();
-        return Optional.of(enumResolver.toYang(expectedClass, value.toString()));
-    }
-
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectMapper.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectMapper.java
deleted file mode 100644 (file)
index 2608c57..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.mapping;
-
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Maps;
-import java.util.Map;
-import java.util.Map.Entry;
-import javax.management.openmbean.ArrayType;
-import javax.management.openmbean.CompositeType;
-import javax.management.openmbean.OpenType;
-import javax.management.openmbean.SimpleType;
-import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIfc;
-import org.opendaylight.controller.config.yangjmxgenerator.attribute.DependencyAttribute;
-import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListAttribute;
-import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListDependenciesAttribute;
-import org.opendaylight.controller.config.yangjmxgenerator.attribute.TOAttribute;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.AttributeIfcSwitchStatement;
-import org.opendaylight.controller.netconf.confignetconfconnector.osgi.EnumResolver;
-
-public class ObjectMapper extends AttributeIfcSwitchStatement<AttributeMappingStrategy<?, ? extends OpenType<?>>> {
-
-    private EnumResolver enumResolver;
-
-    public Map<String, AttributeMappingStrategy<?, ? extends OpenType<?>>> prepareMapping(
-            Map<String, AttributeIfc> configDefinition, EnumResolver enumResolver) {
-        this.enumResolver = Preconditions.checkNotNull(enumResolver);
-        Map<String, AttributeMappingStrategy<?, ? extends OpenType<?>>> strategies = Maps.newHashMap();
-
-        for (Entry<String, AttributeIfc> attrEntry : configDefinition.entrySet()) {
-            strategies.put(attrEntry.getKey(), prepareStrategy(attrEntry.getValue()));
-        }
-
-        return strategies;
-    }
-
-    public AttributeMappingStrategy<?, ? extends OpenType<?>> prepareStrategy(AttributeIfc attributeIfc) {
-
-        if(attributeIfc instanceof DependencyAttribute) {
-            namespaceOfDepAttr = ((DependencyAttribute)attributeIfc).getDependency().getSie().getQName().getNamespace().toString();
-        } else if (attributeIfc instanceof ListDependenciesAttribute) {
-            namespaceOfDepAttr = ((ListDependenciesAttribute)attributeIfc).getDependency().getSie().getQName().getNamespace().toString();
-        }
-
-        return switchAttribute(attributeIfc);
-    }
-
-    private Map<String, String> createJmxToYangMapping(TOAttribute attributeIfc) {
-        Map<String, String> retVal = Maps.newHashMap();
-        for (Entry<String, AttributeIfc> entry : attributeIfc.getJmxPropertiesToTypesMap().entrySet()) {
-            retVal.put(entry.getKey(), (entry.getValue()).getAttributeYangName());
-        }
-        return retVal;
-    }
-
-    @Override
-    protected AttributeMappingStrategy<?, ? extends OpenType<?>> caseJavaSimpleAttribute(SimpleType<?> openType) {
-        return new SimpleAttributeMappingStrategy(openType);
-    }
-
-    @Override
-    protected AttributeMappingStrategy<?, ? extends OpenType<?>> caseJavaEnumAttribute(final OpenType<?> openType) {
-        return new EnumAttributeMappingStrategy(((CompositeType) openType), enumResolver);
-    }
-
-    @Override
-    protected AttributeMappingStrategy<?, ? extends OpenType<?>> caseJavaArrayAttribute(ArrayType<?> openType) {
-
-        AttributeMappingStrategy<?, ? extends OpenType<?>> innerStrategy = new SimpleAttributeMappingStrategy(
-                (SimpleType<?>) openType.getElementOpenType());
-        return new ArrayAttributeMappingStrategy(openType, innerStrategy);
-    }
-
-    @Override
-    protected AttributeMappingStrategy<?, ? extends OpenType<?>> caseJavaCompositeAttribute(CompositeType openType) {
-        Map<String, AttributeMappingStrategy<?, ? extends OpenType<?>>> innerStrategies = Maps.newHashMap();
-
-        Map<String, String> attributeMapping = Maps.newHashMap();
-
-        for (String innerAttributeKey : openType.keySet()) {
-
-            innerStrategies.put(innerAttributeKey, caseJavaAttribute(openType.getType(innerAttributeKey)));
-            attributeMapping.put(innerAttributeKey, innerAttributeKey);
-        }
-
-        return new CompositeAttributeMappingStrategy(openType, innerStrategies, attributeMapping);
-    }
-
-    @Override
-    protected AttributeMappingStrategy<?, ? extends OpenType<?>> caseJavaUnionAttribute(OpenType<?> openType) {
-        Map<String, AttributeMappingStrategy<?, ? extends OpenType<?>>> innerStrategies = Maps.newHashMap();
-
-        Map<String, String> attributeMapping = Maps.newHashMap();
-
-        CompositeType compositeType = (CompositeType) openType;
-        for (String innerAttributeKey : compositeType.keySet()) {
-
-            innerStrategies.put(innerAttributeKey, caseJavaAttribute(compositeType.getType(innerAttributeKey)));
-            attributeMapping.put(innerAttributeKey, innerAttributeKey);
-        }
-
-        return new UnionCompositeAttributeMappingStrategy(compositeType, innerStrategies, attributeMapping);
-    }
-
-    private String namespaceOfDepAttr;
-
-    @Override
-    protected AttributeMappingStrategy<?, ? extends OpenType<?>> caseDependencyAttribute(
-            SimpleType<?> openType) {
-        return new ObjectNameAttributeMappingStrategy(openType, namespaceOfDepAttr);
-    }
-
-    @Override
-    protected AttributeMappingStrategy<?, ? extends OpenType<?>> caseTOAttribute(CompositeType openType) {
-        Map<String, AttributeMappingStrategy<?, ? extends OpenType<?>>> innerStrategies = Maps.newHashMap();
-
-        Preconditions.checkState(getLastAttribute() instanceof TOAttribute);
-        TOAttribute lastTO = (TOAttribute) getLastAttribute();
-
-        for (Entry<String, AttributeIfc> innerAttrEntry : ((TOAttribute)getLastAttribute()).getJmxPropertiesToTypesMap().entrySet()) {
-            innerStrategies.put(innerAttrEntry.getKey(), prepareStrategy(innerAttrEntry.getValue()));
-        }
-
-        return new CompositeAttributeMappingStrategy(openType, innerStrategies,
-                createJmxToYangMapping(lastTO));
-    }
-
-    @Override
-    protected AttributeMappingStrategy<?, ? extends OpenType<?>> caseListAttribute(ArrayType<?> openType) {
-        Preconditions.checkState(getLastAttribute() instanceof ListAttribute);
-        return new ArrayAttributeMappingStrategy(openType,
-                prepareStrategy(((ListAttribute) getLastAttribute()).getInnerAttribute()));
-    }
-
-    @Override
-    protected AttributeMappingStrategy<?, ? extends OpenType<?>> caseListDependeciesAttribute(ArrayType<?> openType) {
-        Preconditions.checkState(getLastAttribute() instanceof ListDependenciesAttribute);
-        return new ArrayAttributeMappingStrategy(openType, caseDependencyAttribute(SimpleType.OBJECTNAME));
-    }
-
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectNameAttributeMappingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectNameAttributeMappingStrategy.java
deleted file mode 100644 (file)
index b0569de..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.mapping;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import javax.management.ObjectName;
-import javax.management.openmbean.SimpleType;
-import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
-import org.opendaylight.controller.netconf.confignetconfconnector.util.Util;
-import org.opendaylight.yangtools.yang.common.QName;
-
-public class ObjectNameAttributeMappingStrategy extends
-        AbstractAttributeMappingStrategy<ObjectNameAttributeMappingStrategy.MappedDependency, SimpleType<?>> {
-
-    private final String namespace;
-
-    public ObjectNameAttributeMappingStrategy(SimpleType<?> openType, String namespace) {
-        super(openType);
-        this.namespace = namespace;
-    }
-
-    @Override
-    public Optional<MappedDependency> mapAttribute(Object value) {
-        if (value == null){
-            return Optional.absent();
-        }
-
-        String expectedClass = getOpenType().getClassName();
-        String realClass = value.getClass().getName();
-        Preconditions.checkArgument(realClass.equals(expectedClass), "Type mismatch, expected " + expectedClass
-                + " but was " + realClass);
-        Util.checkType(value, ObjectName.class);
-
-        ObjectName on = (ObjectName) value;
-
-        String refName = ObjectNameUtil.getReferenceName(on);
-
-        //we want to use the exact service name that was configured in xml so services that are referencing it can be resolved
-        return Optional.of(new MappedDependency(namespace,
-                QName.create(ObjectNameUtil.getServiceQName(on)).getLocalName(), refName));
-    }
-
-    public static class MappedDependency {
-        private final String namespace, serviceName, refName;
-
-        public MappedDependency(String namespace, String serviceName, String refName) {
-            this.serviceName = serviceName;
-            this.refName = refName;
-            this.namespace = namespace;
-        }
-
-        public String getServiceName() {
-            return serviceName;
-        }
-
-        public String getRefName() {
-            return refName;
-        }
-
-        public String getNamespace() {
-            return namespace;
-        }
-
-        @Override
-        public String toString() {
-            final StringBuffer sb = new StringBuffer("MappedDependency{");
-            sb.append("namespace='").append(namespace).append('\'');
-            sb.append(", serviceName='").append(serviceName).append('\'');
-            sb.append(", refName='").append(refName).append('\'');
-            sb.append('}');
-            return sb.toString();
-        }
-    }
-
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/SimpleAttributeMappingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/SimpleAttributeMappingStrategy.java
deleted file mode 100644 (file)
index 101649e..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.mapping;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Maps;
-import java.util.Date;
-import java.util.Map;
-import javax.management.openmbean.SimpleType;
-import org.opendaylight.controller.netconf.confignetconfconnector.util.Util;
-
-public class SimpleAttributeMappingStrategy extends AbstractAttributeMappingStrategy<String, SimpleType<?>> {
-
-    public SimpleAttributeMappingStrategy(SimpleType<?> openType) {
-        super(openType);
-    }
-
-    @Override
-    public Optional<String> mapAttribute(Object value) {
-        if (value == null){
-            return Optional.absent();
-        }
-
-        String expectedClass = getOpenType().getClassName();
-        String realClass = value.getClass().getName();
-        Preconditions.checkArgument(realClass.equals(expectedClass), "Type mismatch, expected " + expectedClass
-                + " but was " + realClass);
-
-        WriterPlugin prefferedPlugin = writerPlugins.get(value.getClass().getCanonicalName());
-        prefferedPlugin = prefferedPlugin == null ? writerPlugins.get(DEFAULT_WRITER_PLUGIN) : prefferedPlugin;
-        return Optional.of(prefferedPlugin.writeObject(value));
-    }
-
-    private static final String DEFAULT_WRITER_PLUGIN = "default";
-    private static final Map<String, WriterPlugin> writerPlugins = Maps.newHashMap();
-    static {
-        writerPlugins.put(DEFAULT_WRITER_PLUGIN, new DefaultWriterPlugin());
-        writerPlugins.put(Date.class.getCanonicalName(), new DatePlugin());
-    }
-
-    /**
-     * Custom writer plugins must implement this interface.
-     */
-    static interface WriterPlugin {
-        String writeObject(Object value);
-    }
-
-    static class DefaultWriterPlugin implements WriterPlugin {
-
-        @Override
-        public String writeObject(Object value) {
-            return value.toString();
-        }
-    }
-
-    static class DatePlugin implements WriterPlugin {
-
-        @Override
-        public String writeObject(Object value) {
-            Preconditions.checkArgument(value instanceof Date, "Attribute must be Date");
-            return Util.writeDate((Date) value);
-        }
-    }
-
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/UnionCompositeAttributeMappingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/UnionCompositeAttributeMappingStrategy.java
deleted file mode 100644 (file)
index 033ab43..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.mapping;
-
-import com.google.common.base.Optional;
-import java.util.Map;
-import javax.management.openmbean.CompositeDataSupport;
-import javax.management.openmbean.CompositeType;
-import javax.management.openmbean.OpenType;
-import org.opendaylight.controller.config.yangjmxgenerator.attribute.JavaAttribute;
-
-public class UnionCompositeAttributeMappingStrategy extends
-        CompositeAttributeMappingStrategy {
-
-
-    public UnionCompositeAttributeMappingStrategy(CompositeType compositeType, Map<String, AttributeMappingStrategy<?, ? extends OpenType<?>>> innerStrategies, Map<String, String> jmxToJavaNameMapping) {
-        super(compositeType, innerStrategies, jmxToJavaNameMapping);
-    }
-
-    @Override
-    protected Optional<?> mapInnerAttribute(CompositeDataSupport compositeData, String jmxName, String description) {
-        if(!description.equals(JavaAttribute.DESCRIPTION_OF_VALUE_ATTRIBUTE_FOR_UNION)){
-            return Optional.absent();
-        }
-        return super.mapInnerAttribute(compositeData, jmxName, description);
-    }
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/AbstractAttributeResolvingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/AbstractAttributeResolvingStrategy.java
deleted file mode 100644 (file)
index 5763ed8..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.resolving;
-
-import javax.management.openmbean.OpenType;
-
-abstract class AbstractAttributeResolvingStrategy<T, O extends OpenType<?>> implements AttributeResolvingStrategy<T, O> {
-    private O openType;
-
-    public AbstractAttributeResolvingStrategy(O openType) {
-        this.openType = openType;
-    }
-
-    @Override
-    public O getOpenType() {
-        return openType;
-    }
-
-    /**
-     * Composite types might change during resolution. Use this setter to update open type
-     */
-    public void setOpenType(final O openType) {
-        this.openType = openType;
-    }
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ArrayAttributeResolvingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ArrayAttributeResolvingStrategy.java
deleted file mode 100644 (file)
index 9c17fa4..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.resolving;
-
-import com.google.common.base.Optional;
-import java.lang.reflect.Array;
-import java.util.List;
-import javax.management.openmbean.ArrayType;
-import javax.management.openmbean.CompositeDataSupport;
-import javax.management.openmbean.CompositeType;
-import javax.management.openmbean.OpenDataException;
-import javax.management.openmbean.OpenType;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.confignetconfconnector.util.Util;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-final class ArrayAttributeResolvingStrategy extends AbstractAttributeResolvingStrategy<Object, ArrayType<?>> {
-
-    private final AttributeResolvingStrategy<?, ? extends OpenType<?>> innerTypeResolvingStrategy;
-
-    private static final Logger LOG = LoggerFactory.getLogger(ArrayAttributeResolvingStrategy.class);
-
-    public ArrayAttributeResolvingStrategy(AttributeResolvingStrategy<?, ? extends OpenType<?>> innerTypeResolved,
-            ArrayType<?> openType) {
-        super(openType);
-        this.innerTypeResolvingStrategy = innerTypeResolved;
-    }
-
-    @Override
-    public Optional<Object> parseAttribute(String attrName, Object value) throws NetconfDocumentedException {
-        if (value == null) {
-            return Optional.absent();
-        }
-
-        Util.checkType(value, List.class);
-        List<?> valueList = (List<?>) value;
-
-        Class<?> innerTypeClass = null;
-
-        if (innerTypeResolvingStrategy.getOpenType() instanceof CompositeType) {
-            innerTypeClass = CompositeDataSupport.class;
-        } else {
-            try {
-                innerTypeClass = Class.forName(getOpenType().getElementOpenType().getClassName());
-            } catch (ClassNotFoundException e) {
-                throw new IllegalStateException("Unable to locate class for "
-                        + getOpenType().getElementOpenType().getClassName(), e);
-            }
-        }
-
-        Object parsedArray = null;
-
-        if (getOpenType().isPrimitiveArray()) {
-            Class<?> primitiveType = getPrimitiveType(innerTypeClass);
-            parsedArray = Array.newInstance(primitiveType, valueList.size());
-        } else {
-            parsedArray = Array.newInstance(innerTypeClass, valueList.size());
-        }
-
-        int i = 0;
-        for (Object innerValue : valueList) {
-            Optional<?> parsedElement = innerTypeResolvingStrategy.parseAttribute(attrName + "_" + i, innerValue);
-            if (!parsedElement.isPresent()){
-                continue;
-            }
-            Array.set(parsedArray, i, parsedElement.get());
-            i++;
-        }
-
-        // Rebuild open type. Underlying composite types might have changed
-        if (innerTypeResolvingStrategy.getOpenType() instanceof CompositeType) {
-            try {
-                final ArrayType<?> openType = new ArrayType<Object>(getOpenType().getDimension(), innerTypeResolvingStrategy.getOpenType());
-                setOpenType(openType);
-            } catch (OpenDataException e) {
-                throw new IllegalStateException("An error occurred during restoration of array type " + this
-                        + " for attribute " + attrName + " from value " + value, e);
-            }
-        }
-
-        LOG.debug("Attribute {} : {} parsed to type {} as {}", attrName, value, getOpenType(),
-                toStringArray(parsedArray));
-
-        return Optional.of(parsedArray);
-    }
-
-    private static String toStringArray(Object array) {
-        StringBuilder build = new StringBuilder(array.toString());
-        build.append(" [");
-        for (int i = 0; i < Array.getLength(array); i++) {
-            build.append(Array.get(array, i).toString());
-            build.append(",");
-        }
-        build.append("]]");
-        return build.toString();
-    }
-
-    private static Class<?> getPrimitiveType(Class<?> innerTypeClass) {
-        try {
-            return (Class<?>) innerTypeClass.getField("TYPE").get(null);
-        } catch (Exception e) {
-            throw new IllegalStateException("Unable to determine primitive type to " + innerTypeClass);
-        }
-    }
-
-    @Override
-    public String toString() {
-        return "ResolvedArrayTypeAttributeType [innerTypeResolved=" + innerTypeResolvingStrategy + "]";
-    }
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/AttributeResolvingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/AttributeResolvingStrategy.java
deleted file mode 100644 (file)
index 23d01de..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.resolving;
-
-import com.google.common.base.Optional;
-import javax.management.openmbean.OpenType;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-
-/**
- * Create real object from String or Map that corresponds to given opentype.
- */
-public interface AttributeResolvingStrategy<T, O extends OpenType<?>> {
-    O getOpenType();
-
-    Optional<T> parseAttribute(String attrName, Object value) throws NetconfDocumentedException;
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/CompositeAttributeResolvingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/CompositeAttributeResolvingStrategy.java
deleted file mode 100644 (file)
index b912a49..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.resolving;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Maps;
-import java.util.Map;
-import javax.management.openmbean.CompositeDataSupport;
-import javax.management.openmbean.CompositeType;
-import javax.management.openmbean.OpenDataException;
-import javax.management.openmbean.OpenType;
-import javax.management.openmbean.SimpleType;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.confignetconfconnector.util.Util;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-class CompositeAttributeResolvingStrategy extends
-        AbstractAttributeResolvingStrategy<CompositeDataSupport, CompositeType> {
-    private final Map<String, AttributeResolvingStrategy<?, ? extends OpenType<?>>> innerTypes;
-    private final Map<String, String> yangToJavaAttrMapping;
-
-    private static final Logger LOG = LoggerFactory.getLogger(CompositeAttributeResolvingStrategy.class);
-
-    CompositeAttributeResolvingStrategy(Map<String, AttributeResolvingStrategy<?, ? extends OpenType<?>>> innerTypes,
-            CompositeType openType, Map<String, String> yangToJavaAttrMapping) {
-        super(openType);
-        this.innerTypes = innerTypes;
-        this.yangToJavaAttrMapping = yangToJavaAttrMapping;
-    }
-
-    @Override
-    public String toString() {
-        return "ResolvedCompositeAttribute [" + innerTypes + "]";
-    }
-
-    @Override
-    public Optional<CompositeDataSupport> parseAttribute(String attrName, Object value) throws NetconfDocumentedException {
-
-        if (value == null) {
-            return Optional.absent();
-        }
-
-        Util.checkType(value, Map.class);
-        Map<?, ?> valueMap = (Map<?, ?>) value;
-        valueMap = preprocessValueMap(valueMap);
-
-        Map<String, Object> items = Maps.newHashMap();
-        Map<String, OpenType<?>> openTypes = Maps.newHashMap();
-
-        final String[] names = new String[getOpenType().keySet().size()];
-        final String[] descriptions = new String[getOpenType().keySet().size()];
-        OpenType<?>[] itemTypes = new OpenType[names.length];
-        int i = 0;
-
-        for (Object innerAttrName : innerTypes.keySet()) {
-            Preconditions.checkState(innerAttrName instanceof String, "Attribute name must be string");
-            String innerAttrNameStr = (String) innerAttrName;
-
-            AttributeResolvingStrategy<?, ? extends OpenType<?>> attributeResolvingStrategy = innerTypes
-                    .get(innerAttrName);
-
-            Object valueToParse = valueMap.get(innerAttrName);
-
-            Optional<?> parsedInnerValue = attributeResolvingStrategy.parseAttribute(innerAttrNameStr, valueToParse);
-
-            if(attributeResolvingStrategy instanceof EnumAttributeResolvingStrategy) {
-                // Open type for enum contain the class name necessary for its resolution, however in a DTO
-                // the open type need to be just SimpleType.STRING so that JMX is happy
-                // After the enum attribute is resolved, change its open type back to STRING
-                openTypes.put(innerAttrNameStr, SimpleType.STRING);
-            } else {
-                openTypes.put(innerAttrNameStr, attributeResolvingStrategy.getOpenType());
-            }
-
-            items.put(yangToJavaAttrMapping.get(innerAttrNameStr),
-                    parsedInnerValue.isPresent() ? parsedInnerValue.get() : null);
-
-            // fill names + item types in order to reconstruct the open type for current attribute
-            names[i] = yangToJavaAttrMapping.get(innerAttrNameStr);
-            descriptions[i] = getOpenType().getDescription(names[i]);
-            itemTypes[i] = openTypes.get(innerAttrNameStr);
-            i++;
-        }
-
-        CompositeDataSupport parsedValue;
-        try {
-            LOG.trace("Attribute {} with open type {}. Reconstructing open type.", attrName, getOpenType());
-            setOpenType(new CompositeType(getOpenType().getTypeName(), getOpenType().getDescription(), names, descriptions, itemTypes));
-            LOG.debug("Attribute {}. Open type reconstructed to {}", attrName, getOpenType(), getOpenType());
-            parsedValue = new CompositeDataSupport(getOpenType(), items);
-        } catch (OpenDataException e) {
-            throw new IllegalStateException("An error occurred during restoration of composite type " + this
-                    + " for attribute " + attrName + " from value " + value, e);
-        }
-
-        LOG.debug("Attribute {} : {} parsed to type {} as {}", attrName, value, getOpenType(), parsedValue);
-
-        return Optional.of(parsedValue);
-    }
-
-
-    protected Map<?, ?> preprocessValueMap(Map<?, ?> valueMap) {
-        return valueMap;
-    }
-
-
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/EnumAttributeResolvingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/EnumAttributeResolvingStrategy.java
deleted file mode 100644 (file)
index 25c4da1..0000000
+++ /dev/null
@@ -1,55 +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.netconf.confignetconfconnector.mapping.attributes.resolving;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import java.util.Map;
-import javax.management.openmbean.CompositeType;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.confignetconfconnector.osgi.EnumResolver;
-import org.opendaylight.controller.netconf.confignetconfconnector.util.Util;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-final class EnumAttributeResolvingStrategy extends AbstractAttributeResolvingStrategy<Object, CompositeType> {
-
-    private static final Logger LOG = LoggerFactory.getLogger(EnumAttributeResolvingStrategy.class);
-    private final EnumResolver enumResolver;
-
-    EnumAttributeResolvingStrategy(CompositeType simpleType, final EnumResolver enumResolver) {
-        super(simpleType);
-        this.enumResolver = enumResolver;
-    }
-
-    @Override
-    public String toString() {
-        return "ResolvedEnumAttribute [" + getOpenType().getClassName() + "]";
-    }
-
-    @Override
-    public Optional<Object> parseAttribute(String attrName, Object value) throws NetconfDocumentedException {
-        if (value == null) {
-            return Optional.absent();
-        }
-
-        Util.checkType(value, Map.class);
-        Map<?, ?> valueMap = (Map<?, ?>) value;
-        Preconditions.checkArgument(valueMap.size() == 1, "Unexpected value size " + value + " should be just 1 foe enum");
-        final Object innerValue = valueMap.values().iterator().next();
-        Util.checkType(innerValue, String.class);
-
-        final String className = getOpenType().getTypeName();
-        final Object parsedValue = enumResolver.fromYang(className, ((String) innerValue));
-
-        LOG.debug("Attribute {} : {} parsed to enum type {} with value {}", attrName, innerValue, getOpenType(), parsedValue);
-        return Optional.of(parsedValue);
-    }
-
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectNameAttributeResolvingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectNameAttributeResolvingStrategy.java
deleted file mode 100644 (file)
index 34b4a8e..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.resolving;
-
-import com.google.common.base.Optional;
-import javax.management.ObjectName;
-import javax.management.openmbean.SimpleType;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.mapping.ObjectNameAttributeMappingStrategy;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
-import org.opendaylight.controller.netconf.confignetconfconnector.util.Util;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ObjectNameAttributeResolvingStrategy extends AbstractAttributeResolvingStrategy<ObjectName, SimpleType<?>> {
-
-    private final ServiceRegistryWrapper serviceTracker;
-    private static final Logger LOG = LoggerFactory.getLogger(ObjectNameAttributeResolvingStrategy.class);
-
-    ObjectNameAttributeResolvingStrategy(ServiceRegistryWrapper serviceTracker) {
-        super(SimpleType.OBJECTNAME);
-        this.serviceTracker = serviceTracker;
-    }
-
-    @Override
-    public Optional<ObjectName> parseAttribute(String attrName, Object value) {
-        if (value == null) {
-            return Optional.absent();
-        }
-
-        Util.checkType(value, ObjectNameAttributeMappingStrategy.MappedDependency.class);
-
-        ObjectNameAttributeMappingStrategy.MappedDependency mappedDep = (ObjectNameAttributeMappingStrategy.MappedDependency) value;
-        String serviceName = mappedDep.getServiceName();
-        String refName = mappedDep.getRefName();
-        String namespace = mappedDep.getNamespace();
-        LOG.trace("Getting service instance by service name {} : {} and ref name {}", namespace, serviceName, refName);
-
-        ObjectName on = serviceTracker.getByServiceAndRefName(namespace, serviceName, refName);
-
-        LOG.debug("Attribute {} : {} parsed to type {}", attrName, value, getOpenType());
-        return Optional.of(on);
-    }
-
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectResolver.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectResolver.java
deleted file mode 100644 (file)
index 93c83eb..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.resolving;
-
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Maps;
-import java.util.Map;
-import java.util.Map.Entry;
-import javax.management.openmbean.ArrayType;
-import javax.management.openmbean.CompositeType;
-import javax.management.openmbean.OpenType;
-import javax.management.openmbean.SimpleType;
-import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIfc;
-import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListAttribute;
-import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListDependenciesAttribute;
-import org.opendaylight.controller.config.yangjmxgenerator.attribute.TOAttribute;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.AttributeIfcSwitchStatement;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
-import org.opendaylight.controller.netconf.confignetconfconnector.osgi.EnumResolver;
-
-public class ObjectResolver extends AttributeIfcSwitchStatement<AttributeResolvingStrategy<?, ? extends OpenType<?>>> {
-
-    private final ServiceRegistryWrapper serviceTracker;
-    private EnumResolver enumResolver;
-
-    public ObjectResolver(ServiceRegistryWrapper serviceTracker) {
-        this.serviceTracker = serviceTracker;
-    }
-
-    public Map<String, AttributeResolvingStrategy<?, ? extends OpenType<?>>> prepareResolving(
-            Map<String, AttributeIfc> configDefinition, final EnumResolver enumResolver) {
-        this.enumResolver = enumResolver;
-
-        Map<String, AttributeResolvingStrategy<?, ? extends OpenType<?>>> strategies = Maps.newHashMap();
-
-        for (Entry<String, AttributeIfc> attrEntry : configDefinition.entrySet()) {
-            strategies.put(attrEntry.getKey(),
-                    prepareStrategy(attrEntry.getValue()));
-        }
-
-        return strategies;
-    }
-
-    private AttributeResolvingStrategy<?, ? extends OpenType<?>> prepareStrategy(AttributeIfc attributeIfc) {
-        return switchAttribute(attributeIfc);
-    }
-
-    private Map<String, String> createYangToJmxMapping(TOAttribute attributeIfc) {
-        Map<String, String> retVal = Maps.newHashMap();
-        for (Entry<String, AttributeIfc> entry : attributeIfc.getYangPropertiesToTypesMap().entrySet()) {
-            retVal.put(entry.getKey(), (entry.getValue()).getLowerCaseCammelCase());
-        }
-        return retVal;
-    }
-
-    @Override
-    protected AttributeResolvingStrategy<?, ? extends OpenType<?>> caseJavaEnumAttribute(final OpenType<?> openType) {
-        return new EnumAttributeResolvingStrategy((CompositeType) openType, enumResolver);
-    }
-
-    @Override
-    protected AttributeResolvingStrategy<?, ? extends OpenType<?>>  caseJavaSimpleAttribute(SimpleType<?> openType) {
-        return new SimpleAttributeResolvingStrategy(openType);
-    }
-
-    @Override
-    protected AttributeResolvingStrategy<?, ? extends OpenType<?>>  caseJavaArrayAttribute(ArrayType<?> openType) {
-
-        SimpleType<?> innerType = (SimpleType<?>) openType.getElementOpenType();
-        AttributeResolvingStrategy<?, ? extends OpenType<?>> strat = new SimpleAttributeResolvingStrategy(innerType);
-        return new ArrayAttributeResolvingStrategy(strat, openType);
-    }
-
-    @Override
-    protected AttributeResolvingStrategy<?, ? extends OpenType<?>>  caseJavaCompositeAttribute(CompositeType openType) {
-        Map<String, AttributeResolvingStrategy<?, ? extends OpenType<?>>> innerMap = Maps.newHashMap();
-        Map<String, String> yangToJmxMapping = Maps.newHashMap();
-
-        fillMappingForComposite(openType, innerMap, yangToJmxMapping);
-        return new CompositeAttributeResolvingStrategy(innerMap, openType, yangToJmxMapping);
-    }
-
-    private void fillMappingForComposite(CompositeType openType, Map<String, AttributeResolvingStrategy<?, ? extends OpenType<?>>> innerMap, Map<String, String> yangToJmxMapping) {
-        for (String innerAttributeKey : openType.keySet()) {
-            innerMap.put(innerAttributeKey, caseJavaAttribute(openType.getType(innerAttributeKey)));
-            yangToJmxMapping.put(innerAttributeKey, innerAttributeKey);
-        }
-    }
-
-    @Override
-    protected AttributeResolvingStrategy<?, ? extends OpenType<?>> caseJavaUnionAttribute(OpenType<?> openType) {
-
-        Preconditions.checkState(openType instanceof CompositeType, "Unexpected open type, expected %s but was %s");
-        CompositeType compositeType = (CompositeType) openType;
-
-        Map<String, AttributeResolvingStrategy<?, ? extends OpenType<?>>> innerMap = Maps.newHashMap();
-        Map<String, String> yangToJmxMapping = Maps.newHashMap();
-        fillMappingForComposite(compositeType, innerMap, yangToJmxMapping);
-
-        return new UnionCompositeAttributeResolvingStrategy(innerMap, compositeType, yangToJmxMapping);
-    }
-
-    @Override
-    protected AttributeResolvingStrategy<?, ? extends OpenType<?>> caseDependencyAttribute(
-            SimpleType<?> openType) {
-        return new ObjectNameAttributeResolvingStrategy(serviceTracker);
-    }
-
-    @Override
-    protected AttributeResolvingStrategy<?, ? extends OpenType<?>> caseTOAttribute(CompositeType openType) {
-        Preconditions.checkState(getLastAttribute() instanceof TOAttribute);
-        TOAttribute toAttribute = (TOAttribute) getLastAttribute();
-
-        Map<String, AttributeResolvingStrategy<?, ? extends OpenType<?>>> innerMap = Maps.newHashMap();
-
-        for (String innerName : openType.keySet()) {
-
-            AttributeIfc innerAttributeIfc = toAttribute.getJmxPropertiesToTypesMap().get(innerName);
-            innerMap.put(innerAttributeIfc.getAttributeYangName(),
-                    prepareStrategy(innerAttributeIfc));
-        }
-        return new CompositeAttributeResolvingStrategy(innerMap, openType, createYangToJmxMapping(toAttribute));
-    }
-
-    @Override
-    protected AttributeResolvingStrategy<?, ? extends OpenType<?>> caseListAttribute(ArrayType<?> openType) {
-        Preconditions.checkState(getLastAttribute() instanceof ListAttribute);
-        AttributeIfc innerAttribute = ((ListAttribute) getLastAttribute()).getInnerAttribute();
-        return new ArrayAttributeResolvingStrategy(prepareStrategy(innerAttribute), openType);
-    }
-
-    @Override
-    protected AttributeResolvingStrategy<?, ? extends OpenType<?>> caseListDependeciesAttribute(ArrayType<?> openType) {
-        Preconditions.checkState(getLastAttribute() instanceof ListDependenciesAttribute);
-        return new ArrayAttributeResolvingStrategy(caseDependencyAttribute(SimpleType.OBJECTNAME), openType);
-    }
-
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/SimpleAttributeResolvingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/SimpleAttributeResolvingStrategy.java
deleted file mode 100644 (file)
index f1e603c..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.resolving;
-
-import com.google.common.base.Optional;
-import com.google.common.collect.Maps;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.text.ParseException;
-import java.util.Date;
-import java.util.Map;
-import javax.management.openmbean.SimpleType;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.confignetconfconnector.util.Util;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-final class SimpleAttributeResolvingStrategy extends AbstractAttributeResolvingStrategy<Object, SimpleType<?>> {
-
-    private static final Logger LOG = LoggerFactory.getLogger(SimpleAttributeResolvingStrategy.class);
-
-    SimpleAttributeResolvingStrategy(SimpleType<?> simpleType) {
-        super(simpleType);
-    }
-
-    @Override
-    public String toString() {
-        return "ResolvedSimpleAttribute [" + getOpenType().getClassName() + "]";
-    }
-
-    @Override
-    public Optional<Object> parseAttribute(String attrName, Object value) throws NetconfDocumentedException {
-        if (value == null) {
-            return Optional.absent();
-        }
-
-        Class<?> cls;
-        try {
-            cls = Class.forName(getOpenType().getClassName());
-        } catch (ClassNotFoundException e) {
-            throw new RuntimeException("Unable to locate class for " + getOpenType().getClassName(), e);
-        }
-
-        Util.checkType(value, String.class);
-
-        Resolver prefferedPlugin = resolverPlugins.get(cls.getCanonicalName());
-        prefferedPlugin = prefferedPlugin == null ? resolverPlugins.get(DEFAULT_RESOLVERS) : prefferedPlugin;
-
-        Object parsedValue = prefferedPlugin.resolveObject(cls, attrName, (String) value);
-        LOG.debug("Attribute {} : {} parsed to type {} with value {}", attrName, value, getOpenType(), parsedValue);
-        return Optional.of(parsedValue);
-    }
-
-    private static final String DEFAULT_RESOLVERS = "default";
-    private static final Map<String, Resolver> resolverPlugins = Maps.newHashMap();
-
-    static {
-        resolverPlugins.put(DEFAULT_RESOLVERS, new DefaultResolver());
-        resolverPlugins.put(String.class.getCanonicalName(), new StringResolver());
-        resolverPlugins.put(Date.class.getCanonicalName(), new DateResolver());
-        resolverPlugins.put(Character.class.getCanonicalName(), new CharResolver());
-        resolverPlugins.put(BigInteger.class.getCanonicalName(), new BigIntegerResolver());
-        resolverPlugins.put(BigDecimal.class.getCanonicalName(), new BigDecimalResolver());
-    }
-
-    static interface Resolver {
-        Object resolveObject(Class<?> type, String attrName, String value) throws NetconfDocumentedException;
-    }
-
-    static class DefaultResolver implements Resolver {
-
-        @Override
-        public Object resolveObject(Class<?> type, String attrName, String value) throws NetconfDocumentedException {
-            try {
-                return parseObject(type, value);
-            } catch (Exception e) {
-                throw new NetconfDocumentedException("Unable to resolve attribute " + attrName + " from " + value,
-                        NetconfDocumentedException.ErrorType.application,
-                        NetconfDocumentedException.ErrorTag.operation_failed,
-                        NetconfDocumentedException.ErrorSeverity.error);
-            }
-        }
-
-        protected Object parseObject(Class<?> type, String value) throws NetconfDocumentedException {
-            Method method = null;
-            try {
-                method = type.getMethod("valueOf", String.class);
-                return method.invoke(null, value);
-            } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
-                LOG.trace("Error parsing object ",e);
-                throw new NetconfDocumentedException("Error parsing object.",
-                        NetconfDocumentedException.ErrorType.application,
-                        NetconfDocumentedException.ErrorTag.operation_failed,
-                        NetconfDocumentedException.ErrorSeverity.error);
-            }
-        }
-    }
-
-    static class StringResolver extends DefaultResolver {
-
-        @Override
-        protected Object parseObject(Class<?> type, String value) {
-            return value;
-        }
-    }
-
-    static class BigIntegerResolver extends DefaultResolver {
-
-        @Override
-        protected Object parseObject(Class<?> type, String value) {
-            return new BigInteger(value);
-        }
-    }
-
-    static class BigDecimalResolver extends DefaultResolver {
-
-        @Override
-        protected Object parseObject(Class<?> type, String value) {
-            return new BigDecimal(value);
-        }
-    }
-
-    static class CharResolver extends DefaultResolver {
-
-        @Override
-        protected Object parseObject(Class<?> type, String value)  {
-            return value.charAt(0);
-        }
-    }
-
-    static class DateResolver extends DefaultResolver {
-        @Override
-        protected Object parseObject(Class<?> type, String value) throws NetconfDocumentedException {
-            try {
-                return Util.readDate(value);
-            } catch (ParseException e) {
-                LOG.trace("Unable parse value {} due to ",value, e);
-                throw new NetconfDocumentedException("Unable to parse value "+value+" as date.",
-                        NetconfDocumentedException.ErrorType.application,
-                        NetconfDocumentedException.ErrorTag.operation_failed,
-                        NetconfDocumentedException.ErrorSeverity.error);
-            }
-        }
-    }
-
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/UnionCompositeAttributeResolvingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/UnionCompositeAttributeResolvingStrategy.java
deleted file mode 100644 (file)
index 4cab995..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.resolving;
-
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Maps;
-import java.util.Map;
-import javax.management.openmbean.CompositeType;
-import javax.management.openmbean.OpenType;
-import org.opendaylight.controller.config.yangjmxgenerator.attribute.JavaAttribute;
-
-final class UnionCompositeAttributeResolvingStrategy extends CompositeAttributeResolvingStrategy {
-
-    UnionCompositeAttributeResolvingStrategy(Map<String, AttributeResolvingStrategy<?, ? extends OpenType<?>>> innerTypes,
-                                        CompositeType openType, Map<String, String> yangToJavaAttrMapping) {
-        super(innerTypes, openType, yangToJavaAttrMapping);
-    }
-
-    protected Map<String, Object> preprocessValueMap(Map<?, ?> valueMap) {
-        CompositeType openType = getOpenType();
-
-        Preconditions.checkArgument(
-                valueMap.size() == 1 && valueMap.containsKey(JavaAttribute.DESCRIPTION_OF_VALUE_ATTRIBUTE_FOR_UNION),
-                "Unexpected structure of incoming map, expecting one element under %s, but was %s",
-                JavaAttribute.DESCRIPTION_OF_VALUE_ATTRIBUTE_FOR_UNION, valueMap);
-
-        Map<String, Object> newMap = Maps.newHashMap();
-
-        for (String key : openType.keySet()) {
-            if (openType.getDescription(key).equals(JavaAttribute.DESCRIPTION_OF_VALUE_ATTRIBUTE_FOR_UNION)){
-                newMap.put(key, valueMap.get(JavaAttribute.DESCRIPTION_OF_VALUE_ATTRIBUTE_FOR_UNION));
-            } else {
-                newMap.put(key, null);
-            }
-        }
-        return newMap;
-    }
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/ArrayAttributeWritingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/ArrayAttributeWritingStrategy.java
deleted file mode 100644 (file)
index e888e4d..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.toxml;
-
-import java.util.List;
-import org.opendaylight.controller.netconf.confignetconfconnector.util.Util;
-import org.w3c.dom.Element;
-
-public class ArrayAttributeWritingStrategy implements AttributeWritingStrategy {
-
-    private final AttributeWritingStrategy innnerStrategy;
-
-    public ArrayAttributeWritingStrategy(AttributeWritingStrategy innerStrategy) {
-        this.innnerStrategy = innerStrategy;
-    }
-
-    @Override
-    public void writeElement(Element parentElement, String namespace, Object value) {
-        Util.checkType(value, List.class);
-
-        for (Object innerObject : ((List<?>) value)) {
-            innnerStrategy.writeElement(parentElement, namespace, innerObject);
-        }
-
-    }
-
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/AttributeWritingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/AttributeWritingStrategy.java
deleted file mode 100644 (file)
index d0c2b88..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.toxml;
-
-import org.w3c.dom.Element;
-
-public interface AttributeWritingStrategy {
-
-    void writeElement(Element parentElement, String namespace, Object value);
-
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/CompositeAttributeWritingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/CompositeAttributeWritingStrategy.java
deleted file mode 100644 (file)
index 11cb35c..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.toxml;
-
-import com.google.common.base.Optional;
-import java.util.Map;
-import java.util.Map.Entry;
-import org.opendaylight.controller.netconf.confignetconfconnector.util.Util;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-public class CompositeAttributeWritingStrategy implements AttributeWritingStrategy {
-
-    private final String key;
-    private final Document document;
-    private final Map<String, AttributeWritingStrategy> innerStrats;
-
-    public CompositeAttributeWritingStrategy(Document document, String key,
-            Map<String, AttributeWritingStrategy> innerStrats) {
-        this.document = document;
-        this.key = key;
-        this.innerStrats = innerStrats;
-    }
-
-    @Override
-    public void writeElement(Element parentElement, String namespace, Object value) {
-        Util.checkType(value, Map.class);
-
-        Element innerNode = XmlUtil.createElement(document, key, Optional.of(namespace));
-
-        Map<?, ?> map = (Map<?, ?>) value;
-
-        for (Entry<?, ?> innerObjectEntry : map.entrySet()) {
-            Util.checkType(innerObjectEntry.getKey(), String.class);
-
-            String innerKey = (String) innerObjectEntry.getKey();
-            Object innerValue = innerObjectEntry.getValue();
-
-            innerStrats.get(innerKey).writeElement(innerNode, namespace, innerValue);
-        }
-        parentElement.appendChild(innerNode);
-    }
-
-    public String getKey() {
-        return key;
-    }
-
-    public Document getDocument() {
-        return document;
-    }
-
-    public Map<String, AttributeWritingStrategy> getInnerStrats() {
-        return innerStrats;
-    }
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/ObjectNameAttributeWritingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/ObjectNameAttributeWritingStrategy.java
deleted file mode 100644 (file)
index 043aec6..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.toxml;
-
-import com.google.common.base.Optional;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.mapping.ObjectNameAttributeMappingStrategy;
-import org.opendaylight.controller.netconf.confignetconfconnector.util.Util;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-public class ObjectNameAttributeWritingStrategy implements AttributeWritingStrategy {
-
-    private final Document document;
-    private final String key;
-
-    /**
-     * @param document
-     * @param key
-     */
-    public ObjectNameAttributeWritingStrategy(Document document, String key) {
-        this.document = document;
-        this.key = key;
-    }
-
-    @Override
-    public void writeElement(Element parentElement, String namespace, Object value) {
-        Util.checkType(value, ObjectNameAttributeMappingStrategy.MappedDependency.class);
-        Element innerNode = XmlUtil.createElement(document, key, Optional.of(namespace));
-
-        String moduleName = ((ObjectNameAttributeMappingStrategy.MappedDependency) value).getServiceName();
-        String refName = ((ObjectNameAttributeMappingStrategy.MappedDependency) value).getRefName();
-        String namespaceForType = ((ObjectNameAttributeMappingStrategy.MappedDependency) value).getNamespace();
-
-        Element typeElement = XmlUtil.createTextElementWithNamespacedContent(document,  XmlNetconfConstants.TYPE_KEY, XmlNetconfConstants.PREFIX,
-                namespaceForType, moduleName);
-
-        innerNode.appendChild(typeElement);
-
-        final Element nameElement = XmlUtil.createTextElement(document, XmlNetconfConstants.NAME_KEY, refName, Optional.<String>absent());
-        innerNode.appendChild(nameElement);
-
-        parentElement.appendChild(innerNode);
-    }
-
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/ObjectXmlWriter.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/ObjectXmlWriter.java
deleted file mode 100644 (file)
index 022e370..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.toxml;
-
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Maps;
-import java.util.Map;
-import java.util.Map.Entry;
-import javax.management.openmbean.ArrayType;
-import javax.management.openmbean.CompositeType;
-import javax.management.openmbean.OpenType;
-import javax.management.openmbean.SimpleType;
-import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIfc;
-import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListAttribute;
-import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListDependenciesAttribute;
-import org.opendaylight.controller.config.yangjmxgenerator.attribute.TOAttribute;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.AttributeIfcSwitchStatement;
-import org.w3c.dom.Document;
-
-public class ObjectXmlWriter extends AttributeIfcSwitchStatement<AttributeWritingStrategy> {
-
-    private Document document;
-    private String key;
-
-    public Map<String, AttributeWritingStrategy> prepareWriting(Map<String, AttributeIfc> yangToAttrConfig,
-            Document document) {
-
-        Map<String, AttributeWritingStrategy> preparedWriting = Maps.newHashMap();
-
-        for (Entry<String, AttributeIfc> mappedAttributeEntry : yangToAttrConfig.entrySet()) {
-            String key = mappedAttributeEntry.getKey();
-            AttributeIfc value = mappedAttributeEntry.getValue();
-            AttributeWritingStrategy strat = prepareWritingStrategy(key, value, document);
-            preparedWriting.put(key, strat);
-        }
-
-        return preparedWriting;
-    }
-
-    public AttributeWritingStrategy prepareWritingStrategy(String key, AttributeIfc expectedAttr, Document document) {
-        Preconditions.checkNotNull(expectedAttr, "Mbean attributes mismatch, unable to find expected attribute for %s",
-                key);
-        this.document = document;
-        this.key = key;
-        return switchAttribute(expectedAttr);
-    }
-
-    @Override
-    protected AttributeWritingStrategy caseJavaBinaryAttribute(OpenType<?> openType) {
-        return new SimpleBinaryAttributeWritingStrategy(document, key);
-    }
-
-    @Override
-    protected AttributeWritingStrategy caseJavaEnumAttribute(final OpenType<?> openType) {
-        return new SimpleAttributeWritingStrategy(document, key);
-    }
-
-    @Override
-    protected AttributeWritingStrategy caseJavaSimpleAttribute(SimpleType<?> openType) {
-        return new SimpleAttributeWritingStrategy(document, key);
-    }
-
-    @Override
-    protected AttributeWritingStrategy caseJavaArrayAttribute(ArrayType<?> openType) {
-        AttributeWritingStrategy innerStrategy = new SimpleAttributeWritingStrategy(document, key);
-        return new ArrayAttributeWritingStrategy(innerStrategy);
-    }
-
-    @Override
-    protected AttributeWritingStrategy caseJavaIdentityRefAttribute(OpenType<?> openType) {
-        return new SimpleIdentityRefAttributeWritingStrategy(document, key);
-    }
-
-    @Override
-    protected AttributeWritingStrategy caseJavaCompositeAttribute(CompositeType openType) {
-        return new SimpleCompositeAttributeWritingStrategy(document, key);
-    }
-
-    @Override
-    protected AttributeWritingStrategy caseJavaUnionAttribute(OpenType<?> openType) {
-        return new SimpleUnionAttributeWritingStrategy(document, key);
-    }
-
-    @Override
-    protected AttributeWritingStrategy caseDependencyAttribute(SimpleType<?> openType) {
-        return new ObjectNameAttributeWritingStrategy(document, key);
-    }
-
-    @Override
-    protected AttributeWritingStrategy caseTOAttribute(CompositeType openType) {
-        Preconditions.checkState(getLastAttribute() instanceof TOAttribute);
-
-        Map<String, AttributeWritingStrategy> innerStrats = Maps.newHashMap();
-        String currentKey = key;
-        for (Entry<String, AttributeIfc> innerAttrEntry : ((TOAttribute) getLastAttribute()).getYangPropertiesToTypesMap().entrySet()) {
-
-            AttributeWritingStrategy innerStrategy = prepareWritingStrategy(innerAttrEntry.getKey(),
-                    innerAttrEntry.getValue(), document);
-            innerStrats.put(innerAttrEntry.getKey(), innerStrategy);
-        }
-
-        return new CompositeAttributeWritingStrategy(document, currentKey, innerStrats);
-    }
-
-    @Override
-    protected AttributeWritingStrategy caseListAttribute(ArrayType<?> openType) {
-        Preconditions.checkState(getLastAttribute() instanceof ListAttribute);
-        AttributeIfc innerAttribute = ((ListAttribute) getLastAttribute()).getInnerAttribute();
-
-        AttributeWritingStrategy innerStrategy = prepareWritingStrategy(key, innerAttribute, document);
-        return new ArrayAttributeWritingStrategy(innerStrategy);
-    }
-
-    @Override
-    protected AttributeWritingStrategy caseListDependeciesAttribute(ArrayType<?> openType) {
-        Preconditions.checkState(getLastAttribute() instanceof ListDependenciesAttribute);
-        AttributeWritingStrategy innerStrategy = caseDependencyAttribute(SimpleType.OBJECTNAME);
-        return new ArrayAttributeWritingStrategy(innerStrategy);
-    }
-
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/RuntimeBeanEntryWritingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/RuntimeBeanEntryWritingStrategy.java
deleted file mode 100644 (file)
index ea53467..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.toxml;
-
-import com.google.common.base.Optional;
-import java.util.Map;
-import java.util.Map.Entry;
-import org.opendaylight.controller.netconf.confignetconfconnector.util.Util;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-public class RuntimeBeanEntryWritingStrategy extends CompositeAttributeWritingStrategy {
-
-    public RuntimeBeanEntryWritingStrategy(Document document, String key,
-            Map<String, AttributeWritingStrategy> innerStrats) {
-        super(document, key, innerStrats);
-    }
-
-    /*
-     * (non-Javadoc)
-     *
-     * @see org.opendaylight.controller.config.netconf.mapping.attributes.toxml.
-     * AttributeWritingStrategy#writeElement(org.w3c.dom.Element,
-     * java.lang.Object)
-     */
-    @Override
-    public void writeElement(Element parentElement, String namespace, Object value) {
-        Util.checkType(value, Map.class);
-
-        Element innerNode = XmlUtil.createElement(getDocument(), getKey(), Optional.<String>absent());
-
-        Map<?, ?> map = (Map<?, ?>) value;
-
-        for (Entry<?, ?> runtimeBeanInstanceMappingEntry : map.entrySet()) {
-
-            // wrap runtime attributes with number assigned to current runtime
-            // bean
-            Util.checkType(runtimeBeanInstanceMappingEntry.getValue(), Map.class);
-            Map<?, ?> innerMap = (Map<?, ?>) runtimeBeanInstanceMappingEntry.getValue();
-            Element runtimeInstanceNode = XmlUtil.createElement(getDocument(), "_"
-                    + runtimeBeanInstanceMappingEntry.getKey(), Optional.<String>absent());
-            innerNode.appendChild(runtimeInstanceNode);
-
-            for (Entry<?, ?> innerObjectEntry : innerMap.entrySet()) {
-
-                Util.checkType(innerObjectEntry.getKey(), String.class);
-
-                String innerKey = (String) innerObjectEntry.getKey();
-                Object innerValue = innerObjectEntry.getValue();
-
-                getInnerStrats().get(innerKey).writeElement(runtimeInstanceNode, namespace, innerValue);
-            }
-        }
-        parentElement.appendChild(innerNode);
-
-    }
-
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleAttributeWritingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleAttributeWritingStrategy.java
deleted file mode 100644 (file)
index 4b68b9a..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.toxml;
-
-import com.google.common.base.Optional;
-import org.opendaylight.controller.netconf.confignetconfconnector.util.Util;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-public class SimpleAttributeWritingStrategy implements AttributeWritingStrategy {
-
-    private final Document document;
-    private final String key;
-
-    /**
-     * @param document
-     * @param key
-     */
-    public SimpleAttributeWritingStrategy(Document document, String key) {
-        this.document = document;
-        this.key = key;
-    }
-
-    @Override
-    public void writeElement(Element parentElement, String namespace, Object value) {
-        value = preprocess(value);
-        Util.checkType(value, String.class);
-        Element innerNode = createElement(document, key, (String) value, Optional.of(namespace));
-        parentElement.appendChild(innerNode);
-    }
-
-    protected Element createElement(Document document, String key, String value, Optional<String> namespace) {
-        Element typeElement = XmlUtil.createElement(document, key, namespace);
-
-        typeElement.appendChild(document.createTextNode(value));
-        return typeElement;
-    }
-    protected Object preprocess(Object value) {
-        return value;
-    }
-
-
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleBinaryAttributeWritingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleBinaryAttributeWritingStrategy.java
deleted file mode 100644 (file)
index 8407ded..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.toxml;
-
-import com.google.common.base.Preconditions;
-import com.google.common.io.BaseEncoding;
-import java.util.List;
-import org.opendaylight.controller.netconf.confignetconfconnector.util.Util;
-import org.w3c.dom.Document;
-
-public class SimpleBinaryAttributeWritingStrategy extends SimpleAttributeWritingStrategy {
-
-    /**
-     * @param document
-     * @param key
-     */
-    public SimpleBinaryAttributeWritingStrategy(Document document, String key) {
-        super(document, key);
-    }
-
-    @Override
-    protected Object preprocess(Object value) {
-        Util.checkType(value, List.class);
-        BaseEncoding en = BaseEncoding.base64();
-
-        List<?> list = (List<?>) value;
-        byte[] decoded = new byte[list.size()];
-        int i = 0;
-        for (Object bAsStr : list) {
-            Preconditions.checkArgument(bAsStr instanceof String, "Unexpected inner value for %s, expected string", value);
-            byte b = Byte.parseByte((String) bAsStr);
-            decoded[i++] = b;
-        }
-
-        return en.encode(decoded);
-    }
-
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleCompositeAttributeWritingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleCompositeAttributeWritingStrategy.java
deleted file mode 100644 (file)
index eac7743..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.toxml;
-
-import com.google.common.base.Preconditions;
-import java.util.Map;
-import org.opendaylight.controller.netconf.confignetconfconnector.util.Util;
-import org.w3c.dom.Document;
-
-public class SimpleCompositeAttributeWritingStrategy extends SimpleAttributeWritingStrategy {
-
-    /**
-     * @param document
-     * @param key
-     */
-    public SimpleCompositeAttributeWritingStrategy(Document document, String key) {
-        super(document, key);
-    }
-
-    protected Object preprocess(Object value) {
-        Util.checkType(value, Map.class);
-        Preconditions.checkArgument(((Map<?, ?>)value).size() == 1, "Unexpected number of values in %s, expected 1", value);
-        return ((Map<?, ?>)value).values().iterator().next();
-    }
-
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleIdentityRefAttributeWritingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleIdentityRefAttributeWritingStrategy.java
deleted file mode 100644 (file)
index 069ccc1..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.toxml;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import java.util.Map;
-import org.opendaylight.controller.netconf.confignetconfconnector.util.Util;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-public class SimpleIdentityRefAttributeWritingStrategy extends SimpleAttributeWritingStrategy {
-
-    private static final String PREFIX = "prefix";
-
-    /**
-     * @param document
-     * @param key
-     */
-    public SimpleIdentityRefAttributeWritingStrategy(Document document, String key) {
-        super(document, key);
-    }
-
-    protected Object preprocess(Object value) {
-        Util.checkType(value, Map.class);
-        Preconditions.checkArgument(((Map<?, ?>)value).size() == 1, "Unexpected number of values in %s, expected 1", value);
-        Object stringValue = ((Map<?, ?>) value).values().iterator().next();
-        Util.checkType(stringValue, String.class);
-
-        return stringValue;
-    }
-
-    @Override
-    protected Element createElement(Document doc, String key, String value, Optional<String> namespace) {
-        QName qName = QName.create(value);
-        String identityValue = qName.getLocalName();
-        String identityNamespace = qName.getNamespace().toString();
-        return XmlUtil.createTextElementWithNamespacedContent(doc, key, PREFIX, identityNamespace, identityValue, namespace);
-    }
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleUnionAttributeWritingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleUnionAttributeWritingStrategy.java
deleted file mode 100644 (file)
index ee97b27..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.toxml;
-
-import com.google.common.base.Preconditions;
-import java.util.List;
-import java.util.Map;
-import org.opendaylight.controller.netconf.confignetconfconnector.util.Util;
-import org.w3c.dom.Document;
-
-public class SimpleUnionAttributeWritingStrategy extends SimpleAttributeWritingStrategy {
-
-    /**
-     * @param document
-     * @param key
-     */
-    public SimpleUnionAttributeWritingStrategy(Document document, String key) {
-        super(document, key);
-    }
-
-    protected Object preprocess(Object value) {
-        Util.checkType(value, Map.class);
-        Preconditions.checkArgument(((Map<?, ?>)value).size() == 1, "Unexpected number of values in %s, expected 1", value);
-        Object listOfStrings = ((Map<?, ?>) value).values().iterator().next();
-        Util.checkType(listOfStrings, List.class);
-
-        StringBuilder b = new StringBuilder();
-        for (Object character: (List<?>)listOfStrings) {
-            Util.checkType(character, String.class);
-            b.append(character);
-        }
-
-        return b.toString();
-    }
-
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Config.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Config.java
deleted file mode 100644 (file)
index c26b4cf..0000000
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.mapping.config;
-
-import static com.google.common.base.Preconditions.checkState;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Multimap;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import javax.management.ObjectName;
-import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfig;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditStrategyType;
-import org.opendaylight.controller.netconf.confignetconfconnector.osgi.EnumResolver;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-
-public class Config {
-
-    private final Map<String/* Namespace from yang file */,
-            Map<String /* Name of module entry from yang file */, ModuleConfig>> moduleConfigs;
-
-    private final Map<String, Map<Date, EditConfig.IdentityMapping>> identityMap;
-
-    private final EnumResolver enumResolver;
-
-    public Config(Map<String, Map<String, ModuleConfig>> moduleConfigs, final EnumResolver enumResolver) {
-        this(moduleConfigs, Collections.<String, Map<Date, EditConfig.IdentityMapping>>emptyMap(), enumResolver);
-    }
-
-    public Config(Map<String, Map<String, ModuleConfig>> moduleConfigs, Map<String, Map<Date, EditConfig.IdentityMapping>> identityMap, final EnumResolver enumResolver) {
-        this.moduleConfigs = moduleConfigs;
-        this.identityMap = identityMap;
-        this.enumResolver = enumResolver;
-    }
-
-    public static Map<String, Map<String, Collection<ObjectName>>> getMappedInstances(Set<ObjectName> instancesToMap,
-                                                                                Map<String, Map<String, ModuleConfig>> configs) {
-        Multimap<String, ObjectName> moduleToInstances = mapInstancesToModules(instancesToMap);
-
-        Map<String, Map<String, Collection<ObjectName>>> retVal = Maps.newLinkedHashMap();
-
-        for (Entry<String, Map<String, ModuleConfig>> namespaceToModuleToConfigEntry : configs.entrySet()) {
-
-            Map<String, Collection<ObjectName>> innerRetVal = Maps.newHashMap();
-
-            for (Entry<String, ModuleConfig> mbeEntry : namespaceToModuleToConfigEntry.getValue().entrySet()) {
-
-                String moduleName = mbeEntry.getKey();
-                Collection<ObjectName> instances = moduleToInstances.get(moduleName);
-
-                // TODO, this code does not support same module names from different namespaces
-                // Namespace should be present in ObjectName
-
-                if (instances == null){
-                    continue;
-                }
-
-                innerRetVal.put(moduleName, instances);
-
-            }
-
-            retVal.put(namespaceToModuleToConfigEntry.getKey(), innerRetVal);
-        }
-        return retVal;
-    }
-
-    private static Multimap<String, ObjectName> mapInstancesToModules(Set<ObjectName> instancesToMap) {
-        Multimap<String, ObjectName> retVal = HashMultimap.create();
-
-        for (ObjectName objectName : instancesToMap) {
-            String factoryName = ObjectNameUtil.getFactoryName(objectName);
-            retVal.put(factoryName, objectName);
-        }
-        return retVal;
-    }
-
-    public Element toXml(Set<ObjectName> instancesToMap, Optional<String> maybeNamespace, Document document,
-            Element dataElement, ServiceRegistryWrapper serviceTracker) {
-
-        Map<String, Map<String, Collection<ObjectName>>> moduleToInstances = getMappedInstances(instancesToMap,
-                moduleConfigs);
-
-        if (maybeNamespace.isPresent()) {
-            dataElement.setAttributeNS(maybeNamespace.get(), dataElement.getNodeName(), "xmlns");
-        }
-
-        Element modulesElement = XmlUtil.createElement(document, XmlNetconfConstants.MODULES_KEY, Optional.of(XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG));
-        dataElement.appendChild(modulesElement);
-        for (Entry<String, Map<String, Collection<ObjectName>>> moduleToInstanceEntry : moduleToInstances.entrySet()) {
-            for (Entry<String, Collection<ObjectName>> moduleMappingEntry : moduleToInstanceEntry.getValue()
-                    .entrySet()) {
-
-                ModuleConfig mapping = moduleConfigs.get(moduleToInstanceEntry.getKey()).get(moduleMappingEntry.getKey());
-
-                if (moduleMappingEntry.getValue().isEmpty()) {
-                    continue;
-                }
-
-                for (ObjectName objectName : moduleMappingEntry.getValue()) {
-                    modulesElement.appendChild(mapping.toXml(objectName, document, moduleToInstanceEntry.getKey(), enumResolver));
-                }
-
-            }
-        }
-
-        dataElement.appendChild(Services.toXml(serviceTracker, document));
-
-        return dataElement;
-    }
-
-    // TODO refactor, replace string representing namespace with namespace class
-    // TODO refactor, replace Map->Multimap with e.g. ConfigElementResolved
-    // class
-
-    public Map<String, Multimap<String, ModuleElementResolved>> fromXmlModulesResolved(XmlElement xml, EditStrategyType defaultEditStrategyType, ServiceRegistryWrapper serviceTracker) throws NetconfDocumentedException {
-        Optional<XmlElement> modulesElement = getModulesElement(xml);
-        List<XmlElement> moduleElements = getModulesElementList(modulesElement);
-
-        Map<String, Multimap<String, ModuleElementResolved>> retVal = Maps.newHashMap();
-
-        for (XmlElement moduleElement : moduleElements) {
-            ResolvingStrategy<ModuleElementResolved> resolvingStrategy = new ResolvingStrategy<ModuleElementResolved>() {
-                @Override
-                public ModuleElementResolved resolveElement(ModuleConfig moduleMapping, XmlElement moduleElement, ServiceRegistryWrapper serviceTracker, String instanceName, String moduleNamespace, EditStrategyType defaultStrategy) throws NetconfDocumentedException {
-                    return moduleMapping.fromXml(moduleElement, serviceTracker,
-                            instanceName, moduleNamespace, defaultStrategy, identityMap, enumResolver);
-                }
-            };
-
-            resolveModule(retVal, serviceTracker, moduleElement, defaultEditStrategyType, resolvingStrategy);
-        }
-        return retVal;
-    }
-
-    /**
-     * return a map containing namespace -> moduleName -> instanceName map. Attribute parsing is omitted.
-     */
-    public Map<String, Multimap<String, ModuleElementDefinition>> fromXmlModulesMap(XmlElement xml,
-            EditStrategyType defaultEditStrategyType, ServiceRegistryWrapper serviceTracker) throws NetconfDocumentedException {
-        Optional<XmlElement> modulesElement = getModulesElement(xml);
-        List<XmlElement> moduleElements = getModulesElementList(modulesElement);
-
-        Map<String, Multimap<String, ModuleElementDefinition>> retVal = Maps.newHashMap();
-
-        for (XmlElement moduleElement : moduleElements) {
-            ResolvingStrategy<ModuleElementDefinition> resolvingStrategy = new ResolvingStrategy<ModuleElementDefinition>() {
-                @Override
-                public ModuleElementDefinition resolveElement(ModuleConfig moduleMapping, XmlElement moduleElement,
-                        ServiceRegistryWrapper serviceTracker, String instanceName, String moduleNamespace,
-                        EditStrategyType defaultStrategy) {
-                    // TODO: add check for conflicts between global and local
-                    // edit strategy
-                    String perInstanceEditStrategy = moduleElement.getAttribute(XmlNetconfConstants.OPERATION_ATTR_KEY,
-                            XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
-                    return new ModuleElementDefinition(instanceName, perInstanceEditStrategy, defaultStrategy);
-                }
-            };
-
-            resolveModule(retVal, serviceTracker, moduleElement, defaultEditStrategyType, resolvingStrategy);
-        }
-        return retVal;
-    }
-
-    private static Optional<XmlElement> getModulesElement(XmlElement xml) {
-        return xml.getOnlyChildElementOptionally(XmlNetconfConstants.MODULES_KEY,
-                    XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG);
-    }
-
-    private List<XmlElement> getModulesElementList(Optional<XmlElement> modulesElement) throws NetconfDocumentedException {
-        List<XmlElement> moduleElements;
-
-        if (modulesElement.isPresent()) {
-            moduleElements = modulesElement.get().getChildElementsWithSameNamespace(XmlNetconfConstants.MODULE_KEY);
-            modulesElement.get().checkUnrecognisedElements(moduleElements);
-        } else {
-            moduleElements = Lists.newArrayList();
-        }
-        return moduleElements;
-    }
-
-    private <T> void resolveModule(Map<String, Multimap<String, T>> retVal, ServiceRegistryWrapper serviceTracker,
-            XmlElement moduleElement, EditStrategyType defaultStrategy, ResolvingStrategy<T> resolvingStrategy) throws NetconfDocumentedException {
-        XmlElement typeElement = null;
-        typeElement = moduleElement.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.TYPE_KEY);
-        Entry<String, String> prefixToNamespace = typeElement.findNamespaceOfTextContent();
-        String moduleNamespace = prefixToNamespace.getValue();
-        XmlElement nameElement = null;
-        nameElement = moduleElement.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.NAME_KEY);
-        String instanceName = nameElement.getTextContent();
-        String factoryNameWithPrefix = typeElement.getTextContent();
-        String prefixOrEmptyString = prefixToNamespace.getKey();
-        String factoryName = getFactoryName(factoryNameWithPrefix, prefixOrEmptyString);
-
-        ModuleConfig moduleMapping = getModuleMapping(moduleNamespace, instanceName, factoryName);
-
-        Multimap<String, T> innerMap = retVal.get(moduleNamespace);
-        if (innerMap == null) {
-            innerMap = HashMultimap.create();
-            retVal.put(moduleNamespace, innerMap);
-        }
-
-        T resolvedElement = resolvingStrategy.resolveElement(moduleMapping, moduleElement, serviceTracker,
-                instanceName, moduleNamespace, defaultStrategy);
-
-        innerMap.put(factoryName, resolvedElement);
-    }
-
-    public Services fromXmlServices(XmlElement xml) throws NetconfDocumentedException {
-        Optional<XmlElement> servicesElement = getServicesElement(xml);
-
-        Services services;
-        if (servicesElement.isPresent()) {
-            services = Services.fromXml(servicesElement.get());
-        } else {
-            services = new Services();
-        }
-
-        return services;
-    }
-
-    private static Optional<XmlElement> getServicesElement(XmlElement xml) {
-        return xml.getOnlyChildElementOptionally(XmlNetconfConstants.SERVICES_KEY,
-                    XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG);
-    }
-
-    public static void checkUnrecognisedChildren(XmlElement parent) throws NetconfDocumentedException {
-        Optional<XmlElement> servicesOpt = getServicesElement(parent);
-        Optional<XmlElement> modulesOpt = getModulesElement(parent);
-
-        List<XmlElement> recognised = Lists.newArrayList();
-        if(servicesOpt.isPresent()){
-            recognised.add(servicesOpt.get());
-        }
-        if(modulesOpt.isPresent()){
-            recognised.add(modulesOpt.get());
-        }
-
-        parent.checkUnrecognisedElements(recognised);
-    }
-
-    private String getFactoryName(String factoryNameWithPrefix, String prefixOrEmptyString) {
-        checkState(
-                factoryNameWithPrefix.startsWith(prefixOrEmptyString),
-                String.format("Internal error: text " + "content '%s' of type node does not start with prefix '%s'",
-                        factoryNameWithPrefix, prefixOrEmptyString));
-
-        int factoryNameAfterPrefixIndex;
-        if (prefixOrEmptyString.isEmpty()) {
-            factoryNameAfterPrefixIndex = 0;
-        } else {
-            factoryNameAfterPrefixIndex = prefixOrEmptyString.length() + 1;
-        }
-        return factoryNameWithPrefix.substring(factoryNameAfterPrefixIndex);
-    }
-
-    private ModuleConfig getModuleMapping(String moduleNamespace, String instanceName, String factoryName) {
-        Map<String, ModuleConfig> mappingsFromNamespace = moduleConfigs.get(moduleNamespace);
-
-        Preconditions.checkNotNull(mappingsFromNamespace,
-                "Namespace %s, defined in: module %s of type %s not found, available namespaces: %s", moduleNamespace,
-                instanceName, factoryName, moduleConfigs.keySet());
-
-        ModuleConfig moduleMapping = mappingsFromNamespace.get(factoryName);
-        checkState(moduleMapping != null, "Cannot find mapping for module type " + factoryName);
-        return moduleMapping;
-    }
-
-    private interface ResolvingStrategy<T> {
-        public T resolveElement(ModuleConfig moduleMapping, XmlElement moduleElement, ServiceRegistryWrapper serviceTracker,
-                String instanceName, String moduleNamespace, EditStrategyType defaultStrategy) throws NetconfDocumentedException;
-    }
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfig.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfig.java
deleted file mode 100644 (file)
index 7cfeb45..0000000
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.mapping.config;
-
-import com.google.common.base.Optional;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import javax.management.ObjectName;
-import javax.management.openmbean.OpenType;
-import org.opendaylight.controller.config.util.BeanReader;
-import org.opendaylight.controller.config.yangjmxgenerator.RuntimeBeanEntry;
-import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIfc;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeReadingStrategy;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.ObjectXmlReader;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.mapping.AttributeMappingStrategy;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.mapping.ObjectMapper;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.resolving.AttributeResolvingStrategy;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.resolving.ObjectResolver;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.toxml.AttributeWritingStrategy;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.toxml.ObjectXmlWriter;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfig;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditStrategyType;
-import org.opendaylight.controller.netconf.confignetconfconnector.osgi.EnumResolver;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-public final class InstanceConfig {
-    private static final Logger LOG = LoggerFactory.getLogger(InstanceConfig.class);
-
-    private final Map<String, AttributeIfc> yangToAttrConfig;
-    private final String nullableDummyContainerName;
-    private final Map<String, AttributeIfc> jmxToAttrConfig;
-    private final BeanReader configRegistryClient;
-
-    public InstanceConfig(BeanReader configRegistryClient, Map<String, AttributeIfc> yangNamesToAttributes,
-                          String nullableDummyContainerName) {
-
-        this.yangToAttrConfig = yangNamesToAttributes;
-        this.nullableDummyContainerName = nullableDummyContainerName;
-        this.jmxToAttrConfig = reverseMap(yangNamesToAttributes);
-        this.configRegistryClient = configRegistryClient;
-    }
-
-    private Map<String, Object> getMappedConfiguration(ObjectName on, final EnumResolver enumResolver) {
-
-        // TODO make field, mappingStrategies can be instantiated only once
-        Map<String, AttributeMappingStrategy<?, ? extends OpenType<?>>> mappingStrategies = new ObjectMapper()
-                .prepareMapping(jmxToAttrConfig, enumResolver);
-
-        Map<String, Object> toXml = Maps.newHashMap();
-
-        for (Entry<String, AttributeIfc> configDefEntry : jmxToAttrConfig.entrySet()) {
-            // Skip children runtime beans as they are mapped by InstanceRuntime
-            if (configDefEntry.getValue() instanceof RuntimeBeanEntry){
-                continue;
-            }
-            Object value = configRegistryClient.getAttributeCurrentValue(on, configDefEntry.getKey());
-            try {
-                AttributeMappingStrategy<?, ? extends OpenType<?>> attributeMappingStrategy = mappingStrategies
-                        .get(configDefEntry.getKey());
-                Optional<?> a = attributeMappingStrategy.mapAttribute(value);
-                if (!a.isPresent()){
-                    continue;
-                }
-                toXml.put(configDefEntry.getValue().getAttributeYangName(), a.get());
-            } catch (Exception e) {
-                throw new IllegalStateException("Unable to map value " + value + " to attribute "
-                        + configDefEntry.getKey(), e);
-            }
-        }
-        return toXml;
-    }
-
-    public Element toXml(ObjectName on, String namespace, Document document, Element rootElement, final EnumResolver enumResolver) {
-        Map<String, AttributeWritingStrategy> strats = new ObjectXmlWriter().prepareWriting(yangToAttrConfig, document);
-        Map<String, Object> mappedConfig = getMappedConfiguration(on, enumResolver);
-        Element parentElement;
-        if (nullableDummyContainerName != null) {
-            Element dummyElement = XmlUtil.createElement(document, nullableDummyContainerName, Optional.of(namespace));
-            rootElement.appendChild(dummyElement);
-            parentElement = dummyElement;
-        } else {
-            parentElement = rootElement;
-        }
-        for (Entry<String, ?> mappingEntry : mappedConfig.entrySet()) {
-            try {
-                strats.get(mappingEntry.getKey()).writeElement(parentElement, namespace, mappingEntry.getValue());
-            } catch (Exception e) {
-                throw new IllegalStateException("Unable to write value " + mappingEntry.getValue() + " for attribute "
-                        + mappingEntry.getValue(), e);
-            }
-        }
-        return rootElement;
-    }
-
-    private void resolveConfiguration(InstanceConfigElementResolved mappedConfig, ServiceRegistryWrapper depTracker, final EnumResolver enumResolver) {
-
-        // TODO make field, resolvingStrategies can be instantiated only once
-        Map<String, AttributeResolvingStrategy<?, ? extends OpenType<?>>> resolvingStrategies = new ObjectResolver(
-                depTracker).prepareResolving(yangToAttrConfig, enumResolver);
-
-        for (Entry<String, AttributeConfigElement> configDefEntry : mappedConfig.getConfiguration().entrySet()) {
-            AttributeConfigElement value = configDefEntry.getValue();
-            String attributeName = configDefEntry.getKey();
-            try {
-                AttributeResolvingStrategy<?, ? extends OpenType<?>> attributeResolvingStrategy = resolvingStrategies
-                        .get(attributeName);
-                LOG.trace("Trying to set value {} of attribute {} with {}", value, attributeName, attributeResolvingStrategy);
-
-                value.resolveValue(attributeResolvingStrategy, attributeName);
-                value.setJmxName(
-                        yangToAttrConfig.get(attributeName).getUpperCaseCammelCase());
-            } catch (Exception e) {
-                throw new IllegalStateException("Unable to resolve value " + value
-                        + " to attribute " + attributeName, e);
-            }
-        }
-    }
-
-    public InstanceConfigElementResolved fromXml(XmlElement moduleElement, ServiceRegistryWrapper services, String moduleNamespace,
-                                                 EditStrategyType defaultStrategy,
-                                                 Map<String, Map<Date, EditConfig.IdentityMapping>> identityMap, final EnumResolver enumResolver) throws NetconfDocumentedException {
-        Map<String, AttributeConfigElement> retVal = Maps.newHashMap();
-
-        Map<String, AttributeReadingStrategy> strats = new ObjectXmlReader().prepareReading(yangToAttrConfig, identityMap);
-        List<XmlElement> recognisedChildren = Lists.newArrayList();
-
-        XmlElement typeElement = moduleElement.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.TYPE_KEY);
-        XmlElement nameElement = moduleElement.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.NAME_KEY);
-        List<XmlElement> typeAndNameElements = Lists.newArrayList(typeElement, nameElement);
-
-        // if dummy container was defined in yang, set moduleElement to its content
-        if (nullableDummyContainerName != null) {
-            int size = moduleElement.getChildElements().size();
-            int expectedChildNodes = 1 + typeAndNameElements.size();
-            if (size > expectedChildNodes) {
-                throw new NetconfDocumentedException("Error reading module " + typeElement.getTextContent() + " : " +
-                        nameElement.getTextContent() + " - Expected " + expectedChildNodes +" child nodes, " +
-                        "one of them with name " + nullableDummyContainerName +
-                        ", got " + size + " elements.");
-            }
-            if (size == expectedChildNodes) {
-                try {
-                    moduleElement = moduleElement.getOnlyChildElement(nullableDummyContainerName, moduleNamespace);
-                } catch (NetconfDocumentedException e) {
-                    throw new NetconfDocumentedException("Error reading module " + typeElement.getTextContent() + " : " +
-                            nameElement.getTextContent() + " - Expected child node with name " + nullableDummyContainerName +
-                            "." + e.getMessage());
-                }
-            } // else 2 elements, no need to descend
-        }
-
-        for (Entry<String, AttributeReadingStrategy> readStratEntry : strats.entrySet()) {
-            List<XmlElement> configNodes = getConfigNodes(moduleElement, moduleNamespace, readStratEntry.getKey(),
-                    recognisedChildren, typeAndNameElements);
-            AttributeConfigElement readElement = readStratEntry.getValue().readElement(configNodes);
-            retVal.put(readStratEntry.getKey(), readElement);
-        }
-
-        recognisedChildren.addAll(typeAndNameElements);
-        try {
-            moduleElement.checkUnrecognisedElements(recognisedChildren);
-        } catch (NetconfDocumentedException e) {
-            throw new NetconfDocumentedException("Error reading module " + typeElement.getTextContent() + " : " +
-                    nameElement.getTextContent() + " - " +
-                    e.getMessage(), e.getErrorType(), e.getErrorTag(),e.getErrorSeverity(),e.getErrorInfo());
-        }
-        // TODO: add check for conflicts between global and local edit strategy
-        String perInstanceEditStrategy = moduleElement.getAttribute(XmlNetconfConstants.OPERATION_ATTR_KEY,
-                XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
-
-        InstanceConfigElementResolved instanceConfigElementResolved = perInstanceEditStrategy.equals("") ? new InstanceConfigElementResolved(
-                retVal, defaultStrategy) : new InstanceConfigElementResolved(perInstanceEditStrategy, retVal, defaultStrategy);
-
-        resolveConfiguration(instanceConfigElementResolved, services, enumResolver);
-        return instanceConfigElementResolved;
-    }
-
-    private List<XmlElement> getConfigNodes(XmlElement moduleElement, String moduleNamespace, String name,
-            List<XmlElement> recognisedChildren, List<XmlElement> typeAndName) throws NetconfDocumentedException {
-        List<XmlElement> foundConfigNodes = moduleElement.getChildElementsWithinNamespace(name, moduleNamespace);
-        if (foundConfigNodes.isEmpty()) {
-            LOG.debug("No config nodes {}:{} found in {}", moduleNamespace, name, moduleElement);
-            LOG.debug("Trying lookup of config nodes without specified namespace");
-            foundConfigNodes = moduleElement.getChildElementsWithinNamespace(name,
-                    XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG);
-            // In case module type or name element is not present in config it
-            // would be matched with config type or name
-            // We need to remove config type and name from available module
-            // config elements
-            foundConfigNodes.removeAll(typeAndName);
-            LOG.debug("Found {} config nodes {} without specified namespace in {}", foundConfigNodes.size(), name,
-                    moduleElement);
-        } else {
-            List<XmlElement> foundWithoutNamespaceNodes = moduleElement.getChildElementsWithinNamespace(name,
-                    XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG);
-            foundWithoutNamespaceNodes.removeAll(typeAndName);
-            if (!foundWithoutNamespaceNodes.isEmpty()){
-                throw new NetconfDocumentedException(String.format("Element %s present multiple times with different namespaces: %s, %s", name, foundConfigNodes,
-                        foundWithoutNamespaceNodes),
-                        NetconfDocumentedException.ErrorType.application,
-                        NetconfDocumentedException.ErrorTag.invalid_value,
-                        NetconfDocumentedException.ErrorSeverity.error);
-            }
-        }
-
-        recognisedChildren.addAll(foundConfigNodes);
-        return foundConfigNodes;
-    }
-
-    private static Map<String, AttributeIfc> reverseMap(Map<String, AttributeIfc> yangNameToAttr) {
-        Map<String, AttributeIfc> reversednameToAtr = Maps.newHashMap();
-
-        for (Entry<String, AttributeIfc> entry : yangNameToAttr.entrySet()) {
-            reversednameToAtr.put(entry.getValue().getUpperCaseCammelCase(), entry.getValue());
-        }
-
-        return reversednameToAtr;
-    }
-
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfigElementResolved.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfigElementResolved.java
deleted file mode 100644 (file)
index ef5ba75..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.mapping.config;
-
-import java.util.Map;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.confignetconfconnector.exception.OperationNotPermittedException;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfigStrategy;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditStrategyType;
-
-/**
- * Parsed xml element containing whole configuration for an instance of some
- * module. Contains preferred edit strategy type.
- */
-public class InstanceConfigElementResolved {
-
-    private final EditStrategyType editStrategy;
-    private final Map<String, AttributeConfigElement> configuration;
-
-    public InstanceConfigElementResolved(String currentStrategy, Map<String, AttributeConfigElement> configuration,
-                                         EditStrategyType defaultStrategy)
-            throws NetconfDocumentedException {
-        this.editStrategy = parseStrategy(currentStrategy, defaultStrategy);
-        this.configuration = configuration;
-    }
-
-    public InstanceConfigElementResolved(Map<String, AttributeConfigElement> configuration, EditStrategyType defaultStrategy) {
-        editStrategy = defaultStrategy;
-        this.configuration = configuration;
-    }
-
-
-    static EditStrategyType parseStrategy(String currentStrategy, EditStrategyType defaultStrategy) throws OperationNotPermittedException {
-        EditStrategyType parsedStrategy = EditStrategyType.valueOf(currentStrategy);
-        EditStrategyType.compareParsedStrategyToDefaultEnforcing(parsedStrategy,defaultStrategy);
-        return parsedStrategy;
-    }
-
-
-    public EditConfigStrategy getEditStrategy() {
-        return editStrategy.getFittingStrategy();
-    }
-
-    public Map<String, AttributeConfigElement> getConfiguration() {
-        return configuration;
-    }
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleConfig.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleConfig.java
deleted file mode 100644 (file)
index 5cadc08..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.mapping.config;
-
-import com.google.common.base.Optional;
-import java.util.Date;
-import java.util.Map;
-import javax.management.ObjectName;
-import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfig;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditStrategyType;
-import org.opendaylight.controller.netconf.confignetconfconnector.osgi.EnumResolver;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-public class ModuleConfig {
-
-    private final String moduleName;
-    private final InstanceConfig instanceConfig;
-
-    public ModuleConfig(String moduleName, InstanceConfig mbeanMapping) {
-        this.moduleName = moduleName;
-        this.instanceConfig = mbeanMapping;
-    }
-
-    public Element toXml(ObjectName instanceON, Document document, String namespace, final EnumResolver enumResolver) {
-        Element root = XmlUtil.createElement(document, XmlNetconfConstants.MODULE_KEY, Optional.<String>absent());
-
-        // type belongs to config.yang namespace, but needs to be <type prefix:moduleNS>prefix:moduleName</type>
-
-        Element typeElement = XmlUtil.createTextElementWithNamespacedContent(document, XmlNetconfConstants.TYPE_KEY,
-                XmlNetconfConstants.PREFIX, namespace, moduleName);
-
-        root.appendChild(typeElement);
-        // name belongs to config.yang namespace
-        String instanceName = ObjectNameUtil.getInstanceName(instanceON);
-        Element nameElement = XmlUtil.createTextElement(document, XmlNetconfConstants.NAME_KEY, instanceName, Optional.<String>absent());
-
-        root.appendChild(nameElement);
-
-        root = instanceConfig.toXml(instanceON, namespace, document, root, enumResolver);
-
-        return root;
-    }
-
-    public ModuleElementResolved fromXml(XmlElement moduleElement, ServiceRegistryWrapper depTracker, String instanceName,
-                                         String moduleNamespace, EditStrategyType defaultStrategy, Map<String, Map<Date, EditConfig.IdentityMapping>> identityMap, final EnumResolver enumResolver) throws NetconfDocumentedException {
-
-        InstanceConfigElementResolved ice = instanceConfig.fromXml(moduleElement, depTracker, moduleNamespace, defaultStrategy, identityMap, enumResolver);
-        return new ModuleElementResolved(instanceName, ice);
-    }
-
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleElementDefinition.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleElementDefinition.java
deleted file mode 100644 (file)
index 88a18ad..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.mapping.config;
-
-import org.opendaylight.controller.netconf.confignetconfconnector.exception.OperationNotPermittedException;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfigStrategy;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditStrategyType;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.MissingInstanceHandlingStrategy;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.NoneEditConfigStrategy;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ModuleElementDefinition {
-
-    public static final NoneEditConfigStrategy NONE_EDIT_CONFIG_STRATEGY = new NoneEditConfigStrategy();
-    public static final MissingInstanceHandlingStrategy MISSING_INSTANCE_HANDLING_STRATEGY = new MissingInstanceHandlingStrategy();
-
-    private final String instanceName;
-    private final EditStrategyType editStrategy;
-    private static final Logger LOG = LoggerFactory.getLogger(ModuleElementDefinition.class);
-
-    public ModuleElementDefinition(String instanceName, String currentStrategy, EditStrategyType defaultStrategy) {
-        this.instanceName = instanceName;
-        if (currentStrategy == null || currentStrategy.isEmpty()) {
-            this.editStrategy = defaultStrategy;
-        } else {
-            EditStrategyType _edStrategy = null;
-            try {
-                _edStrategy = InstanceConfigElementResolved.parseStrategy(currentStrategy, defaultStrategy);
-            } catch (OperationNotPermittedException e) {
-                _edStrategy = defaultStrategy;
-                LOG.warn("Operation not permitted on current strategy {} while default strategy is {}. Element definition strategy set to default.",
-                        currentStrategy,
-                        defaultStrategy,
-                        e);
-            }
-            this.editStrategy = _edStrategy;
-        }
-
-    }
-
-    public String getInstanceName() {
-        return instanceName;
-    }
-
-    public EditConfigStrategy getEditStrategy() {
-        switch (editStrategy) {
-        case delete :
-        case remove :
-        case none :
-            return NONE_EDIT_CONFIG_STRATEGY;
-        default :
-            return MISSING_INSTANCE_HANDLING_STRATEGY;
-        }
-    }
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleElementResolved.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleElementResolved.java
deleted file mode 100644 (file)
index 6d2936c..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.mapping.config;
-
-public class ModuleElementResolved {
-
-    private final String instanceName;
-    private final InstanceConfigElementResolved instanceConfigElementResolved;
-
-    public ModuleElementResolved(String instanceName, InstanceConfigElementResolved instanceConfigElementResolved) {
-        this.instanceName = instanceName;
-        this.instanceConfigElementResolved = instanceConfigElementResolved;
-    }
-
-    public String getInstanceName() {
-        return instanceName;
-    }
-
-    public InstanceConfigElementResolved getInstanceConfigElementResolved() {
-        return instanceConfigElementResolved;
-    }
-
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ServiceRegistryWrapper.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ServiceRegistryWrapper.java
deleted file mode 100644 (file)
index 9ce550e..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.confignetconfconnector.mapping.config;
-
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Maps;
-import java.util.Map;
-import javax.management.InstanceNotFoundException;
-import javax.management.ObjectName;
-import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry;
-import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
-import org.opendaylight.yangtools.yang.common.QName;
-
-public class ServiceRegistryWrapper {
-
-    private final ServiceReferenceReadableRegistry configServiceRefRegistry;
-
-    public ServiceRegistryWrapper(ServiceReferenceReadableRegistry configServiceRefRegistry) {
-        this.configServiceRefRegistry = configServiceRefRegistry;
-    }
-
-    public ObjectName getByServiceAndRefName(String namespace, String serviceType, String refName) {
-        Map<String, Map<String, Map<String, String>>> mappedServices = getMappedServices();
-        Map<String, Map<String, String>> serviceNameToRefNameToInstance = mappedServices.get(namespace);
-
-        Preconditions.checkArgument(serviceNameToRefNameToInstance != null,
-                "No service mapped to %s:%s:%s. Wrong namespace, available namespaces: %s",
-                namespace, serviceType, refName, mappedServices.keySet());
-
-        Map<String, String> refNameToInstance = serviceNameToRefNameToInstance.get(serviceType);
-        Preconditions.checkArgument(refNameToInstance != null,
-                "No service mapped to %s:%s:%s. Wrong service type, available service types: %s"
-                , namespace, serviceType, refName, serviceNameToRefNameToInstance.keySet());
-
-        String instanceId = refNameToInstance.get(refName);
-        Preconditions.checkArgument(instanceId != null,
-                "No service mapped to %s:%s:%s. Wrong ref name, available ref names: %s"
-                ,namespace, serviceType, refName, refNameToInstance.keySet());
-
-        Services.ServiceInstance serviceInstance = Services.ServiceInstance.fromString(instanceId);
-        Preconditions.checkArgument(serviceInstance != null,
-                "No service mapped to %s:%s:%s. Wrong ref name, available ref names: %s"
-                ,namespace, serviceType, refName, refNameToInstance.keySet());
-
-        String qNameOfService = configServiceRefRegistry.getServiceInterfaceName(namespace, serviceType);
-        try {
-            /*
-             Remove transaction name as this is redundant - will be stripped in DynamicWritableWrapper,
-             and makes it hard to compare with service references got from MXBean attributes
-            */
-            return ObjectNameUtil.withoutTransactionName(
-                    configServiceRefRegistry.getServiceReference(qNameOfService, refName));
-        } catch (InstanceNotFoundException e) {
-            throw new IllegalArgumentException("No serviceInstance mapped to " + refName
-                    + " under service name " + serviceType + " , " + refNameToInstance.keySet(), e);
-
-        }
-    }
-
-    public Map<String, Map<String, Map<String, String>>> getMappedServices() {
-        Map<String, Map<String, Map<String, String>>> retVal = Maps.newHashMap();
-
-        Map<String, Map<String, ObjectName>> serviceMapping = configServiceRefRegistry.getServiceMapping();
-        for (Map.Entry<String, Map<String, ObjectName>> qNameToRefNameEntry : serviceMapping.entrySet()){
-            for (String refName : qNameToRefNameEntry.getValue().keySet()) {
-
-                ObjectName on = qNameToRefNameEntry.getValue().get(refName);
-                Services.ServiceInstance si = Services.ServiceInstance.fromObjectName(on);
-
-                QName qname = QName.create(qNameToRefNameEntry.getKey());
-                String namespace = qname.getNamespace().toString();
-                Map<String, Map<String, String>> serviceToRefs = retVal.get(namespace);
-                if(serviceToRefs==null) {
-                    serviceToRefs = Maps.newHashMap();
-                    retVal.put(namespace, serviceToRefs);
-                }
-
-                String localName = qname.getLocalName();
-                Map<String, String> refsToSis = serviceToRefs.get(localName);
-                if(refsToSis==null) {
-                    refsToSis = Maps.newHashMap();
-                    serviceToRefs.put(localName, refsToSis);
-                }
-
-                Preconditions.checkState(!refsToSis.containsKey(refName),
-                        "Duplicate reference name %s for service %s:%s, now for instance %s", refName, namespace,
-                        localName, on);
-                refsToSis.put(refName, si.toString());
-            }
-        }
-
-        return retVal;
-    }
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Services.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Services.java
deleted file mode 100644 (file)
index 74655f9..0000000
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.mapping.config;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Maps;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import javax.management.ObjectName;
-import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.ObjectNameAttributeReadingStrategy;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
-import org.opendaylight.yangtools.yang.data.api.ModifyAction;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-public final class Services {
-
-    private static final String EMPTY_PROVIDER = "";
-    private static final String PROVIDER_KEY = "provider";
-    private static final String NAME_KEY = "name";
-    public static final String TYPE_KEY = "type";
-    public static final String SERVICE_KEY = "service";
-
-    private final Map<String /*Namespace*/, Map<String/* ServiceName */, Map<String/* refName */, ServiceInstance>>> namespaceToServiceNameToRefNameToInstance = Maps
-            .newHashMap();
-
-    /**
-     *
-     */
-    public Map<String, Map<String, Map<String, ServiceInstance>>> getNamespaceToServiceNameToRefNameToInstance() {
-        return namespaceToServiceNameToRefNameToInstance;
-    }
-
-    private static Services resolveServices(Map<String, Map<String, Map<String, String>>> mappedServices) {
-        Services tracker = new Services();
-
-        for (Entry<String, Map<String, Map<String, String>>> namespaceEntry : mappedServices.entrySet()) {
-            String namespace = namespaceEntry.getKey();
-
-            for (Entry<String, Map<String, String>> serviceEntry : namespaceEntry.getValue().entrySet()) {
-
-                String serviceName = serviceEntry.getKey();
-                for (Entry<String, String> refEntry : serviceEntry.getValue().entrySet()) {
-
-                    Map<String, Map<String, ServiceInstance>> namespaceToServices = tracker.namespaceToServiceNameToRefNameToInstance.get(namespace);
-                    if (namespaceToServices == null) {
-                        namespaceToServices = Maps.newHashMap();
-                        tracker.namespaceToServiceNameToRefNameToInstance.put(namespace, namespaceToServices);
-                    }
-
-                    Map<String, ServiceInstance> refNameToInstance = namespaceToServices
-                            .get(serviceName);
-                    if (refNameToInstance == null) {
-                        refNameToInstance = Maps.newHashMap();
-                        namespaceToServices.put(serviceName, refNameToInstance);
-                    }
-
-                    String refName = refEntry.getKey();
-                    //we want to compare reference not value of the provider
-                    refNameToInstance.put(refName, refEntry.getValue() == EMPTY_PROVIDER
-                            //provider name cannot be EMPTY_PROVIDER instance unless we are executing delete
-                            ? ServiceInstance.EMPTY_SERVICE_INSTANCE
-                            : ServiceInstance.fromString(refEntry.getValue()));
-
-                }
-            }
-        }
-        return tracker;
-    }
-
-    // TODO support edit strategies on services
-
-    public static Services fromXml(XmlElement xml) throws NetconfDocumentedException {
-        Map<String, Map<String, Map<String, String>>> retVal = Maps.newHashMap();
-
-        List<XmlElement> services = xml.getChildElements(SERVICE_KEY);
-        xml.checkUnrecognisedElements(services);
-
-        for (XmlElement service : services) {
-
-            XmlElement typeElement = service.getOnlyChildElement(TYPE_KEY);
-            Entry<String, String> prefixNamespace = typeElement.findNamespaceOfTextContent();
-
-            Preconditions.checkState(prefixNamespace.getKey()!=null && !prefixNamespace.getKey().equals(""), "Type attribute was not prefixed");
-
-            Map<String, Map<String, String>> namespaceToServices = retVal.get(prefixNamespace.getValue());
-            if(namespaceToServices == null) {
-                namespaceToServices = Maps.newHashMap();
-                retVal.put(prefixNamespace.getValue(), namespaceToServices);
-            }
-
-            String serviceName =  ObjectNameAttributeReadingStrategy.checkPrefixAndExtractServiceName(typeElement, prefixNamespace);
-
-            Map<String, String> innerMap = namespaceToServices.get(serviceName);
-            if (innerMap == null) {
-                innerMap = Maps.newHashMap();
-                namespaceToServices.put(serviceName, innerMap);
-            }
-
-            List<XmlElement> instances = service.getChildElements(XmlNetconfConstants.INSTANCE_KEY);
-            service.checkUnrecognisedElements(instances, typeElement);
-
-            for (XmlElement instance : instances) {
-                XmlElement nameElement = instance.getOnlyChildElement(NAME_KEY);
-                String refName = nameElement.getTextContent();
-
-                if (!ModifyAction.DELETE.toString().toLowerCase().equals(
-                        instance.getAttribute(
-                                XmlNetconfConstants.OPERATION_ATTR_KEY,
-                                XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0)))
-                {
-                    XmlElement providerElement = instance.getOnlyChildElement(PROVIDER_KEY);
-                    String providerName = providerElement.getTextContent();
-
-                    instance.checkUnrecognisedElements(nameElement, providerElement);
-
-                    innerMap.put(refName, providerName);
-                } else {
-                    //since this is a delete we dont have a provider name - we want empty service instance
-                    innerMap.put(refName, EMPTY_PROVIDER);
-                }
-            }
-        }
-
-        return resolveServices(retVal);
-    }
-
-    public static Element toXml(ServiceRegistryWrapper serviceRegistryWrapper, Document document) {
-        Element root = XmlUtil.createElement(document, XmlNetconfConstants.SERVICES_KEY, Optional.of(XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG));
-
-        Map<String, Map<String, Map<String, String>>> mappedServices = serviceRegistryWrapper.getMappedServices();
-        for (Entry<String, Map<String, Map<String, String>>> namespaceToRefEntry : mappedServices.entrySet()) {
-
-            for (Entry<String, Map<String, String>> serviceEntry : namespaceToRefEntry.getValue().entrySet()) {
-                // service belongs to config.yang namespace
-                Element serviceElement = XmlUtil.createElement(document, SERVICE_KEY, Optional.<String>absent());
-                root.appendChild(serviceElement);
-
-                // type belongs to config.yang namespace
-                String serviceType = serviceEntry.getKey();
-                Element typeElement = XmlUtil.createTextElementWithNamespacedContent(document, XmlNetconfConstants.TYPE_KEY,
-                        XmlNetconfConstants.PREFIX, namespaceToRefEntry.getKey(), serviceType);
-
-                serviceElement.appendChild(typeElement);
-
-                for (Entry<String, String> instanceEntry : serviceEntry.getValue().entrySet()) {
-                    Element instanceElement = XmlUtil.createElement(document, XmlNetconfConstants.INSTANCE_KEY, Optional.<String>absent());
-                    serviceElement.appendChild(instanceElement);
-
-                    Element nameElement = XmlUtil.createTextElement(document, NAME_KEY, instanceEntry.getKey(), Optional.<String>absent());
-                    instanceElement.appendChild(nameElement);
-
-                    Element providerElement = XmlUtil.createTextElement(document, PROVIDER_KEY, instanceEntry.getValue(), Optional.<String>absent());
-                    instanceElement.appendChild(providerElement);
-                }
-            }
-
-        }
-        return root;
-    }
-
-    public static final class ServiceInstance {
-        public static final ServiceInstance EMPTY_SERVICE_INSTANCE = new ServiceInstance("", "");
-
-        public ServiceInstance(String moduleName, String instanceName) {
-            this.moduleName = moduleName;
-            this.instanceName = instanceName;
-        }
-
-        public static ServiceInstance fromString(String instanceId) {
-            instanceId = instanceId.trim();
-            Matcher matcher = p.matcher(instanceId);
-            if(!matcher.matches()) {
-                matcher = pDeprecated.matcher(instanceId);
-            }
-
-            Preconditions.checkArgument(matcher.matches(), "Unexpected format for provider, expected " + p.toString()
-                    + " or " + pDeprecated.toString() + " but was " + instanceId);
-
-            String factoryName = matcher.group(1);
-            String instanceName = matcher.group(2);
-            return new ServiceInstance(factoryName, instanceName);
-        }
-
-        private final String moduleName, instanceName;
-        private String serviceName;
-
-        public String getServiceName() {
-            return serviceName;
-        }
-
-        public void setServiceName(String serviceName) {
-            this.serviceName = serviceName;
-        }
-
-        public String getModuleName() {
-            return moduleName;
-        }
-
-        public String getInstanceName() {
-            return instanceName;
-        }
-
-        private static final String blueprint = "/"
-                + XmlNetconfConstants.MODULES_KEY + "/" + XmlNetconfConstants.MODULE_KEY + "["
-                + XmlNetconfConstants.TYPE_KEY + "='%s']["
-                + XmlNetconfConstants.NAME_KEY + "='%s']";
-
-        // TODO unify with xpath in RuntimeRpc
-
-        // Previous version of xpath, needs to be supported for backwards compatibility (persisted configs by config-persister)
-        private static final String blueprintRDeprecated = "/" + XmlNetconfConstants.CONFIG_KEY + "/"
-                + XmlNetconfConstants.MODULES_KEY + "/" + XmlNetconfConstants.MODULE_KEY + "\\["
-                + XmlNetconfConstants.NAME_KEY + "='%s'\\]/" + XmlNetconfConstants.INSTANCE_KEY + "\\["
-                + XmlNetconfConstants.NAME_KEY + "='%s'\\]";
-
-        private static final String blueprintR = "/"
-                + XmlNetconfConstants.MODULES_KEY + "/" + XmlNetconfConstants.MODULE_KEY + "\\["
-                + XmlNetconfConstants.TYPE_KEY + "='%s'\\]\\["
-                + XmlNetconfConstants.NAME_KEY + "='%s'\\]";
-
-        private static final Pattern pDeprecated = Pattern.compile(String.format(blueprintRDeprecated, "(.+)", "(.+)"));
-        private static final Pattern p = Pattern.compile(String.format(blueprintR, "(.+)", "(.+)"));
-
-        @Override
-        public String toString() {
-            return String.format(blueprint, moduleName, instanceName);
-        }
-
-        @Override
-        public int hashCode() {
-            final int prime = 31;
-            int result = 1;
-            result = prime * result + ((instanceName == null) ? 0 : instanceName.hashCode());
-            result = prime * result + ((moduleName == null) ? 0 : moduleName.hashCode());
-            return result;
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (this == obj){
-                return true;
-            }
-            if (obj == null){
-                return false;
-            }
-            if (getClass() != obj.getClass()){
-                return false;
-            }
-            ServiceInstance other = (ServiceInstance) obj;
-            if (instanceName == null) {
-                if (other.instanceName != null){
-                    return false;
-                }
-            } else if (!instanceName.equals(other.instanceName)){
-                return false;
-            }
-            if (moduleName == null) {
-                if (other.moduleName != null){
-                    return false;
-                }
-            } else if (!moduleName.equals(other.moduleName)){
-                return false;
-            }
-            return true;
-        }
-
-        public ObjectName getObjectName(String transactionName) {
-            return ObjectNameUtil.createTransactionModuleON(transactionName, moduleName, instanceName);
-        }
-
-        public static ServiceInstance fromObjectName(ObjectName on) {
-            return new ServiceInstance(ObjectNameUtil.getFactoryName(on), ObjectNameUtil.getInstanceName(on));
-        }
-    }
-
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/rpc/InstanceRuntimeRpc.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/rpc/InstanceRuntimeRpc.java
deleted file mode 100644 (file)
index f7108f4..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.mapping.rpc;
-
-import com.google.common.collect.Maps;
-import java.util.Collections;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import javax.management.openmbean.OpenType;
-import org.opendaylight.controller.config.yangjmxgenerator.RuntimeBeanEntry.Rpc;
-import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIfc;
-import org.opendaylight.controller.config.yangjmxgenerator.attribute.JavaAttribute;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeReadingStrategy;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.ObjectXmlReader;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.resolving.AttributeResolvingStrategy;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.resolving.ObjectResolver;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfig;
-import org.opendaylight.controller.netconf.confignetconfconnector.osgi.EnumResolver;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-
-public final class InstanceRuntimeRpc {
-
-    private final Map<String, AttributeIfc> yangToAttrConfig;
-    private final Rpc rpc;
-    private final EnumResolver enumResolver;
-
-    public InstanceRuntimeRpc(Rpc rpc, final EnumResolver enumResolver) {
-        this.enumResolver = enumResolver;
-        this.yangToAttrConfig = map(rpc.getParameters());
-        this.rpc = rpc;
-    }
-
-    private Map<String, AttributeIfc> map(List<JavaAttribute> parameters) {
-        Map<String, AttributeIfc> mapped = Maps.newHashMap();
-        for (JavaAttribute javaAttribute : parameters) {
-            mapped.put(javaAttribute.getAttributeYangName(), javaAttribute);
-        }
-        return mapped;
-    }
-
-    private void resolveConfiguration(Map<String, AttributeConfigElement> mappedConfig) {
-
-        // TODO make field, resolvingStrategies can be instantiated only once
-        Map<String, AttributeResolvingStrategy<?, ? extends OpenType<?>>> resolvingStrategies = new ObjectResolver(null)
-                .prepareResolving(yangToAttrConfig, enumResolver);
-        // TODO make constructor for object resolver without service tracker
-        for (Entry<String, AttributeConfigElement> configDefEntry : mappedConfig.entrySet()) {
-            try {
-
-                AttributeResolvingStrategy<?, ? extends OpenType<?>> attributeResolvingStrategy = resolvingStrategies
-                        .get(configDefEntry.getKey());
-
-                configDefEntry.getValue().resolveValue(attributeResolvingStrategy, configDefEntry.getKey());
-                configDefEntry.getValue().setJmxName(
-                        yangToAttrConfig.get(configDefEntry.getKey()).getUpperCaseCammelCase());
-            } catch (Exception e) {
-                throw new IllegalStateException("Unable to resolve value " + configDefEntry.getValue()
-                        + " to attribute " + configDefEntry.getKey(), e);
-            }
-        }
-    }
-
-    public Map<String, AttributeConfigElement> fromXml(XmlElement configRootNode) throws NetconfDocumentedException {
-        Map<String, AttributeConfigElement> retVal = Maps.newHashMap();
-
-        // FIXME add identity map to runtime data
-        Map<String, AttributeReadingStrategy> strats = new ObjectXmlReader().prepareReading(yangToAttrConfig,
-                Collections.<String, Map<Date, EditConfig.IdentityMapping>> emptyMap());
-
-        for (Entry<String, AttributeReadingStrategy> readStratEntry : strats.entrySet()) {
-            List<XmlElement> configNodes = configRootNode.getChildElements(readStratEntry.getKey());
-            AttributeConfigElement readElement = readStratEntry.getValue().readElement(configNodes);
-            retVal.put(readStratEntry.getKey(), readElement);
-        }
-
-        resolveConfiguration(retVal);
-        return retVal;
-    }
-
-    public String getName() {
-        return rpc.getName();
-    }
-
-    public AttributeIfc getReturnType() {
-        return rpc.getReturnType();
-    }
-
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/rpc/ModuleRpcs.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/rpc/ModuleRpcs.java
deleted file mode 100644 (file)
index 7316dbc..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.mapping.rpc;
-
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Maps;
-import java.util.Map;
-import org.opendaylight.controller.config.yangjmxgenerator.RuntimeBeanEntry;
-import org.opendaylight.controller.config.yangjmxgenerator.RuntimeBeanEntry.Rpc;
-import org.opendaylight.controller.netconf.confignetconfconnector.osgi.EnumResolver;
-
-public final class ModuleRpcs {
-
-    private final Map<String, String> yangToJavaNames = Maps.newHashMap();
-    private final Map<String, Map<String, InstanceRuntimeRpc>> rpcMapping = Maps.newHashMap();
-    private final EnumResolver enumResolver;
-
-    public ModuleRpcs(final EnumResolver enumResolver) {
-        this.enumResolver = enumResolver;
-    }
-
-    public void addNameMapping(RuntimeBeanEntry runtimeEntry) {
-        String yangName = runtimeEntry.getYangName();
-        Preconditions.checkState(!yangToJavaNames.containsKey(yangName),
-                "RuntimeBean %s found twice in same namespace", yangName);
-        yangToJavaNames.put(yangName, runtimeEntry.getJavaNamePrefix());
-    }
-
-    public void addRpc(RuntimeBeanEntry runtimeEntry, Rpc rpc) {
-        String yangName = runtimeEntry.getYangName();
-        Map<String, InstanceRuntimeRpc> map = rpcMapping.get(yangName);
-        if (map == null) {
-            map = Maps.newHashMap();
-            rpcMapping.put(yangName, map);
-        }
-
-        Preconditions.checkState(!map.containsKey(rpc.getYangName()), "Rpc %s for runtime bean %s added twice",
-                rpc.getYangName(), yangName);
-        map.put(rpc.getYangName(), new InstanceRuntimeRpc(rpc, enumResolver));
-    }
-
-    public String getRbeJavaName(String yangName) {
-        String javaName = yangToJavaNames.get(yangName);
-        Preconditions.checkState(javaName != null,
-                "No runtime bean entry found under yang name %s, available yang names %s", yangName,
-                yangToJavaNames.keySet());
-        return javaName;
-    }
-
-    public InstanceRuntimeRpc getRpc(String rbeName, String rpcName) {
-        Map<String, InstanceRuntimeRpc> rpcs = rpcMapping.get(rbeName);
-        Preconditions.checkState(rpcs != null, "No rpcs found for runtime bean %s", rbeName);
-        InstanceRuntimeRpc rpc = rpcs.get(rpcName);
-        Preconditions.checkState(rpc != null, "No rpc found for runtime bean %s with name %s", rbeName, rpcName);
-        return rpc;
-    }
-
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/rpc/Rpcs.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/rpc/Rpcs.java
deleted file mode 100644 (file)
index 2eef2a6..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.mapping.rpc;
-
-import com.google.common.base.Preconditions;
-import java.util.Map;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.runtimerpc.RuntimeRpcElementResolved;
-
-public class Rpcs {
-    private final Map<String, Map<String, ModuleRpcs>> mappedRpcs;
-
-    public Rpcs(Map<String, Map<String, ModuleRpcs>> mappedRpcs) {
-        super();
-        this.mappedRpcs = mappedRpcs;
-    }
-
-    public ModuleRpcs getRpcMapping(RuntimeRpcElementResolved id) {
-        Map<String, ModuleRpcs> modules = mappedRpcs.get(id.getNamespace());
-        Preconditions.checkState(modules != null, "No modules found for namespace %s", id.getNamespace());
-        String moduleName = id.getModuleName();
-        ModuleRpcs rpcMapping = modules.get(moduleName);
-        Preconditions.checkState(rpcMapping != null, "No module %s found for namespace %s", moduleName,
-                id.getNamespace());
-
-        return rpcMapping;
-    }
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/InstanceRuntime.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/InstanceRuntime.java
deleted file mode 100644 (file)
index ce30dc4..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.mapping.runtime;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Predicate;
-import com.google.common.collect.Collections2;
-import com.google.common.collect.Sets;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import javax.management.ObjectName;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfig;
-import org.opendaylight.controller.netconf.confignetconfconnector.osgi.EnumResolver;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-public class InstanceRuntime {
-
-    /**
-     *
-     */
-    private static final String KEY_ATTRIBUTE_KEY = "key";
-
-    private final InstanceConfig instanceMapping;
-    private final Map<String, InstanceRuntime> childrenMappings;
-    private final Map<String, String> jmxToYangChildRbeMapping;
-
-    public InstanceRuntime(InstanceConfig instanceMapping, Map<String, InstanceRuntime> childrenMappings,
-            Map<String, String> jmxToYangChildRbeMapping) {
-        this.instanceMapping = instanceMapping;
-        this.childrenMappings = childrenMappings;
-        this.jmxToYangChildRbeMapping = jmxToYangChildRbeMapping;
-    }
-
-    /**
-     * Finds all children runtime beans, same properties and values as current
-     * root + any number of additional properties
-     */
-    private Set<ObjectName> findChildren(ObjectName innerRootBean, Set<ObjectName> childRbeOns) {
-        final Map<String, String> wantedProperties = innerRootBean.getKeyPropertyList();
-
-        return Sets.newHashSet(Collections2.filter(childRbeOns, new Predicate<ObjectName>() {
-
-            @Override
-            public boolean apply(ObjectName on) {
-                Map<String, String> localProperties = on.getKeyPropertyList();
-                for (Entry<String, String> propertyEntry : wantedProperties.entrySet()) {
-                    if (!localProperties.containsKey(propertyEntry.getKey())){
-                        return false;
-                    }
-                    if (!localProperties.get(propertyEntry.getKey()).equals(propertyEntry.getValue())){
-                        return false;
-                    }
-                    if (localProperties.size() <= wantedProperties.size()){
-                        return false;
-                    }
-                }
-                return true;
-            }
-        }));
-    }
-
-    /**
-     * Finds next level root runtime beans, beans that have the same properties
-     * as current root + one additional
-     */
-    private Set<ObjectName> getRootBeans(Set<ObjectName> childRbeOns, final String string, final int keyListSize) {
-        return Sets.newHashSet(Collections2.filter(childRbeOns, new Predicate<ObjectName>() {
-
-            @Override
-            public boolean apply(ObjectName on) {
-                if (on.getKeyPropertyList().size() != keyListSize + 1){
-                    return false;
-                }
-                return on.getKeyPropertyList().containsKey(string);
-            }
-        }));
-    }
-
-    public Element toXml(ObjectName rootOn, Set<ObjectName> childRbeOns, Document document, Element parentElement, String namespace, final EnumResolver enumResolver) {
-        return toXml(rootOn, childRbeOns, document, null, parentElement, namespace, enumResolver);
-    }
-
-    public Element toXml(ObjectName rootOn, Set<ObjectName> childRbeOns, Document document, String instanceIndex,
-                         Element parentElement, String namespace, final EnumResolver enumResolver) {
-        Element xml = instanceMapping.toXml(rootOn, namespace, document, parentElement, enumResolver);
-
-        if (instanceIndex != null) {
-            xml.setAttribute(KEY_ATTRIBUTE_KEY, instanceIndex);
-        }
-
-        for (Entry<String, InstanceRuntime> childMappingEntry : childrenMappings.entrySet()) {
-            Set<ObjectName> innerRootBeans = getRootBeans(childRbeOns, childMappingEntry.getKey(), rootOn
-                    .getKeyPropertyList().size());
-
-            for (ObjectName objectName : innerRootBeans) {
-                Set<ObjectName> innerChildRbeOns = findChildren(objectName, childRbeOns);
-                String runtimeInstanceIndex = objectName.getKeyProperty(childMappingEntry.getKey());
-
-                String elementName = jmxToYangChildRbeMapping.get(childMappingEntry.getKey());
-
-                Element innerXml = XmlUtil.createElement(document, elementName, Optional.of(namespace));
-                childMappingEntry.getValue().toXml(objectName, innerChildRbeOns, document,
-                        runtimeInstanceIndex, innerXml, namespace, enumResolver);
-                xml.appendChild(innerXml);
-            }
-        }
-
-        return xml;
-    }
-
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/ModuleRuntime.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/ModuleRuntime.java
deleted file mode 100644 (file)
index ca2c019..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.mapping.runtime;
-
-import com.google.common.collect.Sets;
-import java.util.Collection;
-import java.util.Set;
-import javax.management.ObjectName;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleConfig;
-import org.opendaylight.controller.netconf.confignetconfconnector.osgi.EnumResolver;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-public class ModuleRuntime {
-
-    private final InstanceRuntime instanceRuntime;
-
-    public ModuleRuntime(InstanceRuntime instanceRuntime) {
-        this.instanceRuntime = instanceRuntime;
-    }
-
-    private ObjectName findRoot(Collection<ObjectName> runtimeBeanOns) {
-        for (ObjectName objectName : runtimeBeanOns) {
-            if (objectName.getKeyPropertyList().size() == 3){
-                return objectName;
-            }
-        }
-        throw new IllegalStateException("Root runtime bean not found among " + runtimeBeanOns);
-    }
-
-    public Element toXml(String namespace, Collection<ObjectName> runtimeBeanOns,
-                         Document document, ModuleConfig moduleConfig, ObjectName configBeanON, final EnumResolver enumResolver) {
-
-        Element moduleElement = moduleConfig.toXml(configBeanON, document, namespace, enumResolver);
-
-        ObjectName rootName = findRoot(runtimeBeanOns);
-
-        Set<ObjectName> childrenRuntimeBeans = Sets.newHashSet(runtimeBeanOns);
-        childrenRuntimeBeans.remove(rootName);
-
-        // FIXME: why is this called and not used?
-        instanceRuntime.toXml(rootName, childrenRuntimeBeans, document, moduleElement, namespace, enumResolver);
-
-        return moduleElement;
-    }
-
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/Runtime.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/Runtime.java
deleted file mode 100644 (file)
index ddbc99d..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.mapping.runtime;
-
-import com.google.common.base.Optional;
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Multimap;
-import java.util.Collection;
-import java.util.Map;
-import java.util.Set;
-import javax.management.ObjectName;
-import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Config;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleConfig;
-import org.opendaylight.controller.netconf.confignetconfconnector.osgi.EnumResolver;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-public class Runtime {
-
-    private final Map<String, Map<String, ModuleRuntime>> moduleRuntimes;
-    private final Map<String, Map<String, ModuleConfig>> moduleConfigs;
-
-    public Runtime(Map<String, Map<String, ModuleRuntime>> moduleRuntimes,
-            Map<String, Map<String, ModuleConfig>> moduleConfigs) {
-        this.moduleRuntimes = moduleRuntimes;
-        this.moduleConfigs = moduleConfigs;
-    }
-
-    private Map<String, Multimap<String, ObjectName>> mapInstancesToModules(Set<ObjectName> instancesToMap) {
-        Map<String, Multimap<String, ObjectName>> retVal = Maps.newHashMap();
-
-        // TODO map to namepsace, prevent module name conflicts
-        // this code does not support same module names from different namespaces
-        // Namespace should be present in ObjectName
-
-        for (ObjectName objectName : instancesToMap) {
-            String moduleName = ObjectNameUtil.getFactoryName(objectName);
-
-            Multimap<String, ObjectName> multimap = retVal.get(moduleName);
-            if (multimap == null) {
-                multimap = HashMultimap.create();
-                retVal.put(moduleName, multimap);
-            }
-
-            String instanceName = ObjectNameUtil.getInstanceName(objectName);
-
-            multimap.put(instanceName, objectName);
-        }
-
-        return retVal;
-    }
-
-    public Element toXml(Set<ObjectName> instancesToMap, Set<ObjectName> configBeans, Document document, final EnumResolver enumResolver) {
-        Element root = XmlUtil.createElement(document, XmlNetconfConstants.DATA_KEY, Optional.<String>absent());
-
-        Element modulesElement = XmlUtil.createElement(document, XmlNetconfConstants.MODULES_KEY, Optional.of(XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG));
-        root.appendChild(modulesElement);
-
-        Map<String, Multimap<String, ObjectName>> moduleToRuntimeInstance = mapInstancesToModules(instancesToMap);
-        Map<String, Map<String, Collection<ObjectName>>> moduleToConfigInstance = Config.getMappedInstances(
-                configBeans, moduleConfigs);
-
-        for (String localNamespace : moduleConfigs.keySet()) {
-
-            Map<String, Collection<ObjectName>> instanceToMbe = moduleToConfigInstance.get(localNamespace);
-
-            for (String moduleName : moduleConfigs.get(localNamespace).keySet()) {
-                Multimap<String, ObjectName> instanceToRbe = moduleToRuntimeInstance.get(moduleName);
-
-                for (ObjectName instanceON : instanceToMbe.get(moduleName)) {
-                    String instanceName = ObjectNameUtil.getInstanceName(instanceON);
-
-                    Element runtimeXml;
-                    ModuleConfig moduleConfig = moduleConfigs.get(localNamespace).get(moduleName);
-                    if(instanceToRbe==null || !instanceToRbe.containsKey(instanceName)) {
-                        runtimeXml = moduleConfig.toXml(instanceON, document, localNamespace, enumResolver);
-                    } else {
-                        ModuleRuntime moduleRuntime = moduleRuntimes.get(localNamespace).get(moduleName);
-                        runtimeXml = moduleRuntime.toXml(localNamespace, instanceToRbe.get(instanceName), document,
-                                moduleConfig, instanceON, enumResolver);
-                    }
-                    modulesElement.appendChild(runtimeXml);
-                }
-
-            }
-        }
-
-        return root;
-    }
-
-}
index c4217106cee221cc543b405eb6e4423a64437d8f..8029a1b0a62352098fc7250b68881ddae08364f5 100644 (file)
@@ -8,20 +8,20 @@
 
 package org.opendaylight.controller.netconf.confignetconfconnector.operations;
 
-import org.opendaylight.controller.config.util.ConfigRegistryClient;
+import org.opendaylight.controller.config.facade.xml.ConfigSubsystemFacade;
 import org.opendaylight.controller.netconf.util.mapping.AbstractLastNetconfOperation;
 
 public abstract class AbstractConfigNetconfOperation extends AbstractLastNetconfOperation {
 
-    private final ConfigRegistryClient configRegistryClient;
+    private final ConfigSubsystemFacade configSubsystemFacade;
 
-    protected AbstractConfigNetconfOperation(ConfigRegistryClient configRegistryClient,
+    protected AbstractConfigNetconfOperation(ConfigSubsystemFacade configSubsystemFacade,
             String netconfSessionIdForReporting) {
         super(netconfSessionIdForReporting);
-        this.configRegistryClient = configRegistryClient;
+        this.configSubsystemFacade = configSubsystemFacade;
     }
 
-    public ConfigRegistryClient getConfigRegistryClient() {
-        return configRegistryClient;
+    public ConfigSubsystemFacade getConfigSubsystemFacade() {
+        return configSubsystemFacade;
     }
 }
index 8a0830e48ad18c222b80db0d116b248af28a29ca..6e295580f92b3f50bd32777ab979d547a850c3da 100644 (file)
@@ -12,12 +12,12 @@ import com.google.common.base.Optional;
 import org.opendaylight.controller.config.api.ConflictingVersionException;
 import org.opendaylight.controller.config.api.ValidationException;
 import org.opendaylight.controller.config.api.jmx.CommitStatus;
-import org.opendaylight.controller.config.util.ConfigRegistryClient;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.config.facade.xml.ConfigSubsystemFacade;
+import org.opendaylight.controller.config.facade.xml.Datastore;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.config.util.xml.XmlElement;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
@@ -27,15 +27,11 @@ public class Commit extends AbstractConfigNetconfOperation {
 
     private static final Logger LOG = LoggerFactory.getLogger(Commit.class);
 
-    private final TransactionProvider transactionProvider;
-
-    public Commit(TransactionProvider transactionProvider, ConfigRegistryClient configRegistryClient,
-            String netconfSessionIdForReporting) {
-        super(configRegistryClient, netconfSessionIdForReporting);
-        this.transactionProvider = transactionProvider;
+    public  Commit(final ConfigSubsystemFacade configSubsystemFacade, final String netconfSessionIdForReporting) {
+        super(configSubsystemFacade, netconfSessionIdForReporting);
     }
 
-    private static void checkXml(XmlElement xml) throws NetconfDocumentedException {
+    private static void checkXml(XmlElement xml) throws DocumentedException {
         xml.checkName(XmlNetconfConstants.COMMIT);
         xml.checkNamespace(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
     }
@@ -46,15 +42,15 @@ public class Commit extends AbstractConfigNetconfOperation {
     }
 
     @Override
-    protected Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws NetconfDocumentedException {
+    protected Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws DocumentedException {
 
         checkXml(xml);
         CommitStatus status;
         try {
-            status = this.transactionProvider.commitTransaction();
+            status = getConfigSubsystemFacade().commitTransaction();
             LOG.trace("Datastore {} committed successfully: {}", Datastore.candidate, status);
         } catch (ConflictingVersionException | ValidationException e) {
-            throw NetconfDocumentedException.wrap(e);
+            throw DocumentedException.wrap(e);
         }
         LOG.trace("Datastore {} committed successfully: {}", Datastore.candidate, status);
 
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/Datastore.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/Datastore.java
deleted file mode 100644 (file)
index 9c55953..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.operations;
-
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.getconfig.CandidateDatastoreQueryStrategy;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.getconfig.DatastoreQueryStrategy;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.getconfig.RunningDatastoreQueryStrategy;
-import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider;
-
-public enum Datastore {
-
-    running, candidate;
-
-    /**
-     * @param source
-     * @param transactionProvider
-     * @return
-     */
-    public static DatastoreQueryStrategy getInstanceQueryStrategy(Datastore source,
-            TransactionProvider transactionProvider) {
-        switch (source) {
-        case running:
-            return new RunningDatastoreQueryStrategy(transactionProvider);
-        case candidate:
-            return new CandidateDatastoreQueryStrategy(transactionProvider);
-        default:
-            throw new UnsupportedOperationException("Unimplemented datastore query strategy for " + source);
-        }
-    }
-}
index 1f70a1e52df63b62118e8c97af6b4107c9f068b8..3010b4ffe993d4d168f9de6ea28ee93cc19bdef7 100644 (file)
@@ -11,15 +11,15 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations;
 import com.google.common.base.Optional;
 import java.util.HashMap;
 import java.util.Map;
-import org.opendaylight.controller.config.util.ConfigRegistryClient;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorSeverity;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorTag;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorType;
+import org.opendaylight.controller.config.facade.xml.ConfigSubsystemFacade;
+import org.opendaylight.controller.config.facade.xml.Datastore;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorSeverity;
+import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorTag;
+import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorType;
+import org.opendaylight.controller.config.util.xml.XmlElement;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
@@ -32,15 +32,11 @@ public class DiscardChanges extends AbstractConfigNetconfOperation {
 
     private static final Logger LOG = LoggerFactory.getLogger(DiscardChanges.class);
 
-    private final TransactionProvider transactionProvider;
-
-    public DiscardChanges(final TransactionProvider transactionProvider, ConfigRegistryClient configRegistryClient,
-            String netconfSessionIdForReporting) {
-        super(configRegistryClient, netconfSessionIdForReporting);
-        this.transactionProvider = transactionProvider;
+    public DiscardChanges(final ConfigSubsystemFacade configSubsystemFacade, final String netconfSessionIdForReporting) {
+        super(configSubsystemFacade, netconfSessionIdForReporting);
     }
 
-    private static void fromXml(XmlElement xml) throws NetconfDocumentedException {
+    private static void fromXml(XmlElement xml) throws DocumentedException {
         xml.checkName(DISCARD);
         xml.checkNamespace(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
     }
@@ -51,19 +47,17 @@ public class DiscardChanges extends AbstractConfigNetconfOperation {
     }
 
     @Override
-    protected Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws NetconfDocumentedException {
+    protected Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws DocumentedException {
         fromXml(xml);
         try {
-            if (transactionProvider.getTransaction().isPresent()) {
-                this.transactionProvider.abortTransaction();
-            }
+            getConfigSubsystemFacade().abortConfiguration();
         } catch (final RuntimeException e) {
             LOG.warn("Abort failed: ", e);
             final Map<String, String> errorInfo = new HashMap<>();
             errorInfo
                     .put(ErrorTag.operation_failed.name(),
                             "Abort failed.");
-            throw new NetconfDocumentedException(e.getMessage(), e, ErrorType.application, ErrorTag.operation_failed,
+            throw new DocumentedException(e.getMessage(), e, ErrorType.application, ErrorTag.operation_failed,
                     ErrorSeverity.error, errorInfo);
         }
         LOG.trace("Changes discarded successfully from datastore {}", Datastore.candidate);
index ea019642c5f301aaae40bc2298b8c9dd50f5f923..f9372c0cf3caceb44d6c6807fcf1d377d783425e 100644 (file)
@@ -9,13 +9,12 @@
 package org.opendaylight.controller.netconf.confignetconfconnector.operations;
 
 import com.google.common.base.Optional;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.config.facade.xml.Datastore;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.config.util.xml.XmlElement;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.util.exception.MissingNameSpaceException;
-import org.opendaylight.controller.netconf.util.exception.UnexpectedNamespaceException;
 import org.opendaylight.controller.netconf.util.mapping.AbstractLastNetconfOperation;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
@@ -37,7 +36,7 @@ public class Lock extends AbstractLastNetconfOperation {
     }
 
     @Override
-    protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement operationElement) throws NetconfDocumentedException {
+    protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement operationElement) throws DocumentedException {
         final Datastore targetDatastore = extractTargetParameter(operationElement);
         if(targetDatastore == Datastore.candidate) {
             // Since candidate datastore instances are allocated per session and not accessible anywhere else, no need to lock
@@ -47,19 +46,13 @@ public class Lock extends AbstractLastNetconfOperation {
         }
 
         // Not supported running lock
-        throw new NetconfDocumentedException("Unable to lock " + Datastore.running + " datastore", NetconfDocumentedException.ErrorType.application,
-                NetconfDocumentedException.ErrorTag.operation_not_supported, NetconfDocumentedException.ErrorSeverity.error);
+        throw new DocumentedException("Unable to lock " + Datastore.running + " datastore", DocumentedException.ErrorType.application,
+                DocumentedException.ErrorTag.operation_not_supported, DocumentedException.ErrorSeverity.error);
     }
 
-    static Datastore extractTargetParameter(final XmlElement operationElement) throws NetconfDocumentedException {
-        final XmlElement targetChildNode;
-        try {
-            final XmlElement targetElement = operationElement.getOnlyChildElementWithSameNamespace(TARGET_KEY);
-            targetChildNode = targetElement.getOnlyChildElementWithSameNamespace();
-        } catch (final MissingNameSpaceException | UnexpectedNamespaceException e) {
-            LOG.trace("Can't get only child element with same namespace", e);
-            throw NetconfDocumentedException.wrap(e);
-        }
+    static Datastore extractTargetParameter(final XmlElement operationElement) throws DocumentedException {
+        final XmlElement targetElement = operationElement.getOnlyChildElementWithSameNamespace(TARGET_KEY);
+        final XmlElement targetChildNode = targetElement.getOnlyChildElementWithSameNamespace();
 
         return Datastore.valueOf(targetChildNode.getName());
     }
index 07b10aa3279f1f5a0915cf838af3efdc34128642..c2212732417fe18633a2fd584a77ebb98d098874 100644 (file)
@@ -9,11 +9,12 @@
 package org.opendaylight.controller.netconf.confignetconfconnector.operations;
 
 import com.google.common.base.Optional;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.config.facade.xml.Datastore;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.config.util.xml.XmlElement;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
 import org.opendaylight.controller.netconf.util.mapping.AbstractLastNetconfOperation;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
@@ -34,7 +35,7 @@ public class UnLock extends AbstractLastNetconfOperation {
     }
 
     @Override
-    protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement operationElement) throws NetconfDocumentedException {
+    protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement operationElement) throws DocumentedException {
         final Datastore targetDatastore = Lock.extractTargetParameter(operationElement);
         if(targetDatastore == Datastore.candidate) {
             // Since candidate datastore instances are allocated per session and not accessible anywhere else, no need to lock
@@ -44,8 +45,8 @@ public class UnLock extends AbstractLastNetconfOperation {
         }
 
         // Not supported running lock
-        throw new NetconfDocumentedException("Unable to unlock " + Datastore.running + " datastore", NetconfDocumentedException.ErrorType.application,
-                NetconfDocumentedException.ErrorTag.operation_not_supported, NetconfDocumentedException.ErrorSeverity.error);
+        throw new DocumentedException("Unable to unlock " + Datastore.running + " datastore", DocumentedException.ErrorType.application,
+                DocumentedException.ErrorTag.operation_not_supported, DocumentedException.ErrorSeverity.error);
     }
 
     @Override
index 6fc7165ed7b490861d03f0ffbae0e0aa253486fa..38918b18cadb78253ca80ff32a28bf8f0ca36f38 100644 (file)
@@ -12,15 +12,15 @@ import com.google.common.base.Optional;
 import java.util.HashMap;
 import java.util.Map;
 import org.opendaylight.controller.config.api.ValidationException;
-import org.opendaylight.controller.config.util.ConfigRegistryClient;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorSeverity;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorTag;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorType;
+import org.opendaylight.controller.config.facade.xml.ConfigSubsystemFacade;
+import org.opendaylight.controller.config.facade.xml.Datastore;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorSeverity;
+import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorTag;
+import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorType;
+import org.opendaylight.controller.config.util.xml.XmlElement;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
@@ -32,15 +32,11 @@ public class Validate extends AbstractConfigNetconfOperation {
 
     private static final Logger LOG = LoggerFactory.getLogger(Validate.class);
 
-    private final TransactionProvider transactionProvider;
-
-    public Validate(final TransactionProvider transactionProvider, ConfigRegistryClient configRegistryClient,
-            String netconfSessionIdForReporting) {
-        super(configRegistryClient, netconfSessionIdForReporting);
-        this.transactionProvider = transactionProvider;
+    public Validate(final ConfigSubsystemFacade configSubsystemFacade, final String netconfSessionIdForReporting) {
+        super(configSubsystemFacade, netconfSessionIdForReporting);
     }
 
-    private void checkXml(XmlElement xml) throws NetconfDocumentedException {
+    private void checkXml(XmlElement xml) throws DocumentedException {
         xml.checkName(VALIDATE);
         xml.checkNamespace(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
 
@@ -53,8 +49,8 @@ public class Validate extends AbstractConfigNetconfOperation {
         Datastore sourceDatastore = Datastore.valueOf(datastoreValue);
 
         if (sourceDatastore != Datastore.candidate){
-            throw new NetconfDocumentedException( "Only " + Datastore.candidate
-                    + " is supported as source for " + VALIDATE + " but was " + datastoreValue,ErrorType.application,ErrorTag.data_missing,ErrorSeverity.error);
+            throw new DocumentedException( "Only " + Datastore.candidate
+                    + " is supported as source for " + VALIDATE + " but was " + datastoreValue, ErrorType.application, ErrorTag.data_missing, ErrorSeverity.error);
         }
     }
 
@@ -64,20 +60,20 @@ public class Validate extends AbstractConfigNetconfOperation {
     }
 
     @Override
-    protected Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws NetconfDocumentedException {
+    protected Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws DocumentedException {
         checkXml(xml);
         try {
-            transactionProvider.validateTransaction();
+            getConfigSubsystemFacade().validateConfiguration();
         } catch (ValidationException e) {
             LOG.warn("Validation failed", e);
-            throw NetconfDocumentedException.wrap(e);
+            throw DocumentedException.wrap(e);
         } catch (IllegalStateException e) {
             LOG.warn("Validation failed", e);
             final Map<String, String> errorInfo = new HashMap<>();
             errorInfo
                     .put(ErrorTag.operation_failed.name(),
                             "Datastore is not present. Use 'get-config' or 'edit-config' before triggering 'operations' operation");
-            throw new NetconfDocumentedException(e.getMessage(), e, ErrorType.application, ErrorTag.operation_failed,
+            throw new DocumentedException(e.getMessage(), e, ErrorType.application, ErrorTag.operation_failed,
                     ErrorSeverity.error, errorInfo);
 
         }
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/AbstractEditConfigStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/AbstractEditConfigStrategy.java
deleted file mode 100644 (file)
index df46713..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig;
-
-import java.util.Map;
-import javax.management.InstanceNotFoundException;
-import javax.management.ObjectName;
-import org.opendaylight.controller.config.util.ConfigTransactionClient;
-import org.opendaylight.controller.netconf.confignetconfconnector.exception.NetconfConfigHandlingException;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public abstract class AbstractEditConfigStrategy implements EditConfigStrategy {
-
-    private static final Logger LOG = LoggerFactory.getLogger(AbstractEditConfigStrategy.class);
-
-    @Override
-    public void executeConfiguration(String module, String instance, Map<String, AttributeConfigElement> configuration,
-                                     ConfigTransactionClient ta, ServiceRegistryWrapper services) throws NetconfConfigHandlingException {
-
-        try {
-            ObjectName on = ta.lookupConfigBean(module, instance);
-            LOG.debug("ServiceInstance for {} {} located successfully under {}", module, instance, on);
-            executeStrategy(configuration, ta, on, services);
-        } catch (InstanceNotFoundException e) {
-            handleMissingInstance(configuration, ta, module, instance, services);
-        }
-
-    }
-
-    // TODO split missing instances handling strategies from edit config strategies in this hierarchy = REFACTOR
-    // edit configs should not handle missing
-
-    abstract void handleMissingInstance(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta,
-                                        String module, String instance, ServiceRegistryWrapper services) throws NetconfConfigHandlingException;
-
-    abstract void executeStrategy(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta,
-                                  ObjectName objectName, ServiceRegistryWrapper services) throws NetconfConfigHandlingException;
-
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/DeleteEditConfigStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/DeleteEditConfigStrategy.java
deleted file mode 100644 (file)
index 0155d59..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig;
-
-import java.util.Map;
-import javax.management.InstanceNotFoundException;
-import javax.management.ObjectName;
-import org.opendaylight.controller.config.util.ConfigTransactionClient;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.confignetconfconnector.exception.NetconfConfigHandlingException;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class DeleteEditConfigStrategy extends AbstractEditConfigStrategy {
-
-    private static final Logger LOG = LoggerFactory.getLogger(DeleteEditConfigStrategy.class);
-
-
-    @Override
-    void handleMissingInstance(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta,
-                               String module, String instance, ServiceRegistryWrapper services) throws NetconfConfigHandlingException {
-        throw new NetconfConfigHandlingException(String.format("Unable to delete %s : %s , ServiceInstance not found", module ,instance),
-                NetconfDocumentedException.ErrorType.application,
-                NetconfDocumentedException.ErrorTag.operation_failed,
-                NetconfDocumentedException.ErrorSeverity.error);
-    }
-
-    @Override
-    void executeStrategy(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta, ObjectName on, ServiceRegistryWrapper services) throws NetconfConfigHandlingException {
-        try {
-            ta.destroyModule(on);
-            LOG.debug("ServiceInstance {} deleted successfully", on);
-        } catch (InstanceNotFoundException e) {
-            throw new NetconfConfigHandlingException(
-                    String.format("Unable to delete %s because of exception %s" + on, e.getMessage()),
-                    NetconfDocumentedException.ErrorType.application,
-                    NetconfDocumentedException.ErrorTag.operation_failed,
-                    NetconfDocumentedException.ErrorSeverity.error);
-        }
-    }
-}
index b7699bf69ce82fb16f5eaa57197a6829cdab9a0d..d9076fa89191529fc83aef780b16d1d111b4dc95 100644 (file)
@@ -10,41 +10,20 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.ed
 
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Multimap;
-import java.util.Date;
 import java.util.HashMap;
 import java.util.Map;
-import java.util.Set;
-import javax.management.InstanceNotFoundException;
-import javax.management.ObjectName;
 import org.opendaylight.controller.config.api.ValidationException;
-import org.opendaylight.controller.config.util.BeanReader;
-import org.opendaylight.controller.config.util.ConfigRegistryClient;
-import org.opendaylight.controller.config.util.ConfigTransactionClient;
-import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorSeverity;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorTag;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorType;
+import org.opendaylight.controller.config.facade.xml.ConfigExecution;
+import org.opendaylight.controller.config.facade.xml.ConfigSubsystemFacade;
+import org.opendaylight.controller.config.facade.xml.mapping.config.Config;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorSeverity;
+import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorTag;
+import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorType;
+import org.opendaylight.controller.config.util.xml.XmlElement;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Config;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfig;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfigElementResolved;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleConfig;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleElementDefinition;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleElementResolved;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services.ServiceInstance;
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.AbstractConfigNetconfOperation;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfigXmlParser.EditConfigExecution;
-import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreContext;
-import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
-import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
-import org.opendaylight.yangtools.yang.model.api.Module;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
@@ -54,243 +33,30 @@ public class EditConfig extends AbstractConfigNetconfOperation {
 
     private static final Logger LOG = LoggerFactory.getLogger(EditConfig.class);
 
-    private final YangStoreContext yangStoreSnapshot;
-
-    private final TransactionProvider transactionProvider;
     private EditConfigXmlParser editConfigXmlParser;
 
-    public EditConfig(YangStoreContext yangStoreSnapshot, TransactionProvider transactionProvider,
-            ConfigRegistryClient configRegistryClient, String netconfSessionIdForReporting) {
-        super(configRegistryClient, netconfSessionIdForReporting);
-        this.yangStoreSnapshot = yangStoreSnapshot;
-        this.transactionProvider = transactionProvider;
+    public EditConfig(final ConfigSubsystemFacade configSubsystemFacade, final String netconfSessionIdForReporting) {
+        super(configSubsystemFacade, netconfSessionIdForReporting);
         this.editConfigXmlParser = new EditConfigXmlParser();
     }
 
     @VisibleForTesting
     Element getResponseInternal(final Document document,
-            final EditConfigXmlParser.EditConfigExecution editConfigExecution) throws NetconfDocumentedException {
-
-        if (editConfigExecution.shouldTest()) {
-            executeTests(getConfigRegistryClient(), editConfigExecution);
-        }
-
-        if (editConfigExecution.shouldSet()) {
-            executeSet(getConfigRegistryClient(), editConfigExecution);
-        }
-
-        LOG.trace("Operation {} successful", EditConfigXmlParser.EDIT_CONFIG);
-
-        return XmlUtil.createElement(document, XmlNetconfConstants.OK, Optional.<String>absent());
-    }
+            final ConfigExecution configExecution) throws DocumentedException {
 
-    private void executeSet(ConfigRegistryClient configRegistryClient,
-            EditConfigXmlParser.EditConfigExecution editConfigExecution) throws NetconfDocumentedException {
-        set(configRegistryClient, editConfigExecution);
-        LOG.debug("Set phase for {} operation successful", EditConfigXmlParser.EDIT_CONFIG);
-    }
-
-    private void executeTests(ConfigRegistryClient configRegistryClient,
-            EditConfigExecution editConfigExecution) throws NetconfDocumentedException {
         try {
-            test(configRegistryClient, editConfigExecution, editConfigExecution.getDefaultStrategy());
-        } catch (final ValidationException e) {
+            getConfigSubsystemFacade().executeConfigExecution(configExecution);
+        } catch (ValidationException e) {
             LOG.warn("Test phase for {} failed", EditConfigXmlParser.EDIT_CONFIG, e);
             final Map<String, String> errorInfo = new HashMap<>();
             errorInfo.put(ErrorTag.operation_failed.name(), e.getMessage());
-            throw new NetconfDocumentedException("Test phase: " + e.getMessage(), e, ErrorType.application,
+            throw new DocumentedException("Test phase: " + e.getMessage(), e, ErrorType.application,
                     ErrorTag.operation_failed, ErrorSeverity.error, errorInfo);
         }
-        LOG.debug("Test phase for {} operation successful", EditConfigXmlParser.EDIT_CONFIG);
-    }
-
-    private void test(ConfigRegistryClient configRegistryClient, EditConfigExecution execution,
-            EditStrategyType editStrategyType) throws ValidationException, NetconfDocumentedException {
-        ObjectName taON = transactionProvider.getTestTransaction();
-        try {
-            // default strategy = replace wipes config
-            if (editStrategyType == EditStrategyType.replace) {
-                transactionProvider.wipeTestTransaction(taON);
-            }
-
-            ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(taON);
-
-            handleMisssingInstancesOnTransaction(ta, execution);
-            setServicesOnTransaction(ta, execution);
-            setOnTransaction(ta, execution);
-            transactionProvider.validateTestTransaction(taON);
-        } finally {
-            transactionProvider.abortTestTransaction(taON);
-        }
-    }
-
-    private void set(ConfigRegistryClient configRegistryClient,
-            EditConfigXmlParser.EditConfigExecution editConfigExecution) throws NetconfDocumentedException {
-        ObjectName taON = transactionProvider.getOrCreateTransaction();
-
-        // default strategy = replace wipes config
-        if (editConfigExecution.getDefaultStrategy() == EditStrategyType.replace) {
-            transactionProvider.wipeTransaction();
-        }
-
-        ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(taON);
-
-        handleMisssingInstancesOnTransaction(ta, editConfigExecution);
-        setServicesOnTransaction(ta, editConfigExecution);
-        setOnTransaction(ta, editConfigExecution);
-    }
-
-    private void setServicesOnTransaction(ConfigTransactionClient ta, EditConfigExecution execution) throws NetconfDocumentedException {
-
-        Services services = execution.getServices();
-
-        Map<String, Map<String, Map<String, Services.ServiceInstance>>> namespaceToServiceNameToRefNameToInstance = services
-                .getNamespaceToServiceNameToRefNameToInstance();
-
-        for (Map.Entry<String, Map<String, Map<String, Services.ServiceInstance>>> namespaceToServiceToRefEntry : namespaceToServiceNameToRefNameToInstance.entrySet()) {
-            for (Map.Entry<String, Map<String, Services.ServiceInstance>> serviceToRefEntry : namespaceToServiceToRefEntry.getValue().entrySet()) {
-
-                String qnameOfService = getQname(ta, namespaceToServiceToRefEntry.getKey(), serviceToRefEntry.getKey());
-                Map<String, Services.ServiceInstance> refNameToInstance = serviceToRefEntry.getValue();
-
-                for (Map.Entry<String, Services.ServiceInstance> refNameToServiceEntry : refNameToInstance.entrySet()) {
-                    ObjectName on = refNameToServiceEntry.getValue().getObjectName(ta.getTransactionName());
-                    try {
-                        if (ServiceInstance.EMPTY_SERVICE_INSTANCE == refNameToServiceEntry.getValue()) {
-                            ta.removeServiceReference(qnameOfService, refNameToServiceEntry.getKey());
-                            LOG.debug("Removing service {} with name {}", qnameOfService, refNameToServiceEntry.getKey());
-                        } else {
-                            ObjectName saved = ta.saveServiceReference(qnameOfService, refNameToServiceEntry.getKey(), on);
-                            LOG.debug("Saving service {} with on {} under name {} with service on {}", qnameOfService,
-                                    on, refNameToServiceEntry.getKey(), saved);
-                        }
-                    } catch (InstanceNotFoundException e) {
-                        throw new NetconfDocumentedException(String.format("Unable to edit ref name " + refNameToServiceEntry.getKey() + " for instance " + on, e),
-                                ErrorType.application,
-                                ErrorTag.operation_failed,
-                                ErrorSeverity.error);
-                    }
-                }
-            }
-        }
-    }
-
-    private String getQname(ConfigTransactionClient ta, String namespace, String serviceName) {
-        return ta.getServiceInterfaceName(namespace, serviceName);
-    }
-
-    private void setOnTransaction(ConfigTransactionClient ta, EditConfigExecution execution) throws NetconfDocumentedException {
-
-        for (Multimap<String, ModuleElementResolved> modulesToResolved : execution.getResolvedXmlElements(ta).values()) {
-
-            for (Map.Entry<String, ModuleElementResolved> moduleToResolved : modulesToResolved.entries()) {
-                String moduleName = moduleToResolved.getKey();
-
-                ModuleElementResolved moduleElementResolved = moduleToResolved.getValue();
-                String instanceName = moduleElementResolved.getInstanceName();
 
-                InstanceConfigElementResolved ice = moduleElementResolved.getInstanceConfigElementResolved();
-                EditConfigStrategy strategy = ice.getEditStrategy();
-                strategy.executeConfiguration(moduleName, instanceName, ice.getConfiguration(), ta, execution.getServiceRegistryWrapper(ta));
-            }
-        }
-    }
-
-    private void handleMisssingInstancesOnTransaction(ConfigTransactionClient ta,
-            EditConfigExecution execution) throws NetconfDocumentedException {
-
-        for (Multimap<String,ModuleElementDefinition> modulesToResolved : execution.getModulesDefinition(ta).values()) {
-            for (Map.Entry<String, ModuleElementDefinition> moduleToResolved : modulesToResolved.entries()) {
-                String moduleName = moduleToResolved.getKey();
-
-                ModuleElementDefinition moduleElementDefinition = moduleToResolved.getValue();
-
-                EditConfigStrategy strategy = moduleElementDefinition.getEditStrategy();
-                strategy.executeConfiguration(moduleName, moduleElementDefinition.getInstanceName(), null, ta, execution.getServiceRegistryWrapper(ta));
-            }
-        }
-    }
-
-    public static Config getConfigMapping(ConfigRegistryClient configRegistryClient, YangStoreContext yangStoreSnapshot) {
-        Map<String, Map<String, ModuleConfig>> factories = transformMbeToModuleConfigs(configRegistryClient,
-                yangStoreSnapshot.getModuleMXBeanEntryMap());
-        Map<String, Map<Date, IdentityMapping>> identitiesMap = transformIdentities(yangStoreSnapshot.getModules());
-        return new Config(factories, identitiesMap, yangStoreSnapshot.getEnumResolver());
-    }
-
-
-    public static class IdentityMapping {
-        private final Map<String, IdentitySchemaNode> identityNameToSchemaNode;
-
-        public IdentityMapping() {
-            this.identityNameToSchemaNode = Maps.newHashMap();
-        }
-
-        void addIdSchemaNode(IdentitySchemaNode node) {
-            String name = node.getQName().getLocalName();
-            Preconditions.checkState(!identityNameToSchemaNode.containsKey(name));
-            identityNameToSchemaNode.put(name, node);
-        }
-
-        public boolean containsIdName(String idName) {
-            return identityNameToSchemaNode.containsKey(idName);
-        }
-
-    }
-
-    private static Map<String, Map<Date, IdentityMapping>> transformIdentities(Set<Module> modules) {
-        Map<String, Map<Date, IdentityMapping>> mappedIds = Maps.newHashMap();
-        for (Module module : modules) {
-            String namespace = module.getNamespace().toString();
-            Map<Date, IdentityMapping> revisionsByNamespace= mappedIds.get(namespace);
-            if(revisionsByNamespace == null) {
-                revisionsByNamespace = Maps.newHashMap();
-                mappedIds.put(namespace, revisionsByNamespace);
-            }
-
-            Date revision = module.getRevision();
-
-            IdentityMapping identityMapping = revisionsByNamespace.get(revision);
-            if(identityMapping == null) {
-                identityMapping = new IdentityMapping();
-                revisionsByNamespace.put(revision, identityMapping);
-            }
-
-            for (IdentitySchemaNode identitySchemaNode : module.getIdentities()) {
-                identityMapping.addIdSchemaNode(identitySchemaNode);
-            }
-
-        }
-
-        return mappedIds;
-    }
-
-    public static Map<String/* Namespace from yang file */,
-        Map<String /* Name of module entry from yang file */, ModuleConfig>> transformMbeToModuleConfigs (
-            final BeanReader configRegistryClient, Map<String/* Namespace from yang file */,
-            Map<String /* Name of module entry from yang file */, ModuleMXBeanEntry>> mBeanEntries) {
-
-        Map<String, Map<String, ModuleConfig>> namespaceToModuleNameToModuleConfig = Maps.newHashMap();
-
-        for (Map.Entry<String, Map<String, ModuleMXBeanEntry>> namespaceToModuleToMbe : mBeanEntries.entrySet()) {
-            for (Map.Entry<String, ModuleMXBeanEntry> moduleNameToMbe : namespaceToModuleToMbe.getValue().entrySet()) {
-                String moduleName = moduleNameToMbe.getKey();
-                ModuleMXBeanEntry moduleMXBeanEntry = moduleNameToMbe.getValue();
-
-                ModuleConfig moduleConfig = new ModuleConfig(moduleName,
-                        new InstanceConfig(configRegistryClient,moduleMXBeanEntry.getAttributes(), moduleMXBeanEntry.getNullableDummyContainerName()));
-
-                Map<String, ModuleConfig> moduleNameToModuleConfig = namespaceToModuleNameToModuleConfig.get(namespaceToModuleToMbe.getKey());
-                if(moduleNameToModuleConfig == null) {
-                    moduleNameToModuleConfig = Maps.newHashMap();
-                    namespaceToModuleNameToModuleConfig.put(namespaceToModuleToMbe.getKey(), moduleNameToModuleConfig);
-                }
-
-                moduleNameToModuleConfig.put(moduleName, moduleConfig);
-            }
-        }
+        LOG.trace("Operation {} successful", EditConfigXmlParser.EDIT_CONFIG);
 
-        return namespaceToModuleNameToModuleConfig;
+        return XmlUtil.createElement(document, XmlNetconfConstants.OK, Optional.<String>absent());
     }
 
     @Override
@@ -299,14 +65,14 @@ public class EditConfig extends AbstractConfigNetconfOperation {
     }
 
     @Override
-    protected Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws NetconfDocumentedException {
-        EditConfigXmlParser.EditConfigExecution editConfigExecution;
-        Config cfg = getConfigMapping(getConfigRegistryClient(), yangStoreSnapshot);
-        editConfigExecution = editConfigXmlParser.fromXml(xml, cfg);
-
-        Element responseInternal;
-        responseInternal = getResponseInternal(document, editConfigExecution);
-        return responseInternal;
+    protected Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws DocumentedException {
+        ConfigExecution configExecution;
+        // FIXME config mapping getter works on dynamic yang store service and so does later executeConfigExecution method
+        // They might have different view of current yangs in ODL and might cause race conditions
+        Config cfg = getConfigSubsystemFacade().getConfigMapping();
+        configExecution = editConfigXmlParser.fromXml(xml, cfg);
+
+        return getResponseInternal(document, configExecution);
     }
 
 }
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigStrategy.java
deleted file mode 100644 (file)
index 9c78457..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig;
-
-import java.util.Map;
-import org.opendaylight.controller.config.util.ConfigTransactionClient;
-import org.opendaylight.controller.netconf.confignetconfconnector.exception.NetconfConfigHandlingException;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
-
-public interface EditConfigStrategy {
-
-    void executeConfiguration(String module, String instance, Map<String, AttributeConfigElement> configuration,
-                              ConfigTransactionClient ta, ServiceRegistryWrapper services) throws NetconfConfigHandlingException;
-
-}
index 99c0a2ff0d719865b7d39cc22143e563ce99c0fc..3995a0a5a4b364e5099185d7122ce87b225fcfb1 100644 (file)
@@ -8,23 +8,15 @@
 
 package org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig;
 
-import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Optional;
-import com.google.common.collect.Multimap;
-import java.util.Arrays;
-import java.util.Map;
-import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.config.facade.xml.ConfigExecution;
+import org.opendaylight.controller.config.facade.xml.Datastore;
+import org.opendaylight.controller.config.facade.xml.TestOption;
+import org.opendaylight.controller.config.facade.xml.mapping.config.Config;
+import org.opendaylight.controller.config.facade.xml.strategy.EditStrategyType;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.config.util.xml.XmlElement;
 import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Config;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleElementDefinition;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleElementResolved;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.Datastore;
-import org.opendaylight.controller.netconf.util.exception.MissingNameSpaceException;
-import org.opendaylight.controller.netconf.util.exception.UnexpectedNamespaceException;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -42,8 +34,8 @@ public class EditConfigXmlParser {
     public EditConfigXmlParser() {
     }
 
-    EditConfigXmlParser.EditConfigExecution fromXml(final XmlElement xml, final Config cfgMapping)
-            throws NetconfDocumentedException {
+    ConfigExecution fromXml(final XmlElement xml, final Config cfgMapping)
+            throws DocumentedException {
 
         //TODO remove transactionProvider and CfgRegistry from parameters, accept only service ref store
 
@@ -55,26 +47,22 @@ public class EditConfigXmlParser {
 
         XmlElement targetElement = null;
         XmlElement targetChildNode = null;
-        try {
-            targetElement  = xml.getOnlyChildElementWithSameNamespace(EditConfigXmlParser.TARGET_KEY);
-            targetChildNode = targetElement.getOnlyChildElementWithSameNamespace();
-        } catch (final MissingNameSpaceException | UnexpectedNamespaceException e) {
-            LOG.trace("Can't get only child element with same namespace", e);
-            throw NetconfDocumentedException.wrap(e);
-        }
+        targetElement  = xml.getOnlyChildElementWithSameNamespace(EditConfigXmlParser.TARGET_KEY);
+        targetChildNode = targetElement.getOnlyChildElementWithSameNamespace();
+
         String datastoreValue = targetChildNode.getName();
         Datastore targetDatastore = Datastore.valueOf(datastoreValue);
         LOG.debug("Setting {} to '{}'", EditConfigXmlParser.TARGET_KEY, targetDatastore);
 
         // check target
         if (targetDatastore != Datastore.candidate){
-            throw new NetconfDocumentedException(String.format(
+            throw new DocumentedException(String.format(
                     "Only %s datastore supported for edit config but was: %s",
                     Datastore.candidate,
                     targetDatastore),
-                    NetconfDocumentedException.ErrorType.application,
-                    NetconfDocumentedException.ErrorTag.invalid_value,
-                    NetconfDocumentedException.ErrorSeverity.error);
+                    DocumentedException.ErrorType.application,
+                    DocumentedException.ErrorTag.invalid_value,
+                    DocumentedException.ErrorSeverity.error);
         }
 
         // Test option
@@ -83,9 +71,9 @@ public class EditConfigXmlParser {
                 .getOnlyChildElementWithSameNamespaceOptionally(EditConfigXmlParser.TEST_OPTION_KEY);
         if (testOptionElementOpt.isPresent()) {
             String testOptionValue = testOptionElementOpt.get().getTextContent();
-            testOption = EditConfigXmlParser.TestOption.getFromXmlName(testOptionValue);
+            testOption = TestOption.getFromXmlName(testOptionValue);
         } else {
-            testOption = EditConfigXmlParser.TestOption.getDefault();
+            testOption = TestOption.getDefault();
         }
         LOG.debug("Setting {} to '{}'", EditConfigXmlParser.TEST_OPTION_KEY, testOption);
 
@@ -110,85 +98,8 @@ public class EditConfigXmlParser {
         }
 
         XmlElement configElement = null;
-        try {
-            configElement = xml.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.CONFIG_KEY);
-        } catch (MissingNameSpaceException e) {
-            LOG.trace("Can't get only child element with same namespace due to ",e);
-            throw NetconfDocumentedException.wrap(e);
-        }
-
-        return new EditConfigXmlParser.EditConfigExecution(cfgMapping, configElement, testOption, editStrategyType);
-    }
-
-    @VisibleForTesting
-    static enum TestOption {
-        testOnly, set, testThenSet;
-
-        static TestOption getFromXmlName(String testOptionXmlName) {
-            switch (testOptionXmlName) {
-            case "test-only":
-                return testOnly;
-            case "test-then-set":
-                return testThenSet;
-            case "set":
-                return set;
-            default:
-                throw new IllegalArgumentException("Unsupported test option " + testOptionXmlName + " supported: "
-                        + Arrays.toString(TestOption.values()));
-            }
-        }
-
-        public static TestOption getDefault() {
-            return testThenSet;
-        }
-
-    }
-
-    @VisibleForTesting
-    static class EditConfigExecution {
-
-        private final TestOption testOption;
-        private final EditStrategyType defaultEditStrategyType;
-        private final Services services;
-        private final Config configResolver;
-        private final XmlElement configElement;
-
-        EditConfigExecution(Config configResolver, XmlElement configElement, TestOption testOption, EditStrategyType defaultStrategy) throws NetconfDocumentedException {
-            Config.checkUnrecognisedChildren(configElement);
-            this.configResolver = configResolver;
-            this.configElement = configElement;
-            this.services = configResolver.fromXmlServices(configElement);
-            this.testOption = testOption;
-            this.defaultEditStrategyType = defaultStrategy;
-        }
+        configElement = xml.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.CONFIG_KEY);
 
-        boolean shouldTest() {
-            return testOption == TestOption.testOnly || testOption == TestOption.testThenSet;
-        }
-
-        boolean shouldSet() {
-            return testOption == TestOption.set || testOption == TestOption.testThenSet;
-        }
-
-        Map<String, Multimap<String, ModuleElementResolved>> getResolvedXmlElements(ServiceReferenceReadableRegistry serviceRegistry) throws NetconfDocumentedException {
-            return configResolver.fromXmlModulesResolved(configElement, defaultEditStrategyType, getServiceRegistryWrapper(serviceRegistry));
-        }
-
-        ServiceRegistryWrapper getServiceRegistryWrapper(ServiceReferenceReadableRegistry serviceRegistry) {
-            // TODO cache service registry
-            return new ServiceRegistryWrapper(serviceRegistry);
-        }
-
-        Map<String, Multimap<String,ModuleElementDefinition>> getModulesDefinition(ServiceReferenceReadableRegistry serviceRegistry) throws NetconfDocumentedException {
-            return configResolver.fromXmlModulesMap(configElement, defaultEditStrategyType, getServiceRegistryWrapper(serviceRegistry));
-        }
-
-        EditStrategyType getDefaultStrategy() {
-            return defaultEditStrategyType;
-        }
-
-        Services getServices() {
-            return services;
-        }
+        return new ConfigExecution(cfgMapping, configElement, testOption, editStrategyType);
     }
 }
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditStrategyType.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditStrategyType.java
deleted file mode 100644 (file)
index 25d772f..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig;
-
-import java.util.EnumSet;
-import java.util.Set;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.confignetconfconnector.exception.OperationNotPermittedException;
-
-public enum EditStrategyType {
-    // can be default
-    merge, replace, none,
-    // additional per element
-    delete, remove;
-
-    private static final Set<EditStrategyType> defaultStrats = EnumSet.of(merge, replace, none);
-
-    public static EditStrategyType getDefaultStrategy() {
-        return merge;
-    }
-
-    public boolean isEnforcing() {
-        switch (this) {
-        case merge:
-        case none:
-        case remove:
-        case delete:
-            return false;
-        case replace:
-            return true;
-
-        default:
-            throw new IllegalStateException("Default edit strategy can be only of value " + defaultStrats + " but was "
-                    + this);
-        }
-    }
-    public static void compareParsedStrategyToDefaultEnforcing(EditStrategyType parsedStrategy,
-                                                                  EditStrategyType defaultStrategy) throws OperationNotPermittedException {
-        if (defaultStrategy.isEnforcing()) {
-            if (parsedStrategy != defaultStrategy){
-                throw new OperationNotPermittedException(String.format("With "
-                        + defaultStrategy
-                        + " as "
-                        + EditConfigXmlParser.DEFAULT_OPERATION_KEY
-                        + " operations on module elements are not permitted since the default option is restrictive"),
-                        NetconfDocumentedException.ErrorType.application,
-                        NetconfDocumentedException.ErrorTag.operation_failed,
-                        NetconfDocumentedException.ErrorSeverity.error);
-            }
-        }
-
-    }
-    public EditConfigStrategy getFittingStrategy() {
-        switch (this) {
-        case merge:
-            return new MergeEditConfigStrategy();
-        case replace:
-            return new ReplaceEditConfigStrategy();
-        case delete:
-            return new DeleteEditConfigStrategy();
-        case remove:
-            return new RemoveEditConfigStrategy();
-        case none:
-            return new NoneEditConfigStrategy();
-        default:
-            throw new UnsupportedOperationException("Unimplemented edit config strategy" + this);
-        }
-    }
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MergeEditConfigStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MergeEditConfigStrategy.java
deleted file mode 100644 (file)
index d3d5bd9..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig;
-
-import static java.util.Arrays.asList;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import javax.management.Attribute;
-import javax.management.ObjectName;
-import org.opendaylight.controller.config.util.ConfigTransactionClient;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.confignetconfconnector.exception.NetconfConfigHandlingException;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class MergeEditConfigStrategy extends AbstractEditConfigStrategy {
-
-    private static final Logger LOG = LoggerFactory.getLogger(MergeEditConfigStrategy.class);
-
-    public MergeEditConfigStrategy() {
-
-    }
-
-    @Override
-    void handleMissingInstance(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta,
-                               String module, String instance, ServiceRegistryWrapper services) throws NetconfConfigHandlingException {
-        throw new NetconfConfigHandlingException(
-                String.format("Unable to handle missing instance, no missing instances should appear at this point, missing: %s : %s ",
-                        module,
-                        instance),
-                NetconfDocumentedException.ErrorType.application,
-                NetconfDocumentedException.ErrorTag.operation_failed,
-                NetconfDocumentedException.ErrorSeverity.error);
-    }
-
-    @Override
-    void executeStrategy(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta, ObjectName on, ServiceRegistryWrapper services) throws NetconfConfigHandlingException {
-
-        for (Entry<String, AttributeConfigElement> configAttributeEntry : configuration.entrySet()) {
-            try {
-                AttributeConfigElement ace = configAttributeEntry.getValue();
-
-                if (!ace.getResolvedValue().isPresent()) {
-                    LOG.debug("Skipping attribute {} for {}", configAttributeEntry.getKey(), on);
-                    continue;
-                }
-
-                Object toBeMergedIn = ace.getResolvedValue().get();
-                // Get the existing values so we can merge the new values with them.
-                Attribute currentAttribute = ta.getAttribute(on, ace.getJmxName());
-                Object oldValue = (currentAttribute != null ? currentAttribute.getValue() : null);
-                // Merge value with currentValue
-                toBeMergedIn = merge(oldValue, toBeMergedIn);
-                ta.setAttribute(on, ace.getJmxName(), new Attribute(ace.getJmxName(), toBeMergedIn));
-                LOG.debug("Attribute {} set to {} for {}", configAttributeEntry.getKey(), toBeMergedIn, on);
-            } catch (Exception e) {
-                LOG.error("Error while merging objectnames of {}", on, e);
-                throw new NetconfConfigHandlingException(String.format("Unable to set attributes for %s, Error with attribute %s : %s ",
-                        on,
-                        configAttributeEntry.getKey(),
-                        configAttributeEntry.getValue()),
-                        NetconfDocumentedException.ErrorType.application,
-                        NetconfDocumentedException.ErrorTag.operation_failed,
-                        NetconfDocumentedException.ErrorSeverity.error);
-            }
-        }
-    }
-
-    /**
-     * Merge value into current value
-     * Currently, this is only implemented for arrays of ObjectNames, but that is the
-     * most common case for which it is needed.
-     */
-    protected Object merge(Object oldValue, Object toBeMergedIn) {
-        if (oldValue instanceof ObjectName[] && toBeMergedIn instanceof ObjectName[]) {
-            toBeMergedIn = mergeObjectNameArrays((ObjectName[]) oldValue, (ObjectName[]) toBeMergedIn);
-        }
-        return toBeMergedIn;
-    }
-
-    /**
-     * Merge value into current values
-     * This implements for arrays of ObjectNames, but that is the
-     * most common case for which it is needed.
-     *
-     * @param oldValue - the new values to be merged into existing values
-     * @param toBeMergedIn - the existing values
-     *
-     * @return an ObjectName[] consisting the elements of currentValue with an elements from values not already present in currentValue added
-     *
-     */
-    protected ObjectName[] mergeObjectNameArrays(ObjectName[] oldValue, ObjectName[] toBeMergedIn) {
-        List<ObjectName> newValueList = new ArrayList<>();
-        newValueList.addAll(asList(oldValue));
-        /*
-         It is guaranteed that old values do not contain transaction name.
-         Since toBeMergedIn is filled using service references translated by ServiceRegistryWrapper, it
-         is also guaranteed that this list will not contain transaction names.
-         Run through the list of values to be merged.  If we don't have them already, add them to the list.
-         */
-        for (ObjectName objName : toBeMergedIn) {
-            if (!newValueList.contains(objName)) {
-                newValueList.add(objName);
-            }
-        }
-        return newValueList.toArray(new ObjectName[newValueList.size()]);
-    }
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MissingInstanceHandlingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MissingInstanceHandlingStrategy.java
deleted file mode 100644 (file)
index 1eb4c83..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig;
-
-import java.util.Map;
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.ObjectName;
-import org.opendaylight.controller.config.util.ConfigTransactionClient;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.confignetconfconnector.exception.NetconfConfigHandlingException;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class MissingInstanceHandlingStrategy extends AbstractEditConfigStrategy {
-
-    private static final Logger LOG = LoggerFactory.getLogger(MissingInstanceHandlingStrategy.class);
-
-    @Override
-    void handleMissingInstance(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta,
-            String module, String instance, ServiceRegistryWrapper services) throws NetconfConfigHandlingException {
-        try {
-            ObjectName on = ta.createModule(module, instance);
-            LOG.trace("New instance for {} {} created under name {}", module, instance, on);
-        } catch (InstanceAlreadyExistsException e1) {
-            throw new NetconfConfigHandlingException(String.format("Unable to create instance for %s : %s.", module, instance),
-                    NetconfDocumentedException.ErrorType.application,
-                    NetconfDocumentedException.ErrorTag.operation_failed,
-                    NetconfDocumentedException.ErrorSeverity.error);
-        }
-    }
-
-    @Override
-    void executeStrategy(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta,
-            ObjectName objectName, ServiceRegistryWrapper services) {
-    }
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/NoneEditConfigStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/NoneEditConfigStrategy.java
deleted file mode 100644 (file)
index 83afd70..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig;
-
-import java.util.Collections;
-import java.util.Map;
-import org.opendaylight.controller.config.util.ConfigTransactionClient;
-import org.opendaylight.controller.netconf.confignetconfconnector.exception.NetconfConfigHandlingException;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class NoneEditConfigStrategy implements EditConfigStrategy {
-
-    private static final Logger LOG = LoggerFactory.getLogger(NoneEditConfigStrategy.class);
-
-    @Override
-    public void executeConfiguration(String module, String instance, Map<String, AttributeConfigElement> configuration,
-                                     ConfigTransactionClient ta, ServiceRegistryWrapper services) throws NetconfConfigHandlingException {
-        if(configuration != null && !configuration.isEmpty()) {
-            for (Map.Entry<String, AttributeConfigElement> attrEntry : configuration.entrySet()) {
-                if(attrEntry.getValue().getEditStrategy().isPresent()) {
-                    final Map<String, AttributeConfigElement> partialConfig =
-                            Collections.singletonMap(attrEntry.getKey(), attrEntry.getValue());
-                    attrEntry.getValue().getEditStrategy().get().getFittingStrategy()
-                            .executeConfiguration(module, instance, partialConfig, ta, services);
-                } else {
-                    LOG.debug("Skipping configuration element for {}:{}:{}", module, instance, attrEntry.getKey());
-                }
-            }
-        } else {
-            LOG.debug("Skipping configuration element for {}:{}", module, instance);
-        }
-    }
-
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/RemoveEditConfigStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/RemoveEditConfigStrategy.java
deleted file mode 100644 (file)
index 55040d7..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig;
-
-import java.util.Map;
-import org.opendaylight.controller.config.util.ConfigTransactionClient;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class RemoveEditConfigStrategy extends DeleteEditConfigStrategy {
-
-    private static final Logger LOG = LoggerFactory.getLogger(RemoveEditConfigStrategy.class);
-
-    @Override
-    void handleMissingInstance(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta,
-                               String module, String instance, ServiceRegistryWrapper services) {
-        LOG.warn("Unable to delete {}:{}, ServiceInstance not found", module, instance);
-    }
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/ReplaceEditConfigStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/ReplaceEditConfigStrategy.java
deleted file mode 100644 (file)
index 8d786d2..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig;
-
-import java.util.Map;
-import java.util.Map.Entry;
-import javax.management.Attribute;
-import javax.management.ObjectName;
-import org.opendaylight.controller.config.util.ConfigTransactionClient;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.confignetconfconnector.exception.NetconfConfigHandlingException;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ReplaceEditConfigStrategy extends AbstractEditConfigStrategy {
-
-    private static final Logger LOG = LoggerFactory.getLogger(ReplaceEditConfigStrategy.class);
-
-    @Override
-    void handleMissingInstance(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta,
-                               String module, String instance, ServiceRegistryWrapper services) throws NetconfConfigHandlingException {
-        throw new NetconfConfigHandlingException(
-                String.format("Unable to handle missing instance, no missing instances should appear at this point, missing: %s : %s ",
-                        module,
-                        instance),
-                NetconfDocumentedException.ErrorType.application,
-                NetconfDocumentedException.ErrorTag.operation_failed,
-                NetconfDocumentedException.ErrorSeverity.error);
-    }
-
-    @Override
-    void executeStrategy(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta, ObjectName on, ServiceRegistryWrapper services) throws NetconfConfigHandlingException {
-        for (Entry<String, AttributeConfigElement> configAttributeEntry : configuration.entrySet()) {
-            try {
-                AttributeConfigElement ace = configAttributeEntry.getValue();
-
-                if (!ace.getResolvedValue().isPresent()) {
-                    Object value = ace.getResolvedDefaultValue();
-                    ta.setAttribute(on, ace.getJmxName(), new Attribute(ace.getJmxName(), value));
-                    LOG.debug("Attribute {} set to default value {} for {}", configAttributeEntry.getKey(), value,
-                            on);
-                } else {
-                    Object value = ace.getResolvedValue().get();
-                    ta.setAttribute(on, ace.getJmxName(), new Attribute(ace.getJmxName(), value));
-                    LOG.debug("Attribute {} set to value {} for {}", configAttributeEntry.getKey(), value, on);
-                }
-
-            } catch (Exception e) {
-                throw new IllegalStateException("Unable to set attributes for " + on + ", Error with attribute "
-                        + configAttributeEntry.getKey() + ":" + configAttributeEntry.getValue(), e);
-            }
-        }
-    }
-}
index 40592ea64b50ef0a1bb4f37c7c9c54c38b18c6b9..0b79f5e17cebeb12a00f869a31f0a5243b36ac68 100644 (file)
@@ -8,31 +8,11 @@
 
 package org.opendaylight.controller.netconf.confignetconfconnector.operations.get;
 
-import com.google.common.collect.Maps;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import javax.management.ObjectName;
-import org.opendaylight.controller.config.util.ConfigRegistryClient;
-import org.opendaylight.controller.config.util.ConfigTransactionClient;
-import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
-import org.opendaylight.controller.config.yangjmxgenerator.RuntimeBeanEntry;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.config.facade.xml.ConfigSubsystemFacade;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.config.util.xml.XmlElement;
 import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfig;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleConfig;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.runtime.InstanceRuntime;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.runtime.ModuleRuntime;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.runtime.Runtime;
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.AbstractConfigNetconfOperation;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.Datastore;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfig;
-import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreContext;
-import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider;
-import org.opendaylight.controller.netconf.util.exception.MissingNameSpaceException;
-import org.opendaylight.controller.netconf.util.exception.UnexpectedElementException;
-import org.opendaylight.controller.netconf.util.exception.UnexpectedNamespaceException;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
@@ -40,70 +20,13 @@ import org.w3c.dom.Element;
 
 public class Get extends AbstractConfigNetconfOperation {
 
-    private final TransactionProvider transactionProvider;
-    private final YangStoreContext yangStoreSnapshot;
     private static final Logger LOG = LoggerFactory.getLogger(Get.class);
 
-    public Get(final TransactionProvider transactionProvider, YangStoreContext yangStoreSnapshot, ConfigRegistryClient configRegistryClient,
-               String netconfSessionIdForReporting) {
-        super(configRegistryClient, netconfSessionIdForReporting);
-        this.transactionProvider = transactionProvider;
-        this.yangStoreSnapshot = yangStoreSnapshot;
+    public Get(final ConfigSubsystemFacade configSubsystemFacade, final String netconfSessionIdForReporting) {
+        super(configSubsystemFacade, netconfSessionIdForReporting);
     }
 
-    private Map<String, Map<String, ModuleRuntime>> createModuleRuntimes(ConfigRegistryClient configRegistryClient,
-            Map<String, Map<String, ModuleMXBeanEntry>> mBeanEntries) {
-        Map<String, Map<String, ModuleRuntime>> retVal = Maps.newHashMap();
-
-        for (Map.Entry<String, Map<String, ModuleMXBeanEntry>> namespaceToModuleEntry : mBeanEntries.entrySet()) {
-
-            Map<String, ModuleRuntime> innerMap = Maps.newHashMap();
-            Map<String, ModuleMXBeanEntry> entriesFromNamespace = namespaceToModuleEntry.getValue();
-            for (Map.Entry<String, ModuleMXBeanEntry> moduleToMXEntry : entriesFromNamespace.entrySet()) {
-
-                ModuleMXBeanEntry mbe = moduleToMXEntry.getValue();
-
-                Map<RuntimeBeanEntry, InstanceConfig> cache = Maps.newHashMap();
-                RuntimeBeanEntry root = null;
-                for (RuntimeBeanEntry rbe : mbe.getRuntimeBeans()) {
-                    cache.put(rbe, new InstanceConfig(configRegistryClient, rbe.getYangPropertiesToTypesMap(), mbe.getNullableDummyContainerName()));
-                    if (rbe.isRoot()){
-                        root = rbe;
-                    }
-                }
-
-                if (root == null){
-                    continue;
-                }
-
-                InstanceRuntime rootInstanceRuntime = createInstanceRuntime(root, cache);
-                ModuleRuntime moduleRuntime = new ModuleRuntime(rootInstanceRuntime);
-                innerMap.put(moduleToMXEntry.getKey(), moduleRuntime);
-            }
-
-            retVal.put(namespaceToModuleEntry.getKey(), innerMap);
-        }
-        return retVal;
-    }
-
-    private InstanceRuntime createInstanceRuntime(RuntimeBeanEntry root, Map<RuntimeBeanEntry, InstanceConfig> cache) {
-        Map<String, InstanceRuntime> children = Maps.newHashMap();
-        for (RuntimeBeanEntry child : root.getChildren()) {
-            children.put(child.getJavaNamePrefix(), createInstanceRuntime(child, cache));
-        }
-
-        return new InstanceRuntime(cache.get(root), children, createJmxToYangMap(root.getChildren()));
-    }
-
-    private Map<String, String> createJmxToYangMap(List<RuntimeBeanEntry> children) {
-        Map<String, String> jmxToYangNamesForChildRbe = Maps.newHashMap();
-        for (RuntimeBeanEntry rbe : children) {
-            jmxToYangNamesForChildRbe.put(rbe.getJavaNamePrefix(), rbe.getYangName());
-        }
-        return jmxToYangNamesForChildRbe;
-    }
-
-    private static void checkXml(XmlElement xml) throws UnexpectedElementException, UnexpectedNamespaceException, MissingNameSpaceException {
+    private static void checkXml(XmlElement xml) throws DocumentedException {
         xml.checkName(XmlNetconfConstants.GET);
         xml.checkNamespace(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
 
@@ -116,33 +39,10 @@ public class Get extends AbstractConfigNetconfOperation {
     }
 
     @Override
-    protected Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws NetconfDocumentedException {
+    protected Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws DocumentedException {
         checkXml(xml);
-
-        final ObjectName testTransaction = transactionProvider.getOrCreateReadTransaction();
-        final ConfigTransactionClient registryClient = getConfigRegistryClient().getConfigTransactionClient(testTransaction);
-
-        try {
-            // Runtime beans are not parts of transactions and have to be queried against the central registry
-            final Set<ObjectName> runtimeBeans = getConfigRegistryClient().lookupRuntimeBeans();
-
-            final Set<ObjectName> configBeans = Datastore.getInstanceQueryStrategy(Datastore.running, transactionProvider)
-                    .queryInstances(getConfigRegistryClient());
-
-            final Map<String, Map<String, ModuleRuntime>> moduleRuntimes = createModuleRuntimes(getConfigRegistryClient(),
-                    yangStoreSnapshot.getModuleMXBeanEntryMap());
-            final Map<String, Map<String, ModuleConfig>> moduleConfigs = EditConfig.transformMbeToModuleConfigs(
-                    registryClient, yangStoreSnapshot.getModuleMXBeanEntryMap());
-
-            final Runtime runtime = new Runtime(moduleRuntimes, moduleConfigs);
-
-            final Element element = runtime.toXml(runtimeBeans, configBeans, document, yangStoreSnapshot.getEnumResolver());
-
-            LOG.trace("{} operation successful", XmlNetconfConstants.GET);
-
-            return element;
-        } finally {
-            transactionProvider.closeReadTransaction();
-        }
+        final Element element = getConfigSubsystemFacade().get(document);
+        LOG.trace("{} operation successful", XmlNetconfConstants.GET);
+        return element;
     }
 }
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/getconfig/CandidateDatastoreQueryStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/getconfig/CandidateDatastoreQueryStrategy.java
deleted file mode 100644 (file)
index 6275fca..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.operations.getconfig;
-
-import java.util.Set;
-import javax.management.ObjectName;
-import org.opendaylight.controller.config.util.ConfigRegistryClient;
-import org.opendaylight.controller.config.util.ConfigTransactionClient;
-import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider;
-
-public class CandidateDatastoreQueryStrategy implements DatastoreQueryStrategy {
-
-    private final TransactionProvider transactionProvider;
-
-    public CandidateDatastoreQueryStrategy(TransactionProvider transactionProvider) {
-        this.transactionProvider = transactionProvider;
-    }
-
-    @Override
-    public Set<ObjectName> queryInstances(ConfigRegistryClient configRegistryClient) {
-        ObjectName on = transactionProvider.getOrCreateTransaction();
-        ConfigTransactionClient proxy = configRegistryClient.getConfigTransactionClient(on);
-        return proxy.lookupConfigBeans();
-    }
-
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/getconfig/DatastoreQueryStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/getconfig/DatastoreQueryStrategy.java
deleted file mode 100644 (file)
index d733116..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.operations.getconfig;
-
-import java.util.Set;
-import javax.management.ObjectName;
-import org.opendaylight.controller.config.util.ConfigRegistryClient;
-
-public interface DatastoreQueryStrategy {
-
-    /**
-     * @param configRegistryClient
-     * @return
-     */
-    Set<ObjectName> queryInstances(ConfigRegistryClient configRegistryClient);
-
-}
index 401124e7d985dbc583bb8427e998c0292682a29b..e5ba3dbb1ecbbf5e46b62d381d1ef31c2685ae37 100644 (file)
@@ -9,24 +9,12 @@
 package org.opendaylight.controller.netconf.confignetconfconnector.operations.getconfig;
 
 import com.google.common.base.Optional;
-import java.util.Set;
-import javax.management.ObjectName;
-import org.opendaylight.controller.config.util.ConfigRegistryClient;
-import org.opendaylight.controller.config.util.ConfigTransactionClient;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.config.facade.xml.ConfigSubsystemFacade;
+import org.opendaylight.controller.config.facade.xml.Datastore;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.config.util.xml.XmlElement;
 import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Config;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.AbstractConfigNetconfOperation;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.Datastore;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfig;
-import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreContext;
-import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider;
-import org.opendaylight.controller.netconf.util.exception.MissingNameSpaceException;
-import org.opendaylight.controller.netconf.util.exception.UnexpectedElementException;
-import org.opendaylight.controller.netconf.util.exception.UnexpectedNamespaceException;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
@@ -36,23 +24,16 @@ public class GetConfig extends AbstractConfigNetconfOperation {
 
     public static final String GET_CONFIG = "get-config";
 
-    private final YangStoreContext yangStoreSnapshot;
     private final Optional<String> maybeNamespace;
 
-    private final TransactionProvider transactionProvider;
-
     private static final Logger LOG = LoggerFactory.getLogger(GetConfig.class);
 
-    public GetConfig(YangStoreContext yangStoreSnapshot, Optional<String> maybeNamespace,
-            TransactionProvider transactionProvider, ConfigRegistryClient configRegistryClient,
-            String netconfSessionIdForReporting) {
-        super(configRegistryClient, netconfSessionIdForReporting);
-        this.yangStoreSnapshot = yangStoreSnapshot;
+    public GetConfig(final ConfigSubsystemFacade configSubsystemFacade, final Optional<String> maybeNamespace, final String netconfSessionIdForReporting) {
+        super(configSubsystemFacade, netconfSessionIdForReporting);
         this.maybeNamespace = maybeNamespace;
-        this.transactionProvider = transactionProvider;
     }
 
-    public static Datastore fromXml(XmlElement xml) throws UnexpectedNamespaceException, UnexpectedElementException, MissingNameSpaceException, NetconfDocumentedException {
+    public static Datastore fromXml(XmlElement xml) throws DocumentedException {
 
         xml.checkName(GET_CONFIG);
         xml.checkNamespace(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
@@ -70,49 +51,13 @@ public class GetConfig extends AbstractConfigNetconfOperation {
 
     }
 
-    private Element getResponseInternal(final Document document, final ConfigRegistryClient configRegistryClient,
-            final Datastore source) {
-
-        final ConfigTransactionClient registryClient;
-        // Read current state from a transaction, if running is source, then start new transaction just for reading
-        // in case of candidate, get current transaction representing candidate
-        if(source == Datastore.running) {
-            final ObjectName readTx = transactionProvider.getOrCreateReadTransaction();
-            registryClient = getConfigRegistryClient().getConfigTransactionClient(readTx);
-        } else {
-            registryClient  = getConfigRegistryClient().getConfigTransactionClient(transactionProvider.getOrCreateTransaction());
-        }
-
-        try {
-            Element dataElement = XmlUtil.createElement(document, XmlNetconfConstants.DATA_KEY, Optional.<String>absent());
-            final Set<ObjectName> instances = Datastore.getInstanceQueryStrategy(source, this.transactionProvider)
-                    .queryInstances(configRegistryClient);
-
-            final Config configMapping = new Config(EditConfig.transformMbeToModuleConfigs(registryClient,
-                    yangStoreSnapshot.getModuleMXBeanEntryMap()), yangStoreSnapshot.getEnumResolver());
-
-            ServiceRegistryWrapper serviceTracker = new ServiceRegistryWrapper(registryClient);
-            dataElement = configMapping.toXml(instances, this.maybeNamespace, document, dataElement, serviceTracker);
-
-            LOG.trace("{} operation successful", GET_CONFIG);
-
-            return dataElement;
-        } finally {
-            if(source == Datastore.running) {
-                transactionProvider.closeReadTransaction();
-            }
-        }
-    }
-
     @Override
     protected String getOperationName() {
         return GET_CONFIG;
     }
 
     @Override
-    public Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws NetconfDocumentedException {
-        Datastore source;
-        source = fromXml(xml);
-        return getResponseInternal(document, getConfigRegistryClient(), source);
+    public Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws DocumentedException {
+        return getConfigSubsystemFacade().getConfiguration(document, fromXml(xml), maybeNamespace);
     }
 }
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/getconfig/RunningDatastoreQueryStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/getconfig/RunningDatastoreQueryStrategy.java
deleted file mode 100644 (file)
index 74b5f60..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.operations.getconfig;
-
-import java.util.Set;
-import javax.management.ObjectName;
-import org.opendaylight.controller.config.util.ConfigRegistryClient;
-import org.opendaylight.controller.config.util.ConfigTransactionClient;
-import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider;
-
-public class RunningDatastoreQueryStrategy implements DatastoreQueryStrategy {
-
-    private final TransactionProvider transactionProvider;
-
-    public RunningDatastoreQueryStrategy(TransactionProvider transactionProvider) {
-        this.transactionProvider = transactionProvider;
-    }
-
-    @Override
-    public Set<ObjectName> queryInstances(ConfigRegistryClient configRegistryClient) {
-        ObjectName on = transactionProvider.getOrCreateReadTransaction();
-        ConfigTransactionClient proxy = configRegistryClient.getConfigTransactionClient(on);
-        return proxy.lookupConfigBeans();
-    }
-
-}
index f7d28b789e30d7f631f053249f46f09407901932..2be3308b90c801e89dff101e10a52360b04d6ee4 100644 (file)
@@ -10,32 +10,18 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.ru
 
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
-import com.google.common.collect.Maps;
-import java.util.Map;
-import javax.management.ObjectName;
-import javax.management.openmbean.OpenType;
-import org.opendaylight.controller.config.util.ConfigRegistryClient;
-import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
-import org.opendaylight.controller.config.yangjmxgenerator.RuntimeBeanEntry;
-import org.opendaylight.controller.config.yangjmxgenerator.RuntimeBeanEntry.Rpc;
-import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIfc;
-import org.opendaylight.controller.config.yangjmxgenerator.attribute.VoidAttribute;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.config.facade.xml.ConfigSubsystemFacade;
+import org.opendaylight.controller.config.facade.xml.RpcFacade;
+import org.opendaylight.controller.config.facade.xml.rpc.InstanceRuntimeRpc;
+import org.opendaylight.controller.config.facade.xml.rpc.ModuleRpcs;
+import org.opendaylight.controller.config.facade.xml.rpc.Rpcs;
+import org.opendaylight.controller.config.facade.xml.rpc.RuntimeRpcElementResolved;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.config.util.xml.XmlElement;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.mapping.AttributeMappingStrategy;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.mapping.ObjectMapper;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.toxml.ObjectXmlWriter;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.rpc.InstanceRuntimeRpc;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.rpc.ModuleRpcs;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.rpc.Rpcs;
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.AbstractConfigNetconfOperation;
-import org.opendaylight.controller.netconf.confignetconfconnector.osgi.EnumResolver;
-import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreContext;
 import org.opendaylight.controller.netconf.mapping.api.HandlingPriority;
-import org.opendaylight.controller.netconf.util.exception.MissingNameSpaceException;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
@@ -44,83 +30,14 @@ import org.w3c.dom.Element;
 public class RuntimeRpc extends AbstractConfigNetconfOperation {
 
     private static final Logger LOG = LoggerFactory.getLogger(RuntimeRpc.class);
-    public static final String CONTEXT_INSTANCE = "context-instance";
 
-    private final YangStoreContext yangStoreSnapshot;
-
-    public RuntimeRpc(final YangStoreContext yangStoreSnapshot, ConfigRegistryClient configRegistryClient,
-            String netconfSessionIdForReporting) {
-        super(configRegistryClient, netconfSessionIdForReporting);
-        this.yangStoreSnapshot = yangStoreSnapshot;
-    }
-
-    private Element toXml(Document doc, Object result, AttributeIfc returnType, String namespace, String elementName) throws NetconfDocumentedException {
-        AttributeMappingStrategy<?, ? extends OpenType<?>> mappingStrategy = new ObjectMapper().prepareStrategy(returnType);
-        Optional<?> mappedAttributeOpt = mappingStrategy.mapAttribute(result);
-        Preconditions.checkState(mappedAttributeOpt.isPresent(), "Unable to map return value %s as %s", result, returnType.getOpenType());
-
-        // FIXME: multiple return values defined as leaf-list and list in yang should not be wrapped in output xml element,
-        // they need to be appended directly under rpc-reply element
-        //
-        // Either allow List of Elements to be returned from NetconfOperation or
-        // pass reference to parent output xml element for netconf operations to
-        // append result(s) on their own
-        Element tempParent = XmlUtil.createElement(doc, "output", Optional.of(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0));
-        new ObjectXmlWriter().prepareWritingStrategy(elementName, returnType, doc).writeElement(tempParent, namespace, mappedAttributeOpt.get());
-
-        XmlElement xmlElement = XmlElement.fromDomElement(tempParent);
-        return xmlElement.getChildElements().size() > 1 ? tempParent : xmlElement.getOnlyChildElement().getDomElement();
+    public RuntimeRpc(final ConfigSubsystemFacade configSubsystemFacade, final String netconfSessionIdForReporting) {
+        super(configSubsystemFacade, netconfSessionIdForReporting);
     }
 
-    private Object executeOperation(final ConfigRegistryClient configRegistryClient, final ObjectName on,
-            final String name, final Map<String, AttributeConfigElement> attributes) {
-        final Object[] params = new Object[attributes.size()];
-        final String[] signature = new String[attributes.size()];
-
-        int i = 0;
-        for (final AttributeConfigElement attribute : attributes.values()) {
-            final Optional<?> resolvedValueOpt = attribute.getResolvedValue();
-
-            params[i] = resolvedValueOpt.isPresent() ? resolvedValueOpt.get() : attribute.getResolvedDefaultValue();
-            signature[i] = resolvedValueOpt.isPresent() ? resolvedValueOpt.get().getClass().getName() : attribute
-                    .getResolvedDefaultValue().getClass().getName();
-            i++;
-        }
-
-        return configRegistryClient.invokeMethod(on, name, params, signature);
-    }
-
-    public NetconfOperationExecution fromXml(final XmlElement xml) throws NetconfDocumentedException {
-        final String namespace;
-        try {
-            namespace = xml.getNamespace();
-        } catch (MissingNameSpaceException e) {
-            LOG.trace("Can't get namespace from xml element due to ",e);
-            throw NetconfDocumentedException.wrap(e);
-        }
-        final XmlElement contextInstanceElement = xml.getOnlyChildElement(CONTEXT_INSTANCE);
-        final String operationName = xml.getName();
-
-        final RuntimeRpcElementResolved id = RuntimeRpcElementResolved.fromXpath(
-                contextInstanceElement.getTextContent(), operationName, namespace);
-
-        final Rpcs rpcs = mapRpcs(yangStoreSnapshot.getModuleMXBeanEntryMap(), yangStoreSnapshot.getEnumResolver());
-
-        final ModuleRpcs rpcMapping = rpcs.getRpcMapping(id);
-        final InstanceRuntimeRpc instanceRuntimeRpc = rpcMapping.getRpc(id.getRuntimeBeanName(), operationName);
-
-        // TODO move to Rpcs after xpath attribute is redesigned
-
-        final ObjectName on = id.getObjectName(rpcMapping);
-        Map<String, AttributeConfigElement> attributes = instanceRuntimeRpc.fromXml(xml);
-        attributes = sortAttributes(attributes, xml);
-
-        return new NetconfOperationExecution(on, instanceRuntimeRpc.getName(), attributes,
-                instanceRuntimeRpc.getReturnType(), namespace);
-    }
 
     @Override
-    public HandlingPriority canHandle(Document message) throws NetconfDocumentedException {
+    public HandlingPriority canHandle(Document message) throws DocumentedException {
         XmlElement requestElement = null;
         requestElement = getRequestElementWithCheck(message);
 
@@ -129,13 +46,13 @@ public class RuntimeRpc extends AbstractConfigNetconfOperation {
         final String netconfOperationNamespace;
         try {
             netconfOperationNamespace = operationElement.getNamespace();
-        } catch (MissingNameSpaceException e) {
+        } catch (DocumentedException e) {
             LOG.debug("Cannot retrieve netconf operation namespace from message due to ", e);
             return HandlingPriority.CANNOT_HANDLE;
         }
 
         final Optional<XmlElement> contextInstanceElement = operationElement
-                .getOnlyChildElementOptionally(CONTEXT_INSTANCE);
+                .getOnlyChildElementOptionally(RpcFacade.CONTEXT_INSTANCE);
 
         if (!contextInstanceElement.isPresent()){
             return HandlingPriority.CANNOT_HANDLE;
@@ -145,16 +62,14 @@ public class RuntimeRpc extends AbstractConfigNetconfOperation {
                 .getTextContent(), netconfOperationName, netconfOperationNamespace);
 
         // TODO reuse rpcs instance in fromXml method
-        final Rpcs rpcs = mapRpcs(yangStoreSnapshot.getModuleMXBeanEntryMap(), yangStoreSnapshot.getEnumResolver());
+        final Rpcs rpcs = getConfigSubsystemFacade().getRpcFacade().mapRpcs();
 
         try {
-
             final ModuleRpcs rpcMapping = rpcs.getRpcMapping(id);
             final InstanceRuntimeRpc instanceRuntimeRpc = rpcMapping.getRpc(id.getRuntimeBeanName(),
                     netconfOperationName);
             Preconditions.checkState(instanceRuntimeRpc != null, "No rpc found for %s:%s", netconfOperationNamespace,
                     netconfOperationName);
-
         } catch (IllegalStateException e) {
             LOG.debug("Cannot handle runtime operation {}:{}", netconfOperationNamespace, netconfOperationName, e);
             return HandlingPriority.CANNOT_HANDLE;
@@ -175,103 +90,22 @@ public class RuntimeRpc extends AbstractConfigNetconfOperation {
     }
 
     @Override
-    protected Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws NetconfDocumentedException {
+    protected Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws DocumentedException {
         // TODO check for namespaces and unknown elements
-        final NetconfOperationExecution execution = fromXml(xml);
+        final RpcFacade.OperationExecution execution = getConfigSubsystemFacade().getRpcFacade().fromXml(xml);
 
-        LOG.debug("Invoking operation {} on {} with arguments {}", execution.operationName, execution.on,
-                execution.attributes);
-        final Object result = executeOperation(getConfigRegistryClient(), execution.on, execution.operationName,
-                execution.attributes);
+        LOG.debug("Invoking operation {} on {} with arguments {}", execution.getOperationName(), execution.getOn(),
+                execution.getAttributes());
+        final Object result = getConfigSubsystemFacade().getRpcFacade().executeOperation(execution);
 
-        LOG.trace("Operation {} called successfully on {} with arguments {} with result {}", execution.operationName,
-                execution.on, execution.attributes, result);
+        LOG.trace("Operation {} called successfully on {} with arguments {} with result {}", execution.getOperationName(),
+                execution.getOn(), execution.getAttributes(), result);
 
         if (execution.isVoid()) {
             return XmlUtil.createElement(document, XmlNetconfConstants.OK, Optional.<String>absent());
         } else {
-            return toXml(document, result, execution.returnType, execution.namespace,
-                    execution.returnType.getAttributeYangName());
-        }
-    }
-
-    private static class NetconfOperationExecution {
-
-        private final ObjectName on;
-        private final String operationName;
-        private final Map<String, AttributeConfigElement> attributes;
-        private final AttributeIfc returnType;
-        private final String namespace;
-
-        public NetconfOperationExecution(final ObjectName on, final String name,
-                final Map<String, AttributeConfigElement> attributes, final AttributeIfc returnType, final String namespace) {
-            this.on = on;
-            this.operationName = name;
-            this.attributes = attributes;
-            this.returnType = returnType;
-            this.namespace = namespace;
-        }
-
-        boolean isVoid() {
-            return returnType == VoidAttribute.getInstance();
+            return getConfigSubsystemFacade().getRpcFacade().toXml(document, result, execution);
         }
-
-    }
-
-    private static Map<String, AttributeConfigElement> sortAttributes(
-            final Map<String, AttributeConfigElement> attributes, final XmlElement xml) {
-        final Map<String, AttributeConfigElement> sorted = Maps.newLinkedHashMap();
-
-        for (XmlElement xmlElement : xml.getChildElements()) {
-            final String name = xmlElement.getName();
-            if (!CONTEXT_INSTANCE.equals(name)) { // skip context
-                                                          // instance child node
-                                                          // because it
-                                                          // specifies
-                // ObjectName
-                final AttributeConfigElement value = attributes.get(name);
-                if (value == null) {
-                    throw new IllegalArgumentException("Cannot find yang mapping for node " + xmlElement);
-                }
-                sorted.put(name, value);
-            }
-        }
-
-        return sorted;
-    }
-
-    private static Rpcs mapRpcs(final Map<String, Map<String, ModuleMXBeanEntry>> mBeanEntries, final EnumResolver enumResolver) {
-
-        final Map<String, Map<String, ModuleRpcs>> map = Maps.newHashMap();
-
-        for (final Map.Entry<String, Map<String, ModuleMXBeanEntry>> namespaceToModuleEntry : mBeanEntries.entrySet()) {
-
-            Map<String, ModuleRpcs> namespaceToModules = map.get(namespaceToModuleEntry.getKey());
-            if (namespaceToModules == null) {
-                namespaceToModules = Maps.newHashMap();
-                map.put(namespaceToModuleEntry.getKey(), namespaceToModules);
-            }
-
-            for (final Map.Entry<String, ModuleMXBeanEntry> moduleEntry : namespaceToModuleEntry.getValue().entrySet()) {
-
-                ModuleRpcs rpcMapping = namespaceToModules.get(moduleEntry.getKey());
-                if (rpcMapping == null) {
-                    rpcMapping = new ModuleRpcs(enumResolver);
-                    namespaceToModules.put(moduleEntry.getKey(), rpcMapping);
-                }
-
-                final ModuleMXBeanEntry entry = moduleEntry.getValue();
-
-                for (final RuntimeBeanEntry runtimeEntry : entry.getRuntimeBeans()) {
-                    rpcMapping.addNameMapping(runtimeEntry);
-                    for (final Rpc rpc : runtimeEntry.getRpcs()) {
-                        rpcMapping.addRpc(runtimeEntry, rpc);
-                    }
-                }
-            }
-        }
-
-        return new Rpcs(map);
     }
 
 }
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpcElementResolved.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpcElementResolved.java
deleted file mode 100644 (file)
index 4bf469d..0000000
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.operations.runtimerpc;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Strings;
-import com.google.common.collect.Maps;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import javax.management.ObjectName;
-import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.rpc.ModuleRpcs;
-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;
-
-/**
- * Represents parsed xpath to runtime bean instance
- */
-public final class RuntimeRpcElementResolved {
-    private final String moduleName;
-    private final String instanceName;
-    private final String namespace;
-    private final String runtimeBeanName;
-    private final Map<String, String> additionalAttributes;
-
-    private RuntimeRpcElementResolved(String namespace, String moduleName, String instanceName, String runtimeBeanName,
-            Map<String, String> additionalAttributes) {
-        this.moduleName = Preconditions.checkNotNull(moduleName, "Module name");
-        this.instanceName =  Preconditions.checkNotNull(instanceName, "Instance name");
-        this.additionalAttributes = additionalAttributes;
-        this.namespace = Preconditions.checkNotNull(namespace, "Namespace");
-        this.runtimeBeanName = Preconditions.checkNotNull(runtimeBeanName, "Runtime bean name");
-    }
-
-    public String getModuleName() {
-        return moduleName;
-    }
-
-    @VisibleForTesting
-    Map<String, String> getAdditionalAttributes() {
-        return additionalAttributes;
-    }
-
-    public String getInstanceName() {
-        return instanceName;
-    }
-
-    public String getNamespace() {
-        return namespace;
-    }
-
-    public String getRuntimeBeanName() {
-        return runtimeBeanName;
-    }
-
-    public ObjectName getObjectName(ModuleRpcs rpcMapping) {
-        Map<String, String> additionalAttributesJavaNames = Maps
-                .newHashMapWithExpectedSize(additionalAttributes.size());
-        for (String attributeYangName : additionalAttributes.keySet()) {
-            String attributeJavaName = rpcMapping.getRbeJavaName(attributeYangName);
-            Preconditions.checkState(attributeJavaName != null,
-                    "Cannot find java name for runtime bean wtih yang name %s", attributeYangName);
-            additionalAttributesJavaNames.put(attributeJavaName, additionalAttributes.get(attributeYangName));
-        }
-        return ObjectNameUtil.createRuntimeBeanName(moduleName, instanceName, additionalAttributesJavaNames);
-    }
-
-    /**
-     * Pattern for an absolute instance identifier xpath pointing to a runtime bean instance e.g:
-     * <pre>
-     * /modules/module[name=instanceName][type=moduleType]
-     * </pre>
-     * or
-     * <pre>
-     * /a:modules/a:module[a:name=instanceName][a:type=moduleType]
-     * </pre>
-     */
-    private static final String xpathPatternBlueprint =
-            "/" + getRegExForPrefixedName(Modules.QNAME.getLocalName())+ "/" + getRegExForPrefixedName(Module.QNAME.getLocalName())
-
-                    + "\\["
-                    + "(?<key1>" + getRegExForPrefixedName(XmlNetconfConstants.TYPE_KEY) + "|" + getRegExForPrefixedName(XmlNetconfConstants.NAME_KEY) + ")"
-                    + "=('|\")?(?<value1>[^'\"\\]]+)('|\")?"
-                    + "( and |\\]\\[)"
-                    + "(?<key2>" + getRegExForPrefixedName(XmlNetconfConstants.TYPE_KEY) + "|" + getRegExForPrefixedName(XmlNetconfConstants.NAME_KEY) + ")"
-                    + "=('|\")?(?<value2>[^'\"\\]]+)('|\")?"
-                    + "\\]"
-
-                    + "(?<additional>.*)";
-
-    /**
-     * Return reg ex that matches either the name with or without a prefix
-     */
-    private static String getRegExForPrefixedName(final String name) {
-        return "([^:]+:)?" + name;
-    }
-
-    private static final Pattern xpathPattern = Pattern.compile(xpathPatternBlueprint);
-
-    /**
-     * Pattern for additional path elements inside xpath for instance identifier pointing to an inner runtime bean e.g:
-     * <pre>
-     * /modules/module[name=instanceName and type=moduleType]/inner[key=b]
-     * </pre>
-     */
-    private static final String additionalPatternBlueprint = getRegExForPrefixedName("(?<additionalKey>.+)") + "\\[(?<prefixedKey>" + getRegExForPrefixedName("(.+)") + ")=('|\")?(?<additionalValue>[^'\"\\]]+)('|\")?\\]";
-    private static final Pattern additionalPattern = Pattern.compile(additionalPatternBlueprint);
-
-    public static RuntimeRpcElementResolved fromXpath(String xpath, String elementName, String namespace) {
-        Matcher matcher = xpathPattern.matcher(xpath);
-        Preconditions.checkState(matcher.matches(),
-                "Node %s with value '%s' not in required form on rpc element %s, required format is %s",
-                RuntimeRpc.CONTEXT_INSTANCE, xpath, elementName, xpathPatternBlueprint);
-
-        PatternGroupResolver groups = new PatternGroupResolver(matcher.group("key1"), matcher.group("value1"),
-                matcher.group("value2"), matcher.group("additional"));
-
-        String moduleName = groups.getModuleName();
-        String instanceName = groups.getInstanceName();
-
-        Map<String, String> additionalAttributes = groups.getAdditionalKeys(elementName, moduleName);
-
-        return new RuntimeRpcElementResolved(namespace, moduleName, instanceName, groups.getRuntimeBeanYangName(),
-                additionalAttributes);
-    }
-
-    private static final class PatternGroupResolver {
-
-        private final String key1, value1, value2;
-        private final String additional;
-        private String runtimeBeanYangName;
-
-        PatternGroupResolver(String key1, String value1,  String value2, String additional) {
-            this.key1 = Preconditions.checkNotNull(key1);
-            this.value1 = Preconditions.checkNotNull(value1);
-            this.value2 = Preconditions.checkNotNull(value2);
-            this.additional = Preconditions.checkNotNull(additional);
-        }
-
-        String getModuleName() {
-            return key1.contains(XmlNetconfConstants.TYPE_KEY) ? value1 : value2;
-        }
-
-        String getInstanceName() {
-            return key1.contains(XmlNetconfConstants.NAME_KEY) ? value1 : value2;
-        }
-
-
-        Map<String, String> getAdditionalKeys(String elementName, String moduleName) {
-            HashMap<String, String> additionalAttributes = Maps.newHashMap();
-
-            runtimeBeanYangName = moduleName;
-            for (String additionalKeyValue : additional.split("/")) {
-                if (Strings.isNullOrEmpty(additionalKeyValue)){
-                    continue;
-                }
-                Matcher matcher = additionalPattern.matcher(additionalKeyValue);
-                Preconditions
-                        .checkState(
-                                matcher.matches(),
-                                "Attribute %s not in required form on rpc element %s, required format for additional attributes is: %s",
-                                additionalKeyValue, elementName, additionalPatternBlueprint);
-                String name = matcher.group("additionalKey");
-                runtimeBeanYangName = name;
-                additionalAttributes.put(name, matcher.group("additionalValue"));
-            }
-            return additionalAttributes;
-        }
-
-        private String getRuntimeBeanYangName() {
-            Preconditions.checkState(runtimeBeanYangName!=null);
-            return runtimeBeanYangName;
-        }
-    }
-}
index 6f082b7ab186576c78c23b7e5c1c63df81d56b14..5d01b8decddf5884654a2e1a7e35c4e81390e4a8 100644 (file)
@@ -8,14 +8,11 @@
 
 package org.opendaylight.controller.netconf.confignetconfconnector.osgi;
 
-import static com.google.common.base.Preconditions.checkState;
-
 import java.util.Dictionary;
 import java.util.Hashtable;
+import org.opendaylight.controller.config.facade.xml.ConfigSubsystemFacadeFactory;
 import org.opendaylight.controller.netconf.api.util.NetconfConstants;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactory;
-import org.opendaylight.yangtools.sal.binding.generator.util.BindingRuntimeContext;
-import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider;
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
@@ -29,74 +26,50 @@ public class Activator implements BundleActivator {
 
     private static final Logger LOG = LoggerFactory.getLogger(Activator.class);
 
-    private BundleContext context;
     private ServiceRegistration<?> osgiRegistration;
-    private ConfigRegistryLookupThread configRegistryLookup = null;
 
     @Override
     public void start(final BundleContext context) throws Exception {
-        this.context = context;
+        ServiceTrackerCustomizer<ConfigSubsystemFacadeFactory, ConfigSubsystemFacadeFactory> schemaServiceTrackerCustomizer = new ServiceTrackerCustomizer<ConfigSubsystemFacadeFactory, ConfigSubsystemFacadeFactory>() {
 
-        ServiceTrackerCustomizer<SchemaContextProvider, ConfigRegistryLookupThread> customizer = new ServiceTrackerCustomizer<SchemaContextProvider, ConfigRegistryLookupThread>() {
             @Override
-            public ConfigRegistryLookupThread addingService(ServiceReference<SchemaContextProvider> reference) {
-                LOG.debug("Got addingService(SchemaContextProvider) event, starting ConfigRegistryLookupThread");
-                checkState(configRegistryLookup == null, "More than one onYangStoreAdded received");
-
-                SchemaContextProvider schemaContextProvider = reference.getBundle().getBundleContext().getService(reference);
-
-                YangStoreService yangStoreService = new YangStoreService(schemaContextProvider, context);
-                configRegistryLookup = new ConfigRegistryLookupThread(yangStoreService);
-                configRegistryLookup.start();
-                return configRegistryLookup;
+            public ConfigSubsystemFacadeFactory addingService(ServiceReference<ConfigSubsystemFacadeFactory> reference) {
+                LOG.debug("Got addingService(SchemaContextProvider) event");
+                // Yang store service should not be registered multiple times
+                ConfigSubsystemFacadeFactory configSubsystemFacade = reference.getBundle().getBundleContext().getService(reference);
+                osgiRegistration = startNetconfServiceFactory(configSubsystemFacade, context);
+                return configSubsystemFacade;
             }
 
             @Override
-            public void modifiedService(ServiceReference<SchemaContextProvider> reference, ConfigRegistryLookupThread configRegistryLookup) {
-                LOG.debug("Got modifiedService(SchemaContextProvider) event");
-                final BindingRuntimeContext runtimeContext = (BindingRuntimeContext) reference.getProperty(BindingRuntimeContext.class.getName());
-                LOG.debug("BindingRuntimeContext retrieved as {}", runtimeContext);
-                configRegistryLookup.yangStoreService.refresh(runtimeContext);
-
+            public void modifiedService(ServiceReference<ConfigSubsystemFacadeFactory> reference, ConfigSubsystemFacadeFactory service) {
+                LOG.warn("Config manager facade was modified unexpectedly");
             }
 
             @Override
-            public void removedService(ServiceReference<SchemaContextProvider> reference, ConfigRegistryLookupThread configRegistryLookup) {
-                configRegistryLookup.interrupt();
-                if (osgiRegistration != null) {
-                    osgiRegistration.unregister();
-                }
-                osgiRegistration = null;
-                Activator.this.configRegistryLookup = null;
+            public void removedService(ServiceReference<ConfigSubsystemFacadeFactory> reference, ConfigSubsystemFacadeFactory service) {
+                LOG.warn("Config manager facade was removed unexpectedly");
             }
         };
 
-        ServiceTracker<SchemaContextProvider, ConfigRegistryLookupThread> listenerTracker = new ServiceTracker<>(context, SchemaContextProvider.class, customizer);
-        listenerTracker.open();
+        ServiceTracker<ConfigSubsystemFacadeFactory, ConfigSubsystemFacadeFactory> schemaContextProviderServiceTracker =
+                new ServiceTracker<>(context, ConfigSubsystemFacadeFactory.class, schemaServiceTrackerCustomizer);
+        schemaContextProviderServiceTracker.open();
     }
 
     @Override
-    public void stop(BundleContext context) {
-        if (configRegistryLookup != null) {
-            configRegistryLookup.interrupt();
+    public void stop(final BundleContext bundleContext) throws Exception {
+        if (osgiRegistration != null) {
+            osgiRegistration.unregister();
         }
     }
 
-    private class ConfigRegistryLookupThread extends Thread {
-        private final YangStoreService yangStoreService;
-
-        private ConfigRegistryLookupThread(YangStoreService yangStoreService) {
-            super("config-registry-lookup");
-            this.yangStoreService = yangStoreService;
-        }
-
-        @Override
-        public void run() {
-            NetconfOperationServiceFactoryImpl factory = new NetconfOperationServiceFactoryImpl(yangStoreService);
-            LOG.debug("Registering into OSGi");
-            Dictionary<String, String> properties = new Hashtable<>();
-            properties.put(NetconfConstants.SERVICE_NAME, NetconfConstants.CONFIG_NETCONF_CONNECTOR);
-            osgiRegistration = context.registerService(NetconfOperationServiceFactory.class, factory, properties);
-        }
+    private ServiceRegistration<NetconfOperationServiceFactory> startNetconfServiceFactory(final ConfigSubsystemFacadeFactory configSubsystemFacade, final BundleContext context) {
+        final NetconfOperationServiceFactoryImpl netconfOperationServiceFactory = new NetconfOperationServiceFactoryImpl(configSubsystemFacade);
+        // Add properties to autowire with netconf-impl instance for cfg subsystem
+        final Dictionary<String, String> properties = new Hashtable<>();
+        properties.put(NetconfConstants.SERVICE_NAME, NetconfConstants.CONFIG_NETCONF_CONNECTOR);
+        return context.registerService(NetconfOperationServiceFactory.class, netconfOperationServiceFactory, properties);
     }
+
 }
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/EnumResolver.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/EnumResolver.java
deleted file mode 100644 (file)
index 7efdf5f..0000000
+++ /dev/null
@@ -1,16 +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.netconf.confignetconfconnector.osgi;
-
-public interface EnumResolver {
-
-    String fromYang(String enumType, String enumYangValue);
-
-    String toYang(String enumType, String enumJavaValue);
-}
index e3fdc056d9d77d482adfe53aa513618ba720566e..b0a62a04dc19a7a442d1610bf38b40fc6caa4a43 100644 (file)
@@ -11,7 +11,7 @@ package org.opendaylight.controller.netconf.confignetconfconnector.osgi;
 import com.google.common.base.Optional;
 import com.google.common.collect.Sets;
 import java.util.Set;
-import org.opendaylight.controller.config.util.ConfigRegistryClient;
+import org.opendaylight.controller.config.facade.xml.ConfigSubsystemFacade;
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.Commit;
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.DiscardChanges;
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.Lock;
@@ -21,41 +21,35 @@ import org.opendaylight.controller.netconf.confignetconfconnector.operations.edi
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.get.Get;
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.getconfig.GetConfig;
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.runtimerpc.RuntimeRpc;
-import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperation;
 
 final class NetconfOperationProvider {
     private final Set<NetconfOperation> operations;
 
-    NetconfOperationProvider(YangStoreContext yangStoreSnapshot, ConfigRegistryClient configRegistryClient,
-            TransactionProvider transactionProvider, String netconfSessionIdForReporting) {
+    NetconfOperationProvider(final ConfigSubsystemFacade configSubsystemFacade, final String netconfSessionIdForReporting) {
 
-        operations = setUpOperations(yangStoreSnapshot, configRegistryClient, transactionProvider,
-                netconfSessionIdForReporting);
+        operations = setUpOperations(configSubsystemFacade, netconfSessionIdForReporting);
     }
 
     Set<NetconfOperation> getOperations() {
         return operations;
     }
 
-    private static Set<NetconfOperation> setUpOperations(YangStoreContext yangStoreSnapshot,
-            ConfigRegistryClient configRegistryClient, TransactionProvider transactionProvider,
+    private static Set<NetconfOperation> setUpOperations(final ConfigSubsystemFacade configSubsystemFacade,
             String netconfSessionIdForReporting) {
         Set<NetconfOperation> ops = Sets.newHashSet();
 
-        GetConfig getConfigOp = new GetConfig(yangStoreSnapshot, Optional.<String> absent(), transactionProvider,
-                configRegistryClient, netconfSessionIdForReporting);
+        GetConfig getConfigOp = new GetConfig(configSubsystemFacade, Optional.<String> absent(), netconfSessionIdForReporting);
 
         ops.add(getConfigOp);
-        ops.add(new EditConfig(yangStoreSnapshot, transactionProvider, configRegistryClient,
-                netconfSessionIdForReporting));
-        ops.add(new Commit(transactionProvider, configRegistryClient, netconfSessionIdForReporting));
+        ops.add(new EditConfig(configSubsystemFacade, netconfSessionIdForReporting));
+        ops.add(new Commit(configSubsystemFacade, netconfSessionIdForReporting));
         ops.add(new Lock(netconfSessionIdForReporting));
         ops.add(new UnLock(netconfSessionIdForReporting));
-        ops.add(new Get(transactionProvider, yangStoreSnapshot, configRegistryClient, netconfSessionIdForReporting));
-        ops.add(new DiscardChanges(transactionProvider, configRegistryClient, netconfSessionIdForReporting));
-        ops.add(new Validate(transactionProvider, configRegistryClient, netconfSessionIdForReporting));
-        ops.add(new RuntimeRpc(yangStoreSnapshot, configRegistryClient, netconfSessionIdForReporting));
+        ops.add(new Get(configSubsystemFacade, netconfSessionIdForReporting));
+        ops.add(new DiscardChanges(configSubsystemFacade, netconfSessionIdForReporting));
+        ops.add(new Validate(configSubsystemFacade, netconfSessionIdForReporting));
+        ops.add(new RuntimeRpc(configSubsystemFacade, netconfSessionIdForReporting));
 
         return ops;
     }
index cb9c956b90c8e10bba8283bd75eabe979cb9d068..6ea628d0190e8a531166c823efa4eff8bf6e5173 100644 (file)
 
 package org.opendaylight.controller.netconf.confignetconfconnector.osgi;
 
-import java.lang.management.ManagementFactory;
-import java.util.HashSet;
+import com.google.common.base.Function;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.Sets;
 import java.util.Set;
-import javax.management.MBeanServer;
-import org.opendaylight.controller.config.util.ConfigRegistryJMXClient;
-import org.opendaylight.controller.netconf.api.Capability;
+import org.opendaylight.controller.config.facade.xml.ConfigSubsystemFacadeFactory;
+import org.opendaylight.controller.config.util.capability.Capability;
+import org.opendaylight.controller.config.util.capability.ModuleListener;
+import org.opendaylight.controller.config.util.capability.YangModuleCapability;
 import org.opendaylight.controller.netconf.api.monitoring.CapabilityListener;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactory;
-import org.opendaylight.controller.netconf.util.capability.BasicCapability;
-import org.opendaylight.controller.netconf.util.capability.YangModuleCapability;
 import org.opendaylight.yangtools.yang.model.api.Module;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 public class NetconfOperationServiceFactoryImpl implements NetconfOperationServiceFactory {
 
-    public static final int ATTEMPT_TIMEOUT_MS = 1000;
-    private static final int SILENT_ATTEMPTS = 30;
+    private final ConfigSubsystemFacadeFactory configFacadeFactory;
 
-    private final YangStoreService yangStoreService;
-    private final ConfigRegistryJMXClient jmxClient;
-
-    private static final Logger LOG = LoggerFactory.getLogger(NetconfOperationServiceFactoryImpl.class);
-
-    public NetconfOperationServiceFactoryImpl(YangStoreService yangStoreService) {
-        this(yangStoreService, ManagementFactory.getPlatformMBeanServer());
-    }
-
-    public NetconfOperationServiceFactoryImpl(YangStoreService yangStoreService, MBeanServer mBeanServer) {
-        this.yangStoreService = yangStoreService;
-
-        ConfigRegistryJMXClient configRegistryJMXClient;
-        int i = 0;
-        // Config registry might not be present yet, but will be eventually
-        while(true) {
-
-            try {
-                configRegistryJMXClient = new ConfigRegistryJMXClient(mBeanServer);
-                break;
-            } catch (IllegalStateException e) {
-                ++i;
-                if (i > SILENT_ATTEMPTS) {
-                    LOG.info("JMX client not created after {} attempts, still trying", i, e);
-                } else {
-                    LOG.debug("JMX client could not be created, reattempting, try {}", i, e);
-                }
-                try {
-                    Thread.sleep(ATTEMPT_TIMEOUT_MS);
-                } catch (InterruptedException e1) {
-                    Thread.currentThread().interrupt();
-                    throw new IllegalStateException("Interrupted while reattempting connection", e1);
-                }
-            }
-        }
-
-        jmxClient = configRegistryJMXClient;
-        if (i > SILENT_ATTEMPTS) {
-            LOG.info("Created JMX client after {} attempts", i);
-        } else {
-            LOG.debug("Created JMX client after {} attempts", i);
-        }
+    public NetconfOperationServiceFactoryImpl(ConfigSubsystemFacadeFactory configFacadeFactory) {
+        this.configFacadeFactory = configFacadeFactory;
     }
 
     @Override
     public NetconfOperationServiceImpl createService(String netconfSessionIdForReporting) {
-        return new NetconfOperationServiceImpl(yangStoreService, jmxClient, netconfSessionIdForReporting);
+        return new NetconfOperationServiceImpl(configFacadeFactory.createFacade(netconfSessionIdForReporting), netconfSessionIdForReporting);
     }
 
-
     @Override
     public Set<Capability> getCapabilities() {
-        return setupCapabilities(yangStoreService);
+        return configFacadeFactory.getCurrentCapabilities();
     }
 
     @Override
     public AutoCloseable registerCapabilityListener(final CapabilityListener listener) {
-        return yangStoreService.registerCapabilityListener(listener);
+        return configFacadeFactory.getYangStoreService().registerModuleListener(new ModuleListener() {
+            @Override
+            public void onCapabilitiesChanged(Set<Module> added, Set<Module> removed) {
+                listener.onCapabilitiesChanged(
+                        transformModulesToCapabilities(added), transformModulesToCapabilities(removed));
+            }
+        });
     }
 
-    public static Set<Capability> setupCapabilities(final YangStoreContext yangStoreSnapshot) {
-        Set<Capability> capabilities = new HashSet<>();
-        // [RFC6241] 8.3.  Candidate Configuration Capability
-        capabilities.add(new BasicCapability("urn:ietf:params:netconf:capability:candidate:1.0"));
-
-        // TODO rollback on error not supported EditConfigXmlParser:100
-        // [RFC6241] 8.5.  Rollback-on-Error Capability
-        // capabilities.add(new BasicCapability("urn:ietf:params:netconf:capability:rollback-on-error:1.0"));
-
-        Set<Module> modules = yangStoreSnapshot.getModules();
-        for (Module module : modules) {
-            capabilities.add(new YangModuleCapability(module, yangStoreSnapshot.getModuleSource(module)));
+    private static final Function<Module, Capability> MODULE_TO_CAPABILITY = new Function<Module, Capability>() {
+        @Override
+        public Capability apply(final Module module) {
+            return new YangModuleCapability(module, module.getSource());
         }
+    };
 
-        return capabilities;
+    public static Set<Capability> transformModulesToCapabilities(Set<Module> modules) {
+        return Sets.newHashSet(Collections2.transform(modules, MODULE_TO_CAPABILITY));
     }
 
 }
index 28001851ccf2695b0d9ed69c98a6871e6e0ba7f4..17cbbcace0b01d6af46684cbfa448634c246bb9f 100644 (file)
@@ -9,25 +9,19 @@
 package org.opendaylight.controller.netconf.confignetconfconnector.osgi;
 
 import java.util.Set;
-import org.opendaylight.controller.config.util.ConfigRegistryJMXClient;
-import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider;
+import org.opendaylight.controller.config.facade.xml.ConfigSubsystemFacade;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperation;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService;
 
-/**
- * Manages life cycle of {@link YangStoreContext}.
- */
 public class NetconfOperationServiceImpl implements NetconfOperationService {
 
     private final NetconfOperationProvider operationProvider;
-    private final TransactionProvider transactionProvider;
+    private ConfigSubsystemFacade configSubsystemFacade;
 
-    public NetconfOperationServiceImpl(final YangStoreService yangStoreService, final ConfigRegistryJMXClient jmxClient,
+    public NetconfOperationServiceImpl(final ConfigSubsystemFacade configSubsystemFacade,
             final String netconfSessionIdForReporting) {
-
-        transactionProvider = new TransactionProvider(jmxClient, netconfSessionIdForReporting);
-        operationProvider = new NetconfOperationProvider(yangStoreService, jmxClient, transactionProvider,
-                netconfSessionIdForReporting);
+        this.configSubsystemFacade = configSubsystemFacade;
+        operationProvider = new NetconfOperationProvider(configSubsystemFacade, netconfSessionIdForReporting);
     }
 
     @Override
@@ -37,7 +31,7 @@ public class NetconfOperationServiceImpl implements NetconfOperationService {
 
     @Override
     public void close() {
-        transactionProvider.close();
+        configSubsystemFacade.close();
     }
 
 }
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/YangStoreContext.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/YangStoreContext.java
deleted file mode 100644 (file)
index 290912a..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.confignetconfconnector.osgi;
-
-import java.util.Map;
-import java.util.Set;
-import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier;
-
-public interface YangStoreContext {
-
-    /**
-     * @deprecated Use {@link #getQNamesToIdentitiesToModuleMXBeanEntries()} instead. This method return only one
-     * module representation even if multiple revisions are available.
-     */
-    @Deprecated
-    Map<String/* Namespace from yang file */,
-            Map<String /* Name of module entry from yang file */, ModuleMXBeanEntry>> getModuleMXBeanEntryMap();
-
-
-    Map<QName, Map<String /* identity local name */, ModuleMXBeanEntry>> getQNamesToIdentitiesToModuleMXBeanEntries();
-
-    /**
-     * Get all modules discovered when this snapshot was created.
-     * @return all modules discovered. If one module exists with two different revisions, return both.
-     */
-    Set<Module> getModules();
-
-    String getModuleSource(ModuleIdentifier moduleIdentifier);
-
-    EnumResolver getEnumResolver();
-
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/YangStoreService.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/YangStoreService.java
deleted file mode 100644 (file)
index ad771f9..0000000
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.osgi;
-
-import com.google.common.base.Function;
-import com.google.common.collect.Collections2;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-import java.lang.ref.SoftReference;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.atomic.AtomicReference;
-import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
-import org.opendaylight.controller.netconf.api.Capability;
-import org.opendaylight.controller.netconf.api.monitoring.CapabilityListener;
-import org.opendaylight.controller.netconf.notifications.BaseNetconfNotificationListener;
-import org.opendaylight.controller.netconf.notifications.BaseNotificationPublisherRegistration;
-import org.opendaylight.controller.netconf.notifications.NetconfNotificationCollector;
-import org.opendaylight.controller.netconf.util.capability.YangModuleCapability;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfCapabilityChange;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfCapabilityChangeBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.changed.by.parms.ChangedByBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.changed.by.parms.changed.by.server.or.user.ServerBuilder;
-import org.opendaylight.yangtools.sal.binding.generator.util.BindingRuntimeContext;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier;
-import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
-import org.osgi.util.tracker.ServiceTracker;
-import org.osgi.util.tracker.ServiceTrackerCustomizer;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class YangStoreService implements YangStoreContext {
-
-    private static final Logger LOG = LoggerFactory.getLogger(YangStoreService.class);
-
-    /**
-     * This is a rather interesting locking model. We need to guard against both the
-     * cache expiring from GC and being invalidated by schema context change. The
-     * context can change while we are doing processing, so we do not want to block
-     * it, so no synchronization can happen on the methods.
-     *
-     * So what we are doing is the following:
-     *
-     * We synchronize with GC as usual, using a SoftReference.
-     *
-     * The atomic reference is used to synchronize with {@link #refresh(org.opendaylight.yangtools.sal.binding.generator.util.BindingRuntimeContext)}, e.g. when
-     * refresh happens, it will push a SoftReference(null), e.g. simulate the GC. Now
-     * that may happen while the getter is already busy acting on the old schema context,
-     * so it needs to understand that a refresh has happened and retry. To do that, it
-     * attempts a CAS operation -- if it fails, in knows that the SoftReference has
-     * been replaced and thus it needs to retry.
-     *
-     * Note that {@link #getYangStoreSnapshot()} will still use synchronize() internally
-     * to stop multiple threads doing the same work.
-     */
-    private final AtomicReference<SoftReference<YangStoreSnapshot>> ref =
-            new AtomicReference<>(new SoftReference<YangStoreSnapshot>(null));
-
-    private final AtomicReference<SoftReference<BindingRuntimeContext>> refBindingContext =
-            new AtomicReference<>(new SoftReference<BindingRuntimeContext>(null));
-
-    private final SchemaContextProvider schemaContextProvider;
-    private final BaseNetconfNotificationListener notificationPublisher;
-
-    private final ExecutorService notificationExecutor = Executors.newSingleThreadExecutor(new ThreadFactory() {
-        @Override
-        public Thread newThread(final Runnable r) {
-            return new Thread(r, "config-netconf-connector-capability-notifications");
-        }
-    });
-
-    private final Set<CapabilityListener> listeners = Collections.synchronizedSet(new HashSet<CapabilityListener>());
-
-    public YangStoreService(final SchemaContextProvider schemaContextProvider, final BundleContext context) {
-        this(schemaContextProvider, new NotificationCollectorTracker(context));
-    }
-
-    public YangStoreService(final SchemaContextProvider schemaContextProvider, final BaseNetconfNotificationListener notificationHandler) {
-        this.schemaContextProvider = schemaContextProvider;
-        this.notificationPublisher = notificationHandler;
-    }
-
-    private synchronized YangStoreContext getYangStoreSnapshot() {
-        SoftReference<YangStoreSnapshot> r = ref.get();
-        YangStoreSnapshot ret = r.get();
-
-        while (ret == null) {
-            // We need to be compute a new value
-            ret = new YangStoreSnapshot(schemaContextProvider.getSchemaContext(), refBindingContext.get().get());
-
-            if (!ref.compareAndSet(r, new SoftReference<>(ret))) {
-                LOG.debug("Concurrent refresh detected, recomputing snapshot");
-                r = ref.get();
-                ret = null;
-            }
-        }
-
-        return ret;
-    }
-
-    @Override
-    public Map<String, Map<String, ModuleMXBeanEntry>> getModuleMXBeanEntryMap() {
-        return getYangStoreSnapshot().getModuleMXBeanEntryMap();
-    }
-
-    @Override
-    public Map<QName, Map<String, ModuleMXBeanEntry>> getQNamesToIdentitiesToModuleMXBeanEntries() {
-        return getYangStoreSnapshot().getQNamesToIdentitiesToModuleMXBeanEntries();
-    }
-
-    @Override
-    public Set<Module> getModules() {
-        return getYangStoreSnapshot().getModules();
-    }
-
-    @Override
-    public String getModuleSource(final ModuleIdentifier moduleIdentifier) {
-        return getYangStoreSnapshot().getModuleSource(moduleIdentifier);
-    }
-
-    @Override
-    public EnumResolver getEnumResolver() {
-        return getYangStoreSnapshot().getEnumResolver();
-    }
-
-    public void refresh(final BindingRuntimeContext runtimeContext) {
-        final YangStoreSnapshot previous = ref.get().get();
-        ref.set(new SoftReference<YangStoreSnapshot>(null));
-        refBindingContext.set(new SoftReference<>(runtimeContext));
-        notificationExecutor.submit(new CapabilityChangeNotifier(previous));
-    }
-
-    public AutoCloseable registerCapabilityListener(final CapabilityListener listener) {
-
-        YangStoreContext context = ref.get().get();
-
-        if(context == null) {
-            context = getYangStoreSnapshot();
-        }
-
-        this.listeners.add(listener);
-        listener.onCapabilitiesAdded(NetconfOperationServiceFactoryImpl.setupCapabilities(context));
-
-        return new AutoCloseable() {
-            @Override
-            public void close() throws Exception {
-                YangStoreService.this.listeners.remove(listener);
-            }
-        };
-    }
-
-    private static final Function<Module, Capability> MODULE_TO_CAPABILITY = new Function<Module, Capability>() {
-        @Override
-        public Capability apply(final Module module) {
-            return new YangModuleCapability(module, module.getSource());
-        }
-    };
-
-    private final class CapabilityChangeNotifier implements Runnable {
-
-        private final YangStoreSnapshot previous;
-
-        public CapabilityChangeNotifier(final YangStoreSnapshot previous) {
-            this.previous = previous;
-        }
-
-        @Override
-        public void run() {
-            final YangStoreContext current = getYangStoreSnapshot();
-
-            if(current.equals(previous) == false) {
-                final Sets.SetView<Module> removed = Sets.difference(previous.getModules(), current.getModules());
-                final Sets.SetView<Module> added = Sets.difference(current.getModules(), previous.getModules());
-
-                // Notify notification manager
-                notificationPublisher.onCapabilityChanged(computeDiff(removed, added));
-
-                // Notify direct capability listener TODO would it not be better if the capability listeners went through notification manager ?
-                for (final CapabilityListener listener : listeners) {
-                    listener.onCapabilitiesAdded(Sets.newHashSet(Collections2.transform(added, MODULE_TO_CAPABILITY)));
-                }
-                for (final CapabilityListener listener : listeners) {
-                    listener.onCapabilitiesRemoved(Sets.newHashSet(Collections2.transform(removed, MODULE_TO_CAPABILITY)));
-                }
-            }
-        }
-    }
-
-    private static final Function<Module, Uri> MODULE_TO_URI = new Function<Module, Uri>() {
-        @Override
-        public Uri apply(final Module input) {
-            return new Uri(new YangModuleCapability(input, input.getSource()).getCapabilityUri());
-        }
-    };
-
-    static NetconfCapabilityChange computeDiff(final Sets.SetView<Module> removed, final Sets.SetView<Module> added) {
-        final NetconfCapabilityChangeBuilder netconfCapabilityChangeBuilder = new NetconfCapabilityChangeBuilder();
-        netconfCapabilityChangeBuilder.setChangedBy(new ChangedByBuilder().setServerOrUser(new ServerBuilder().setServer(true).build()).build());
-        netconfCapabilityChangeBuilder.setDeletedCapability(Lists.newArrayList(Collections2.transform(removed, MODULE_TO_URI)));
-        netconfCapabilityChangeBuilder.setAddedCapability(Lists.newArrayList(Collections2.transform(added, MODULE_TO_URI)));
-        // TODO modified should be computed ... but why ?
-        netconfCapabilityChangeBuilder.setModifiedCapability(Collections.<Uri>emptyList());
-        return netconfCapabilityChangeBuilder.build();
-    }
-
-
-    /**
-     * Looks for NetconfNotificationCollector service and publishes base netconf notifications if possible
-     */
-    private static class NotificationCollectorTracker implements ServiceTrackerCustomizer<NetconfNotificationCollector, NetconfNotificationCollector>, BaseNetconfNotificationListener, AutoCloseable {
-
-        private final BundleContext context;
-        private final ServiceTracker<NetconfNotificationCollector, NetconfNotificationCollector> listenerTracker;
-        private BaseNotificationPublisherRegistration publisherReg;
-
-        public NotificationCollectorTracker(final BundleContext context) {
-            this.context = context;
-            listenerTracker = new ServiceTracker<>(context, NetconfNotificationCollector.class, this);
-            listenerTracker.open();
-        }
-
-        @Override
-        public synchronized NetconfNotificationCollector addingService(final ServiceReference<NetconfNotificationCollector> reference) {
-            closePublisherRegistration();
-            publisherReg = context.getService(reference).registerBaseNotificationPublisher();
-            return null;
-        }
-
-        @Override
-        public synchronized void modifiedService(final ServiceReference<NetconfNotificationCollector> reference, final NetconfNotificationCollector service) {
-            closePublisherRegistration();
-            publisherReg = context.getService(reference).registerBaseNotificationPublisher();
-        }
-
-        @Override
-        public synchronized void removedService(final ServiceReference<NetconfNotificationCollector> reference, final NetconfNotificationCollector service) {
-            closePublisherRegistration();
-            publisherReg = null;
-        }
-
-        private void closePublisherRegistration() {
-            if(publisherReg != null) {
-                publisherReg.close();
-            }
-        }
-
-        @Override
-        public synchronized void close() {
-            closePublisherRegistration();
-            listenerTracker.close();
-        }
-
-        @Override
-        public void onCapabilityChanged(final NetconfCapabilityChange capabilityChange) {
-            if(publisherReg == null) {
-                LOG.warn("Omitting notification due to missing notification service: {}", capabilityChange);
-                return;
-            }
-
-            publisherReg.onCapabilityChanged(capabilityChange);
-        }
-    }
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/YangStoreSnapshot.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/YangStoreSnapshot.java
deleted file mode 100644 (file)
index c798da7..0000000
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.osgi;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Predicate;
-import com.google.common.collect.BiMap;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.NoSuchElementException;
-import java.util.Set;
-import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
-import org.opendaylight.controller.config.yangjmxgenerator.PackageTranslator;
-import org.opendaylight.controller.config.yangjmxgenerator.ServiceInterfaceEntry;
-import org.opendaylight.controller.config.yangjmxgenerator.TypeProviderWrapper;
-import org.opendaylight.yangtools.sal.binding.generator.util.BindingRuntimeContext;
-import org.opendaylight.yangtools.sal.binding.yang.types.TypeProviderImpl;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.parser.builder.impl.ModuleIdentifierImpl;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-final class YangStoreSnapshot implements YangStoreContext, EnumResolver {
-    private static final Logger LOG = LoggerFactory.getLogger(YangStoreSnapshot.class);
-
-
-    private final Map<String /* Namespace from yang file */,
-        Map<String /* Name of module entry from yang file */, ModuleMXBeanEntry>> moduleMXBeanEntryMap;
-
-
-    private final Map<QName, Map<String, ModuleMXBeanEntry>> qNamesToIdentitiesToModuleMXBeanEntries;
-
-    private final SchemaContext schemaContext;
-    private final BindingRuntimeContext bindingContextProvider;
-
-    public YangStoreSnapshot(final SchemaContext resolveSchemaContext, final BindingRuntimeContext bindingContextProvider) {
-        this.bindingContextProvider = bindingContextProvider;
-        LOG.trace("Resolved modules:{}", resolveSchemaContext.getModules());
-        this.schemaContext = resolveSchemaContext;
-        // JMX generator
-
-        Map<String, String> namespaceToPackageMapping = Maps.newHashMap();
-        PackageTranslator packageTranslator = new PackageTranslator(namespaceToPackageMapping);
-        Map<QName, ServiceInterfaceEntry> qNamesToSIEs = new HashMap<>();
-        Map<IdentitySchemaNode, ServiceInterfaceEntry> knownSEITracker = new HashMap<>();
-        // create SIE structure qNamesToSIEs
-        for (Module module : resolveSchemaContext.getModules()) {
-            String packageName = packageTranslator.getPackageName(module);
-            Map<QName, ServiceInterfaceEntry> namesToSIEntries = ServiceInterfaceEntry
-                    .create(module, packageName, knownSEITracker);
-            for (Entry<QName, ServiceInterfaceEntry> sieEntry : namesToSIEntries.entrySet()) {
-                // merge value into qNamesToSIEs
-                if (qNamesToSIEs.containsKey(sieEntry.getKey()) == false) {
-                    qNamesToSIEs.put(sieEntry.getKey(), sieEntry.getValue());
-                } else {
-                    throw new IllegalStateException("Cannot add two SIE with same qname "
-                            + sieEntry.getValue());
-                }
-            }
-        }
-
-        Map<String, Map<String, ModuleMXBeanEntry>> moduleMXBeanEntryMap = Maps.newHashMap();
-
-        Map<QName, Map<String /* identity local name */, ModuleMXBeanEntry>> qNamesToIdentitiesToModuleMXBeanEntries = new HashMap<>();
-
-
-        for (Module module : schemaContext.getModules()) {
-            String packageName = packageTranslator.getPackageName(module);
-            TypeProviderWrapper typeProviderWrapper = new TypeProviderWrapper(
-                    new TypeProviderImpl(resolveSchemaContext));
-
-            QName qName = QName.create(module.getNamespace(), module.getRevision(), module.getName());
-
-            Map<String /* MB identity local name */, ModuleMXBeanEntry> namesToMBEs =
-                    Collections.unmodifiableMap(ModuleMXBeanEntry.create(module, qNamesToSIEs, resolveSchemaContext,
-                            typeProviderWrapper, packageName));
-            moduleMXBeanEntryMap.put(module.getNamespace().toString(), namesToMBEs);
-
-            qNamesToIdentitiesToModuleMXBeanEntries.put(qName, namesToMBEs);
-        }
-        this.moduleMXBeanEntryMap = Collections.unmodifiableMap(moduleMXBeanEntryMap);
-        this.qNamesToIdentitiesToModuleMXBeanEntries = Collections.unmodifiableMap(qNamesToIdentitiesToModuleMXBeanEntries);
-
-    }
-
-    @Override
-    public Map<String, Map<String, ModuleMXBeanEntry>> getModuleMXBeanEntryMap() {
-        return moduleMXBeanEntryMap;
-    }
-
-    @Override
-    public Map<QName, Map<String, ModuleMXBeanEntry>> getQNamesToIdentitiesToModuleMXBeanEntries() {
-        return qNamesToIdentitiesToModuleMXBeanEntries;
-    }
-
-    @Override
-    public Set<Module> getModules() {
-        final Set<Module> modules = Sets.newHashSet(schemaContext.getModules());
-        for (final Module module : schemaContext.getModules()) {
-            modules.addAll(module.getSubmodules());
-        }
-        return modules;
-    }
-
-    @Override
-    public String getModuleSource(final org.opendaylight.yangtools.yang.model.api.ModuleIdentifier moduleIdentifier) {
-        final Optional<String> moduleSource = schemaContext.getModuleSource(moduleIdentifier);
-        if(moduleSource.isPresent()) {
-            return moduleSource.get();
-        } else {
-            try {
-                return Iterables.find(getModules(), new Predicate<Module>() {
-                    @Override
-                    public boolean apply(final Module input) {
-                        final ModuleIdentifierImpl id = new ModuleIdentifierImpl(input.getName(), Optional.fromNullable(input.getNamespace()), Optional.fromNullable(input.getRevision()));
-                        return id.equals(moduleIdentifier);
-                    }
-                }).getSource();
-            } catch (final NoSuchElementException e) {
-                throw new IllegalArgumentException("Source for yang module " + moduleIdentifier + " not found", e);
-            }
-        }
-    }
-
-    @Override
-    public EnumResolver getEnumResolver() {
-        return this;
-    }
-
-    @Override
-    public boolean equals(final Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-
-        final YangStoreSnapshot that = (YangStoreSnapshot) o;
-
-        if (schemaContext != null ? !schemaContext.equals(that.schemaContext) : that.schemaContext != null)
-            return false;
-
-        return true;
-    }
-
-    @Override
-    public int hashCode() {
-        return schemaContext != null ? schemaContext.hashCode() : 0;
-    }
-
-    @Override
-    public String fromYang(final String enumClass, final String enumYangValue) {
-        Preconditions.checkState(bindingContextProvider != null, "Binding context provider was not set yet");
-        final BiMap<String, String> enumMapping = bindingContextProvider.getEnumMapping(enumClass);
-        final String javaName = enumMapping.get(enumYangValue);
-        return Preconditions.checkNotNull(javaName, "Unable to resolve enum value %s for enum class %s with assumed enum mapping: %s", enumYangValue, enumClass, enumMapping);
-    }
-
-    @Override
-    public String toYang(final String enumClass, final String enumJavaValue) {
-        Preconditions.checkState(bindingContextProvider != null, "Binding context provider was not set yet");
-        final BiMap<String, String> enumMapping = bindingContextProvider.getEnumMapping(enumClass);
-        final String javaName = enumMapping.inverse().get(enumJavaValue);
-        return Preconditions.checkNotNull(javaName, "Unable to map enumcd .." +
-                "cd  value %s for enum class %s with assumed enum mapping: %s", enumJavaValue, enumClass, enumMapping.inverse());
-    }
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/transactions/TransactionProvider.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/transactions/TransactionProvider.java
deleted file mode 100644 (file)
index 7655cb3..0000000
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.transactions;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
-import javax.management.InstanceNotFoundException;
-import javax.management.ObjectName;
-import org.opendaylight.controller.config.api.ConflictingVersionException;
-import org.opendaylight.controller.config.api.ValidationException;
-import org.opendaylight.controller.config.api.jmx.CommitStatus;
-import org.opendaylight.controller.config.util.ConfigRegistryClient;
-import org.opendaylight.controller.config.util.ConfigTransactionClient;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.confignetconfconnector.exception.NoTransactionFoundException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class TransactionProvider implements AutoCloseable {
-    private static final Logger LOG = LoggerFactory.getLogger(TransactionProvider.class);
-
-    private final ConfigRegistryClient configRegistryClient;
-
-    private final String netconfSessionIdForReporting;
-    private ObjectName candidateTx;
-    private ObjectName readTx;
-    private final List<ObjectName> allOpenedTransactions = new ArrayList<>();
-    private static final String  NO_TRANSACTION_FOUND_FOR_SESSION = "No transaction found for session ";
-
-    public TransactionProvider(ConfigRegistryClient configRegistryClient, String netconfSessionIdForReporting) {
-        this.configRegistryClient = configRegistryClient;
-        this.netconfSessionIdForReporting = netconfSessionIdForReporting;
-    }
-
-    @Override
-    public synchronized void close() {
-        for (ObjectName tx : allOpenedTransactions) {
-            try {
-                if (isStillOpenTransaction(tx)) {
-                    configRegistryClient.getConfigTransactionClient(tx).abortConfig();
-                }
-            } catch (Exception e) {
-                LOG.debug("Ignoring exception while closing transaction {}", tx, e);
-            }
-        }
-        allOpenedTransactions.clear();
-    }
-
-    public synchronized Optional<ObjectName> getTransaction() {
-
-        if (candidateTx == null){
-            return Optional.absent();
-        }
-
-        // Transaction was already closed somehow
-        if (!isStillOpenTransaction(candidateTx)) {
-            LOG.warn("Fixing illegal state: transaction {} was closed in {}", candidateTx,
-                    netconfSessionIdForReporting);
-            candidateTx = null;
-            return Optional.absent();
-        }
-        return Optional.of(candidateTx);
-    }
-
-    public synchronized Optional<ObjectName> getReadTransaction() {
-
-        if (readTx == null){
-            return Optional.absent();
-        }
-
-        // Transaction was already closed somehow
-        if (!isStillOpenTransaction(readTx)) {
-            LOG.warn("Fixing illegal state: transaction {} was closed in {}", readTx,
-                    netconfSessionIdForReporting);
-            readTx = null;
-            return Optional.absent();
-        }
-        return Optional.of(readTx);
-    }
-
-    private boolean isStillOpenTransaction(ObjectName transaction) {
-        return configRegistryClient.getOpenConfigs().contains(transaction);
-    }
-
-    public synchronized ObjectName getOrCreateTransaction() {
-        Optional<ObjectName> ta = getTransaction();
-
-        if (ta.isPresent()) {
-            return ta.get();
-        }
-        candidateTx = configRegistryClient.beginConfig();
-        allOpenedTransactions.add(candidateTx);
-        return candidateTx;
-    }
-
-    public synchronized ObjectName getOrCreateReadTransaction() {
-        Optional<ObjectName> ta = getReadTransaction();
-
-        if (ta.isPresent()) {
-            return ta.get();
-        }
-        readTx = configRegistryClient.beginConfig();
-        allOpenedTransactions.add(readTx);
-        return readTx;
-    }
-
-    /**
-     * Used for editConfig test option
-     */
-    public synchronized ObjectName getTestTransaction() {
-        ObjectName testTx = configRegistryClient.beginConfig();
-        allOpenedTransactions.add(testTx);
-        return testTx;
-    }
-
-    /**
-     * Commit and notification send must be atomic
-     */
-    public synchronized CommitStatus commitTransaction() throws ValidationException, ConflictingVersionException, NoTransactionFoundException {
-        if (!getTransaction().isPresent()){
-            throw new NoTransactionFoundException("No transaction found for session " + netconfSessionIdForReporting,
-                    NetconfDocumentedException.ErrorType.application,
-                    NetconfDocumentedException.ErrorTag.operation_failed,
-                    NetconfDocumentedException.ErrorSeverity.error);
-        }
-        final Optional<ObjectName> maybeTaON = getTransaction();
-        ObjectName taON = maybeTaON.get();
-        try {
-            CommitStatus status = configRegistryClient.commitConfig(taON);
-            // clean up
-            allOpenedTransactions.remove(candidateTx);
-            candidateTx = null;
-            return status;
-        } catch (ValidationException validationException) {
-            // no clean up: user can reconfigure and recover this transaction
-            LOG.warn("Transaction {} failed on {}", taON, validationException.toString());
-            throw validationException;
-        } catch (ConflictingVersionException e) {
-            LOG.error("Exception while commit of {}, aborting transaction", taON, e);
-            // clean up
-            abortTransaction();
-            throw e;
-        }
-    }
-
-    public synchronized void abortTransaction() {
-        LOG.debug("Aborting current transaction");
-        Optional<ObjectName> taON = getTransaction();
-        Preconditions.checkState(taON.isPresent(), NO_TRANSACTION_FOUND_FOR_SESSION + netconfSessionIdForReporting);
-
-        ConfigTransactionClient transactionClient = configRegistryClient.getConfigTransactionClient(taON.get());
-        transactionClient.abortConfig();
-        allOpenedTransactions.remove(candidateTx);
-        candidateTx = null;
-    }
-
-    public synchronized void closeReadTransaction() {
-        LOG.debug("Closing read transaction");
-        Optional<ObjectName> taON = getReadTransaction();
-        Preconditions.checkState(taON.isPresent(), NO_TRANSACTION_FOUND_FOR_SESSION + netconfSessionIdForReporting);
-
-        ConfigTransactionClient transactionClient = configRegistryClient.getConfigTransactionClient(taON.get());
-        transactionClient.abortConfig();
-        allOpenedTransactions.remove(readTx);
-        readTx = null;
-    }
-
-    public synchronized void abortTestTransaction(ObjectName testTx) {
-        LOG.debug("Aborting transaction {}", testTx);
-        ConfigTransactionClient transactionClient = configRegistryClient.getConfigTransactionClient(testTx);
-        allOpenedTransactions.remove(testTx);
-        transactionClient.abortConfig();
-    }
-
-    public void validateTransaction() throws ValidationException {
-        Optional<ObjectName> taON = getTransaction();
-        Preconditions.checkState(taON.isPresent(), NO_TRANSACTION_FOUND_FOR_SESSION + netconfSessionIdForReporting);
-
-        ConfigTransactionClient transactionClient = configRegistryClient.getConfigTransactionClient(taON.get());
-        transactionClient.validateConfig();
-    }
-
-    public void validateTestTransaction(ObjectName taON) throws ValidationException {
-        ConfigTransactionClient transactionClient = configRegistryClient.getConfigTransactionClient(taON);
-        transactionClient.validateConfig();
-    }
-
-    public void wipeTestTransaction(ObjectName taON) {
-        wipeInternal(taON, true);
-    }
-
-    /**
-     * Wiping means removing all module instances keeping the transaction open + service references.
-     */
-    synchronized void wipeInternal(ObjectName taON, boolean isTest) {
-        ConfigTransactionClient transactionClient = configRegistryClient.getConfigTransactionClient(taON);
-
-        Set<ObjectName> lookupConfigBeans = transactionClient.lookupConfigBeans();
-        int i = lookupConfigBeans.size();
-        for (ObjectName instance : lookupConfigBeans) {
-            try {
-                transactionClient.destroyModule(instance);
-            } catch (InstanceNotFoundException e) {
-                if (isTest){
-                    LOG.debug("Unable to clean configuration in transactiom {}", taON, e);
-                } else {
-                    LOG.warn("Unable to clean configuration in transactiom {}", taON, e);
-                }
-
-                throw new IllegalStateException("Unable to clean configuration in transactiom " + taON, e);
-            }
-        }
-        LOG.debug("Transaction {} wiped clean of {} config beans", taON, i);
-
-        transactionClient.removeAllServiceReferences();
-        LOG.debug("Transaction {} wiped clean of all service references", taON);
-    }
-
-    public void wipeTransaction() {
-        Optional<ObjectName> taON = getTransaction();
-        Preconditions.checkState(taON.isPresent(), NO_TRANSACTION_FOUND_FOR_SESSION + netconfSessionIdForReporting);
-        wipeInternal(taON.get(), false);
-    }
-
-}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/util/Util.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/util/Util.java
deleted file mode 100644 (file)
index 7b286df..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.util;
-
-import static org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil.getRevisionFormat;
-
-import com.google.common.base.Preconditions;
-import java.text.ParseException;
-import java.util.Date;
-
-public final class Util {
-
-    public static String writeDate(final Date date) {
-        return getRevisionFormat().format(date);
-    }
-
-    public static Date readDate(final String s) throws ParseException {
-        return getRevisionFormat().parse(s);
-    }
-
-    public static void checkType(final Object value, final Class<?> clazz) {
-        Preconditions.checkArgument(clazz.isAssignableFrom(value.getClass()), "Unexpected type " + value.getClass()
-                + " should be " + clazz + " of " + value);
-    }
-
-}
index 388a131a5611642d58cb046d45b1b6da4fe9a967..9a9f9c5de1bfa2ddee50f516eaa051ff6cd738e2 100644 (file)
@@ -23,9 +23,9 @@ import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.opendaylight.controller.config.util.xml.XmlUtil.readXmlToElement;
 import static org.opendaylight.controller.netconf.util.test.XmlUnitUtil.assertContainsElement;
 import static org.opendaylight.controller.netconf.util.test.XmlUnitUtil.assertContainsElementWithText;
-import static org.opendaylight.controller.netconf.util.xml.XmlUtil.readXmlToElement;
 
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
@@ -71,9 +71,16 @@ import org.opendaylight.controller.config.api.ConflictingVersionException;
 import org.opendaylight.controller.config.api.ValidationException;
 import org.opendaylight.controller.config.api.annotations.AbstractServiceInterface;
 import org.opendaylight.controller.config.api.annotations.ServiceInterfaceAnnotation;
+import org.opendaylight.controller.config.facade.xml.ConfigSubsystemFacade;
+import org.opendaylight.controller.config.facade.xml.osgi.EnumResolver;
+import org.opendaylight.controller.config.facade.xml.osgi.YangStoreService;
+import org.opendaylight.controller.config.facade.xml.transactions.TransactionProvider;
 import org.opendaylight.controller.config.manager.impl.AbstractConfigTest;
 import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
 import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.config.util.xml.XmlMappingConstants;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.config.yang.test.impl.ComplexDtoBInner;
 import org.opendaylight.controller.config.yang.test.impl.ComplexList;
 import org.opendaylight.controller.config.yang.test.impl.Deep;
@@ -88,11 +95,6 @@ import org.opendaylight.controller.config.yang.test.impl.NetconfTestImplModuleMX
 import org.opendaylight.controller.config.yang.test.impl.Peers;
 import org.opendaylight.controller.config.yang.test.impl.TestImplModuleFactory;
 import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorSeverity;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorTag;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorType;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.Commit;
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.DiscardChanges;
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.Lock;
@@ -101,10 +103,6 @@ import org.opendaylight.controller.netconf.confignetconfconnector.operations.edi
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.get.Get;
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.getconfig.GetConfig;
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.runtimerpc.RuntimeRpc;
-import org.opendaylight.controller.netconf.confignetconfconnector.osgi.EnumResolver;
-import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreContext;
-import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreService;
-import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider;
 import org.opendaylight.controller.netconf.impl.NetconfServerSession;
 import org.opendaylight.controller.netconf.impl.NetconfServerSessionListener;
 import org.opendaylight.controller.netconf.impl.mapping.operations.DefaultCloseSession;
@@ -116,7 +114,6 @@ import org.opendaylight.controller.netconf.mapping.api.NetconfOperationChainedEx
 import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader;
 import org.opendaylight.controller.netconf.util.messages.NetconfMessageUtil;
 import org.opendaylight.controller.netconf.util.test.XmlFileLoader;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.test.types.rev131127.TestIdentity1;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.test.types.rev131127.TestIdentity2;
 import org.opendaylight.yangtools.sal.binding.generator.util.BindingRuntimeContext;
@@ -150,7 +147,7 @@ public class NetconfMappingTest extends AbstractConfigTest {
     private TestImplModuleFactory factory4;
 
     @Mock
-    YangStoreContext yangStoreSnapshot;
+    YangStoreService yangStoreSnapshot;
     @Mock
     NetconfOperationRouter netconfOperationRouter;
     @Mock
@@ -160,6 +157,8 @@ public class NetconfMappingTest extends AbstractConfigTest {
 
     private TransactionProvider transactionProvider;
 
+    private ConfigSubsystemFacade configSubsystemFacade;
+
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
@@ -170,6 +169,7 @@ public class NetconfMappingTest extends AbstractConfigTest {
         doNothing().when(mockedContext).addServiceListener(any(ServiceListener.class), anyString());
         doReturn(new ServiceReference<?>[]{}).when(mockedContext).getServiceReferences(anyString(), anyString());
 
+        doReturn(yangStoreSnapshot).when(yangStoreSnapshot).getCurrentSnapshot();
         doReturn(getMbes()).when(this.yangStoreSnapshot).getModuleMXBeanEntryMap();
         doReturn(getModules()).when(this.yangStoreSnapshot).getModules();
         doReturn(new EnumResolver() {
@@ -196,6 +196,8 @@ public class NetconfMappingTest extends AbstractConfigTest {
                 this.factory3, factory4));
 
         transactionProvider = new TransactionProvider(this.configRegistryClient, NETCONF_SESSION_ID);
+
+        configSubsystemFacade = new ConfigSubsystemFacade(configRegistryClient, configRegistryClient, yangStoreSnapshot, "mapping-test");
     }
 
     private ObjectName createModule(final String instanceName) throws InstanceAlreadyExistsException, InstanceNotFoundException, URISyntaxException, ValidationException, ConflictingVersionException {
@@ -294,10 +296,10 @@ public class NetconfMappingTest extends AbstractConfigTest {
         try {
             edit("netconfMessages/editConfig_removeServiceNameOnTest.xml");
             fail("Should've failed, non-existing service instance");
-        } catch (NetconfDocumentedException e) {
-            assertEquals(e.getErrorSeverity(), ErrorSeverity.error);
-            assertEquals(e.getErrorTag(), ErrorTag.operation_failed);
-            assertEquals(e.getErrorType(), ErrorType.application);
+        } catch (DocumentedException e) {
+            assertEquals(e.getErrorSeverity(), DocumentedException.ErrorSeverity.error);
+            assertEquals(e.getErrorTag(), DocumentedException.ErrorTag.operation_failed);
+            assertEquals(e.getErrorType(), DocumentedException.ErrorType.application);
         }
 
         edit("netconfMessages/editConfig_replace_default.xml");
@@ -449,8 +451,8 @@ public class NetconfMappingTest extends AbstractConfigTest {
 
     }
 
-    private void closeSession() throws NetconfDocumentedException, ParserConfigurationException, SAXException,
-            IOException {
+    private void closeSession() throws ParserConfigurationException, SAXException,
+            IOException, DocumentedException {
         final Channel channel = mock(Channel.class);
         doReturn("channel").when(channel).toString();
         final NetconfServerSessionListener listener = mock(NetconfServerSessionListener.class);
@@ -463,43 +465,40 @@ public class NetconfMappingTest extends AbstractConfigTest {
     }
 
     private void edit(String resource) throws ParserConfigurationException, SAXException, IOException,
-            NetconfDocumentedException {
-        EditConfig editOp = new EditConfig(yangStoreSnapshot, transactionProvider, configRegistryClient,
-                NETCONF_SESSION_ID);
+            DocumentedException {
+        EditConfig editOp = new EditConfig(configSubsystemFacade, NETCONF_SESSION_ID);
         executeOp(editOp, resource);
     }
 
-    private void commit() throws ParserConfigurationException, SAXException, IOException, NetconfDocumentedException {
-        Commit commitOp = new Commit(transactionProvider, configRegistryClient, NETCONF_SESSION_ID);
+    private void commit() throws ParserConfigurationException, SAXException, IOException, DocumentedException {
+        Commit commitOp = new Commit(configSubsystemFacade, NETCONF_SESSION_ID);
         executeOp(commitOp, "netconfMessages/commit.xml");
     }
 
-    private Document lockCandidate() throws ParserConfigurationException, SAXException, IOException, NetconfDocumentedException {
+    private Document lockCandidate() throws ParserConfigurationException, SAXException, IOException, DocumentedException {
         Lock commitOp = new Lock(NETCONF_SESSION_ID);
         return executeOp(commitOp, "netconfMessages/lock.xml");
     }
 
-    private Document unlockCandidate() throws ParserConfigurationException, SAXException, IOException, NetconfDocumentedException {
+    private Document unlockCandidate() throws ParserConfigurationException, SAXException, IOException, DocumentedException {
         UnLock commitOp = new UnLock(NETCONF_SESSION_ID);
         return executeOp(commitOp, "netconfMessages/unlock.xml");
     }
 
     private Document getConfigCandidate() throws ParserConfigurationException, SAXException, IOException,
-            NetconfDocumentedException {
-        GetConfig getConfigOp = new GetConfig(yangStoreSnapshot, Optional.<String> absent(), transactionProvider,
-                configRegistryClient, NETCONF_SESSION_ID);
+            DocumentedException {
+        GetConfig getConfigOp = new GetConfig(configSubsystemFacade, Optional.<String> absent(), NETCONF_SESSION_ID);
         return executeOp(getConfigOp, "netconfMessages/getConfig_candidate.xml");
     }
 
     private Document getConfigRunning() throws ParserConfigurationException, SAXException, IOException,
-            NetconfDocumentedException {
-        GetConfig getConfigOp = new GetConfig(yangStoreSnapshot, Optional.<String> absent(), transactionProvider,
-                configRegistryClient, NETCONF_SESSION_ID);
+            DocumentedException {
+        GetConfig getConfigOp = new GetConfig(configSubsystemFacade, Optional.<String> absent(), NETCONF_SESSION_ID);
         return executeOp(getConfigOp, "netconfMessages/getConfig.xml");
     }
 
     @Ignore("second edit message corrupted")
-    @Test(expected = NetconfDocumentedException.class)
+    @Test(expected = DocumentedException.class)
     public void testConfigNetconfReplaceDefaultEx() throws Exception {
 
         createModule(INSTANCE_NAME);
@@ -533,11 +532,11 @@ public class NetconfMappingTest extends AbstractConfigTest {
         try {
             edit("netconfMessages/namespaces/editConfig_sameAttrDifferentNamespaces.xml");
             fail();
-        } catch (NetconfDocumentedException e) {
+        } catch (DocumentedException e) {
             String message = e.getMessage();
             assertContainsString(message, "Element simpleInt present multiple times with different namespaces");
             assertContainsString(message, TEST_NAMESPACE);
-            assertContainsString(message, XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG);
+            assertContainsString(message, XmlMappingConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG);
         }
     }
 
@@ -546,7 +545,7 @@ public class NetconfMappingTest extends AbstractConfigTest {
         try {
             edit("netconfMessages/namespaces/editConfig_differentNamespaceTO.xml");
             fail();
-        } catch (NetconfDocumentedException e) {
+        } catch (DocumentedException e) {
             String message = e.getMessage();
             assertContainsString(message, "Unrecognised elements");
             assertContainsString(message, "simple-int2");
@@ -559,11 +558,11 @@ public class NetconfMappingTest extends AbstractConfigTest {
         try {
             edit("netconfMessages/namespaces/editConfig_sameAttrDifferentNamespacesList.xml");
             fail();
-        } catch (NetconfDocumentedException e) {
+        } catch (DocumentedException e) {
             String message = e.getMessage();
             assertContainsString(message, "Element allow-user present multiple times with different namespaces");
             assertContainsString(message, TEST_NAMESPACE);
-            assertContainsString(message, XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG);
+            assertContainsString(message, XmlMappingConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG);
         }
     }
 
@@ -579,7 +578,7 @@ public class NetconfMappingTest extends AbstractConfigTest {
     }
 
     // TODO add <modules operation="replace"> functionality
-    @Test(expected = NetconfDocumentedException.class)
+    @Test(expected = DocumentedException.class)
     public void testConfigNetconfReplaceModuleEx() throws Exception {
 
         createModule(INSTANCE_NAME);
@@ -599,7 +598,7 @@ public class NetconfMappingTest extends AbstractConfigTest {
             LOG.info("Reading {}", file);
             try {
                 edit(file);
-            } catch (NetconfDocumentedException e) {
+            } catch (DocumentedException e) {
                 assertContainsString(e.getMessage(), "Unrecognised elements");
                 assertContainsString(e.getMessage(), "unknownAttribute");
                 continue;
@@ -630,7 +629,7 @@ public class NetconfMappingTest extends AbstractConfigTest {
         assertEquals(3 + 3, afterReplace);
     }
 
-    @Test(expected = NetconfDocumentedException.class)
+    @Test(expected = DocumentedException.class)
     public void testEx() throws Exception {
 
         commit();
@@ -648,26 +647,23 @@ public class NetconfMappingTest extends AbstractConfigTest {
 
     @Test
     public void testFailedDiscardChangesAbort() throws Exception {
+        final ConfigSubsystemFacade facade = mock(ConfigSubsystemFacade.class);
+        doThrow(new RuntimeException("Mocked runtime exception, Abort has to fail")).when(facade).abortConfiguration();
 
-        TransactionProvider mockedTxProvider = mock(TransactionProvider.class);
-        doThrow(new RuntimeException("Mocked runtime exception, Abort has to fail")).when(mockedTxProvider).abortTransaction();
-        doReturn(Optional.of(ObjectName.getInstance("dummyDomain", "DummyKey", "DummyValue"))).when(mockedTxProvider).getTransaction();
-
-        DiscardChanges discardOp = new DiscardChanges(mockedTxProvider, configRegistryClient, NETCONF_SESSION_ID);
+        DiscardChanges discardOp = new DiscardChanges(facade, NETCONF_SESSION_ID);
 
         try {
             executeOp(discardOp, "netconfMessages/discardChanges.xml");
             fail("Should've failed, abort on mocked is supposed to throw RuntimeException");
-        } catch (NetconfDocumentedException e) {
-            assertTrue(e.getErrorTag() == ErrorTag.operation_failed);
-            assertTrue(e.getErrorSeverity() == ErrorSeverity.error);
-            assertTrue(e.getErrorType() == ErrorType.application);
+        } catch (DocumentedException e) {
+            assertTrue(e.getErrorTag() == DocumentedException.ErrorTag.operation_failed);
+            assertTrue(e.getErrorSeverity() == DocumentedException.ErrorSeverity.error);
+            assertTrue(e.getErrorType() == DocumentedException.ErrorType.application);
         }
-
     }
 
-    private Document discard() throws ParserConfigurationException, SAXException, IOException, NetconfDocumentedException {
-        DiscardChanges discardOp = new DiscardChanges(transactionProvider, configRegistryClient, NETCONF_SESSION_ID);
+    private Document discard() throws ParserConfigurationException, SAXException, IOException, DocumentedException {
+        DiscardChanges discardOp = new DiscardChanges(configSubsystemFacade, NETCONF_SESSION_ID);
         return executeOp(discardOp, "netconfMessages/discardChanges.xml");
     }
 
@@ -741,7 +737,7 @@ public class NetconfMappingTest extends AbstractConfigTest {
             public SchemaContext getSchemaContext() {
                 return schemaContext ;
             }
-        }, mockedContext);
+        });
         final BindingRuntimeContext bindingRuntimeContext = mock(BindingRuntimeContext.class);
         doReturn(getEnumMapping()).when(bindingRuntimeContext).getEnumMapping(any(Class.class));
         yangStoreService.refresh(bindingRuntimeContext);
@@ -802,7 +798,7 @@ public class NetconfMappingTest extends AbstractConfigTest {
         assertEquals(8, getElementsSize(response, "deep4"));
         // TODO assert keys
 
-        RuntimeRpc netconf = new RuntimeRpc(yangStoreSnapshot, configRegistryClient, NETCONF_SESSION_ID);
+        RuntimeRpc netconf = new RuntimeRpc(configSubsystemFacade, NETCONF_SESSION_ID);
 
         response = executeOp(netconf, "netconfMessages/rpc.xml");
         assertContainsElementWithText(response, "testarg1");
@@ -820,8 +816,8 @@ public class NetconfMappingTest extends AbstractConfigTest {
         assertContainsElementWithText(response, "2");
     }
 
-    private Document get() throws NetconfDocumentedException, ParserConfigurationException, SAXException, IOException {
-        Get getOp = new Get(transactionProvider, yangStoreSnapshot, configRegistryClient, NETCONF_SESSION_ID);
+    private Document get() throws ParserConfigurationException, SAXException, IOException, DocumentedException {
+        Get getOp = new Get(configSubsystemFacade, NETCONF_SESSION_ID);
         return executeOp(getOp, "netconfMessages/get.xml");
     }
 
@@ -834,7 +830,7 @@ public class NetconfMappingTest extends AbstractConfigTest {
     }
 
     private Document executeOp(final NetconfOperation op, final String filename) throws ParserConfigurationException,
-            SAXException, IOException, NetconfDocumentedException {
+            SAXException, IOException, DocumentedException {
 
         final Document request = XmlFileLoader.xmlFileToDocument(filename);
 
index 52b6f677a43ab3cc105958f10b8900dbe4bd81b7..0fc738eb3858ff39811a8ab1acd130c91063b2af 100644 (file)
@@ -11,8 +11,8 @@ package org.opendaylight.controller.netconf.confignetconfconnector;
 import static org.junit.Assert.assertEquals;
 
 import org.junit.Test;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services.ServiceInstance;
+import org.opendaylight.controller.config.facade.xml.mapping.config.Services;
+import org.opendaylight.controller.config.facade.xml.mapping.config.Services.ServiceInstance;
 
 public class ServiceTrackerTest {
 
diff --git a/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleIdentityRefAttributeReadingStrategyTest.java b/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleIdentityRefAttributeReadingStrategyTest.java
deleted file mode 100644 (file)
index db21d82..0000000
+++ /dev/null
@@ -1,42 +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.netconf.confignetconfconnector.mapping.attributes.fromxml;
-
-import static org.junit.Assert.assertEquals;
-
-import com.google.common.collect.Maps;
-import java.net.URI;
-import java.util.Collections;
-import java.util.Date;
-import java.util.Map;
-import org.junit.Test;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfig;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-
-public class SimpleIdentityRefAttributeReadingStrategyTest {
-
-    @Test
-    public void testReadIdRef() throws Exception {
-        final Map<String, Map<Date, EditConfig.IdentityMapping>> identityMapping = Maps.newHashMap();
-        final EditConfig.IdentityMapping value = new EditConfig.IdentityMapping();
-        final Date rev = new Date();
-        identityMapping.put("namespace", Collections.singletonMap(rev, value));
-        identityMapping.put("inner", Collections.singletonMap(rev, value));
-        final SimpleIdentityRefAttributeReadingStrategy key = new SimpleIdentityRefAttributeReadingStrategy(null, "key", identityMapping);
-
-        String read = key.readElementContent(XmlElement.fromString("<el xmlns=\"namespace\">local</el>"));
-        assertEquals(org.opendaylight.yangtools.yang.common.QName.create(URI.create("namespace"), rev, "local").toString(), read);
-
-        read = key.readElementContent(XmlElement.fromString("<el xmlns:a=\"inner\" xmlns=\"namespace\">a:local</el>"));
-        assertEquals(org.opendaylight.yangtools.yang.common.QName.create(URI.create("inner"), rev, "local").toString(), read);
-
-        read = key.readElementContent(XmlElement.fromString("<top xmlns=\"namespace\"><el>local</el></top>").getOnlyChildElement());
-        assertEquals(org.opendaylight.yangtools.yang.common.QName.create(URI.create("namespace"), rev, "local").toString(), read);
-    }
-}
index 89d9061426ac020dac0bcb41a0491b2295658b70..f840fe36694b39be87f8f01c75683a69e2baa66b 100644 (file)
@@ -15,68 +15,68 @@ import static org.mockito.Mockito.mock;
 
 import org.junit.Test;
 import org.opendaylight.controller.config.api.ValidationException;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.config.facade.xml.ConfigSubsystemFacade;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.config.util.xml.XmlElement;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.w3c.dom.Element;
 
 public class ValidateTest {
 
     public static final String NETCONF_SESSION_ID_FOR_REPORTING = "foo";
 
-    @Test(expected = NetconfDocumentedException.class)
+    @Test(expected = DocumentedException.class)
     public void test() throws Exception {
         final XmlElement xml = XmlElement.fromString("<abc></abc>");
-        final Validate validate = new Validate(null, null, NETCONF_SESSION_ID_FOR_REPORTING);
+        final Validate validate = new Validate(null, NETCONF_SESSION_ID_FOR_REPORTING);
         validate.handleWithNoSubsequentOperations(null, xml);
     }
 
-    @Test(expected = NetconfDocumentedException.class)
+    @Test(expected = DocumentedException.class)
     public void testNoSource() throws Exception {
         final XmlElement xml = XmlElement.fromString("<validate xmlns=\""
                 + XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0 + "\"/>");
-        final Validate validate = new Validate(null, null, NETCONF_SESSION_ID_FOR_REPORTING);
+        final Validate validate = new Validate(null, NETCONF_SESSION_ID_FOR_REPORTING);
         validate.handleWithNoSubsequentOperations(null, xml);
     }
 
-    @Test(expected = NetconfDocumentedException.class)
+    @Test(expected = DocumentedException.class)
     public void testNoNamespace() throws Exception {
         final XmlElement xml = XmlElement.fromString("<validate/>");
-        final Validate validate = new Validate(null, null, NETCONF_SESSION_ID_FOR_REPORTING);
+        final Validate validate = new Validate(null, NETCONF_SESSION_ID_FOR_REPORTING);
         validate.handleWithNoSubsequentOperations(null, xml);
     }
 
-    @Test(expected = NetconfDocumentedException.class)
+    @Test(expected = DocumentedException.class)
     public void testRunningSource() throws Exception {
 
         final XmlElement xml = XmlElement.fromString("<validate xmlns=\""
                 + XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0
                 + "\"><source><running></running></source></validate>");
-        final Validate validate = new Validate(null, null, NETCONF_SESSION_ID_FOR_REPORTING);
+        final Validate validate = new Validate(null, NETCONF_SESSION_ID_FOR_REPORTING);
         validate.handleWithNoSubsequentOperations(null, xml);
     }
 
-    @Test(expected = NetconfDocumentedException.class)
+    @Test(expected = DocumentedException.class)
     public void testNoTransaction() throws Exception {
         final XmlElement xml = XmlElement.fromString("<validate xmlns=\""
                 + XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0
                 + "\"><source><candidate/></source></validate>");
-        final TransactionProvider transactionProvider = mock(TransactionProvider.class);
-        doThrow(IllegalStateException.class).when(transactionProvider).validateTransaction();
-        final Validate validate = new Validate(transactionProvider, null, NETCONF_SESSION_ID_FOR_REPORTING);
+        final ConfigSubsystemFacade facade = mock(ConfigSubsystemFacade.class);
+        doThrow(IllegalStateException.class).when(facade).validateConfiguration();
+        final Validate validate = new Validate(facade, NETCONF_SESSION_ID_FOR_REPORTING);
         validate.handleWithNoSubsequentOperations(null, xml);
     }
 
-    @Test(expected = NetconfDocumentedException.class)
+    @Test(expected = DocumentedException.class)
     public void testValidationException() throws Exception {
         final XmlElement xml = XmlElement.fromString("<validate xmlns=\""
                 + XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0
                 + "\">><source><candidate/></source></validate>");
-        final TransactionProvider transactionProvider = mock(TransactionProvider.class);
-        doThrow(ValidationException.class).when(transactionProvider).validateTransaction();
-        final Validate validate = new Validate(transactionProvider, null, NETCONF_SESSION_ID_FOR_REPORTING);
+        final ConfigSubsystemFacade facade = mock(ConfigSubsystemFacade.class);
+        doThrow(ValidationException.class).when(facade).validateConfiguration();
+        final Validate validate = new Validate(facade, NETCONF_SESSION_ID_FOR_REPORTING);
         validate.handleWithNoSubsequentOperations(null, xml);
     }
 
@@ -85,10 +85,10 @@ public class ValidateTest {
         final XmlElement xml = XmlElement.fromString("<validate xmlns=\""
                 + XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0
                 + "\"><source><candidate/></source></validate>");
-        final TransactionProvider transactionProvider = mock(TransactionProvider.class);
         final Element okElement = XmlUtil.readXmlToElement("<ok/>");
-        doNothing().when(transactionProvider).validateTransaction();
-        final Validate validate = new Validate(transactionProvider, null, NETCONF_SESSION_ID_FOR_REPORTING);
+        final ConfigSubsystemFacade facade = mock(ConfigSubsystemFacade.class);
+        doNothing().when(facade).validateConfiguration();
+        final Validate validate = new Validate(facade, NETCONF_SESSION_ID_FOR_REPORTING);
         Element ok = validate.handleWithNoSubsequentOperations(XmlUtil.newDocument(), xml);
         assertEquals(XmlUtil.toString(okElement), XmlUtil.toString(ok));
     }
index ad57f897e01d00e4105b8460b222078f71877863..b0b9c752865d02049f3fe5a4eae39a790c92cd5b 100644 (file)
@@ -29,26 +29,28 @@ import org.junit.Test;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry;
-import org.opendaylight.controller.config.api.ValidationException;
+import org.opendaylight.controller.config.facade.xml.ConfigExecution;
+import org.opendaylight.controller.config.facade.xml.ConfigSubsystemFacade;
+import org.opendaylight.controller.config.facade.xml.mapping.attributes.fromxml.AttributeConfigElement;
+import org.opendaylight.controller.config.facade.xml.mapping.config.InstanceConfigElementResolved;
+import org.opendaylight.controller.config.facade.xml.mapping.config.ModuleElementDefinition;
+import org.opendaylight.controller.config.facade.xml.mapping.config.ModuleElementResolved;
+import org.opendaylight.controller.config.facade.xml.mapping.config.ServiceRegistryWrapper;
+import org.opendaylight.controller.config.facade.xml.mapping.config.Services;
+import org.opendaylight.controller.config.facade.xml.osgi.YangStoreService;
+import org.opendaylight.controller.config.facade.xml.strategy.EditConfigStrategy;
+import org.opendaylight.controller.config.facade.xml.strategy.EditStrategyType;
+import org.opendaylight.controller.config.facade.xml.transactions.TransactionProvider;
 import org.opendaylight.controller.config.util.ConfigRegistryClient;
 import org.opendaylight.controller.config.util.ConfigTransactionClient;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfigElementResolved;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleElementDefinition;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleElementResolved;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
+import org.opendaylight.controller.config.util.xml.XmlElement;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.ValidateTest;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfigXmlParser.EditConfigExecution;
-import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreContext;
-import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 
 public class EditConfigTest {
 
     @Mock
-    private YangStoreContext yangStoreSnapshot;
+    private YangStoreService yangStoreSnapshot;
     @Mock
     private TransactionProvider provider;
     @Mock
@@ -58,6 +60,8 @@ public class EditConfigTest {
     @Mock
     private ObjectName mockOn;
 
+    private ConfigSubsystemFacade cfgFacade;
+
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
@@ -76,18 +80,19 @@ public class EditConfigTest {
         doReturn("mockConfigTransactionClient").when(configTransactionClient).toString();
 
         doReturn(mockOn).when(configTransactionClient).lookupConfigBean(anyString(), anyString());
+
+        cfgFacade = new ConfigSubsystemFacade(configRegistry, configRegistry, yangStoreSnapshot, provider);
     }
 
     @Test
-    public void test() throws NetconfDocumentedException, ValidationException {
-        EditConfig edit = new EditConfig(yangStoreSnapshot, provider, configRegistry,
-                ValidateTest.NETCONF_SESSION_ID_FOR_REPORTING);
+    public void test() throws Exception {
+        EditConfig edit = new EditConfig(cfgFacade, ValidateTest.NETCONF_SESSION_ID_FOR_REPORTING);
         EditConfigStrategy editStrat = mock(EditConfigStrategy.class);
 
         doNothing().when(editStrat).executeConfiguration(anyString(), anyString(), anyMapOf(String.class, AttributeConfigElement.class),
                 any(ConfigTransactionClient.class), any(ServiceRegistryWrapper.class));
 
-        EditConfigExecution editConfigExecution = mockExecution(editStrat);
+        ConfigExecution editConfigExecution = mockExecution(editStrat);
 
         edit.getResponseInternal(XmlUtil.newDocument(), editConfigExecution);
 
@@ -103,8 +108,8 @@ public class EditConfigTest {
                 any(ConfigTransactionClient.class), any(ServiceRegistryWrapper.class));
     }
 
-    private EditConfigExecution mockExecution(EditConfigStrategy editStrat) throws NetconfDocumentedException {
-        EditConfigExecution mock = mock(EditConfigExecution.class);
+    private ConfigExecution mockExecution(EditConfigStrategy editStrat) throws Exception {
+        ConfigExecution mock = mock(ConfigExecution.class);
         doReturn(getMapping(editStrat)).when(mock).getResolvedXmlElements(any(ConfigTransactionClient.class));
         doReturn(getMappingDefinition(editStrat)).when(mock).getModulesDefinition(any(ConfigTransactionClient.class));
         doReturn(EditStrategyType.merge).when(mock).getDefaultStrategy();
@@ -112,6 +117,7 @@ public class EditConfigTest {
         doReturn(true).when(mock).shouldTest();
         doReturn(mockServices()).when(mock).getServiceRegistryWrapper(any(ConfigTransactionClient.class));
         doReturn(new Services()).when(mock).getServices();
+        doReturn(XmlElement.fromDomElement(XmlUtil.readXmlToElement("<abc/>"))).when(mock).getConfigElement();
         return mock;
     }
 
index b1877498a95c551bfe2faafa58fa85703efc7030..ab5635603dc9526b40daaaaf59337c5c37627132 100644 (file)
@@ -21,14 +21,15 @@ import java.util.Map;
 import javax.management.ObjectName;
 import org.junit.Before;
 import org.junit.Test;
+import org.opendaylight.controller.config.facade.xml.mapping.attributes.fromxml.AttributeConfigElement;
+import org.opendaylight.controller.config.facade.xml.mapping.config.ServiceRegistryWrapper;
+import org.opendaylight.controller.config.facade.xml.strategy.MergeEditConfigStrategy;
 import org.opendaylight.controller.config.manager.impl.AbstractConfigTest;
 import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
 import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
 import org.opendaylight.controller.config.yang.test.impl.MultipleDependenciesModule;
 import org.opendaylight.controller.config.yang.test.impl.MultipleDependenciesModuleFactory;
 import org.opendaylight.controller.config.yang.test.impl.MultipleDependenciesModuleMXBean;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
 
 public class MergeEditConfigStrategyTest extends AbstractConfigTest {
     private static final MultipleDependenciesModuleFactory factory = new MultipleDependenciesModuleFactory();
index 22a3f105477fbc300739a579b17767a640660406..269555fc3dab19c7db76c1d9ec2aa9616f25a933 100644 (file)
@@ -23,8 +23,9 @@ import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
+import org.opendaylight.controller.config.facade.xml.mapping.attributes.fromxml.AttributeConfigElement;
+import org.opendaylight.controller.config.facade.xml.strategy.ReplaceEditConfigStrategy;
 import org.opendaylight.controller.config.util.ConfigTransactionClient;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
 
 public class ReplaceEditConfigStrategyTest {
 
diff --git a/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpcElementResolvedTest.java b/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpcElementResolvedTest.java
deleted file mode 100644 (file)
index 6ed2861..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.operations.runtimerpc;
-
-import static org.junit.Assert.assertEquals;
-import com.google.common.collect.ImmutableMap;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-@RunWith(Parameterized.class)
-public class RuntimeRpcElementResolvedTest {
-
-    private static final String MODULE_TYPE = "moduleType";
-    private static final String INSTANCE_NAME = "instanceName";
-    @Parameterized.Parameter(0)
-    public String xpath;
-    @Parameterized.Parameter(1)
-    public Map<String, String> additional;
-
-    @Parameterized.Parameters(name = "{index}: parsed({0}) contains moduleName:{1} and instanceName:{2}")
-    public static Collection<Object[]> data() {
-        return Arrays.asList(new Object[][] {
-            // With namespaces
-            { "/a:modules/a:module[a:name='instanceName'][a:type='moduleType']/b:listener-state[b:peer-id='127.0.0.1']",
-                new HashMap<>(ImmutableMap.of("listener-state", "127.0.0.1"))},
-            { "/a:modules/a:module[a:name='instanceName'][a:type='moduleType']",
-                null},
-
-            // Without namespaces
-            { "/modules/module[name=instanceName][type=moduleType]", null},
-            { "/modules/module[type=moduleType][name='instanceName']", null},
-            { "/modules/module[name=\'instanceName\'][type=\"moduleType\"]", null},
-            { "/modules/module[type=moduleType and name=instanceName]", null},
-            { "/modules/module[name=\"instanceName\" and type=moduleType]", null},
-            { "/modules/module[type=\"moduleType\" and name=instanceName]", null},
-            { "/modules/module[name=\'instanceName\' and type=\"moduleType\"]", null},
-
-            // With inner beans
-            { "/modules/module[name=instanceName and type=\"moduleType\"]/inner[key=b]", Collections.singletonMap("inner", "b")},
-            { "/modules/module[name=instanceName and type=moduleType]/inner[key=b]", Collections.singletonMap("inner", "b")},
-            { "/modules/module[name=instanceName and type=moduleType]/inner[key=\'b\']", Collections.singletonMap("inner", "b")},
-            { "/modules/module[name=instanceName and type=moduleType]/inner[key=\"b\"]", Collections.singletonMap("inner", "b")},
-
-            { "/modules/module[name=instanceName and type=\"moduleType\"]/inner[key2=a]/inner2[key=b]",
-                new HashMap<>(ImmutableMap.of("inner", "a", "inner2", "b"))
-            },
-        });
-    }
-
-    @Test
-    public void testFromXpath() throws Exception {
-        final RuntimeRpcElementResolved resolved = RuntimeRpcElementResolved.fromXpath(xpath, "element", "namespace");
-        assertEquals(MODULE_TYPE, resolved.getModuleName());
-        assertEquals(INSTANCE_NAME, resolved.getInstanceName());
-        if (additional != null) {
-            assertEquals(additional, resolved.getAdditionalAttributes());
-        }
-    }
-}
diff --git a/opendaylight/netconf/config-persister-impl/pom.xml b/opendaylight/netconf/config-persister-impl/pom.xml
deleted file mode 100644 (file)
index 5691e04..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-
-  <parent>
-    <groupId>org.opendaylight.controller</groupId>
-    <artifactId>netconf-subsystem</artifactId>
-    <version>0.4.0-SNAPSHOT</version>
-    <relativePath>../</relativePath>
-  </parent>
-  <artifactId>config-persister-impl</artifactId>
-  <packaging>bundle</packaging>
-  <name>${project.artifactId}</name>
-
-  <dependencies>
-    <dependency>
-      <groupId>${project.groupId}</groupId>
-      <artifactId>netconf-api</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>${project.groupId}</groupId>
-      <artifactId>netconf-util</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.google.guava</groupId>
-      <artifactId>guava</artifactId>
-    </dependency>
-    <!-- compile dependencies -->
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>config-persister-api</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.osgi</groupId>
-      <artifactId>org.osgi.core</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-api</artifactId>
-    </dependency>
-
-    <!-- test dependencies -->
-    <dependency>
-      <groupId>${project.groupId}</groupId>
-      <artifactId>netconf-impl</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>${project.groupId}</groupId>
-      <artifactId>netconf-util</artifactId>
-      <type>test-jar</type>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>config-persister-directory-xml-adapter</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>config-persister-file-xml-adapter</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.yangtools</groupId>
-      <artifactId>mockito-configuration</artifactId>
-      <scope>test</scope>
-    </dependency>
-  </dependencies>
-
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.felix</groupId>
-        <artifactId>maven-bundle-plugin</artifactId>
-        <configuration>
-          <instructions>
-            <Bundle-Activator>org.opendaylight.controller.netconf.persist.impl.osgi.ConfigPersisterActivator</Bundle-Activator>
-            <Require-Capability>org.opendaylight.controller.config.persister.storage.adapter</Require-Capability>
-            <Export-Package></Export-Package>
-          </instructions>
-        </configuration>
-      </plugin>
-    </plugins>
-  </build>
-</project>
diff --git a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/CapabilityStrippingConfigSnapshotHolder.java b/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/CapabilityStrippingConfigSnapshotHolder.java
deleted file mode 100644 (file)
index eac58cb..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.persist.impl;
-
-import com.google.common.annotations.VisibleForTesting;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.SortedSet;
-import java.util.TreeSet;
-import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Attr;
-import org.w3c.dom.Element;
-
-/**
- * Inspects snapshot xml to be stored, remove all capabilities that are not referenced by it.
- * Useful when persisting current configuration.
- */
-public class CapabilityStrippingConfigSnapshotHolder implements ConfigSnapshotHolder {
-    private static final Logger LOG = LoggerFactory.getLogger(CapabilityStrippingConfigSnapshotHolder.class);
-
-    private final String configSnapshot;
-    private final StripCapabilitiesResult stripCapabilitiesResult;
-
-    public CapabilityStrippingConfigSnapshotHolder(Element snapshot, Set<String> capabilities) {
-        final XmlElement configElement = XmlElement.fromDomElement(snapshot);
-        configSnapshot = XmlUtil.toString(configElement.getDomElement());
-        stripCapabilitiesResult = stripCapabilities(configElement, capabilities);
-    }
-
-    private static class StripCapabilitiesResult {
-        private final SortedSet<String> requiredCapabilities, obsoleteCapabilities;
-
-        private StripCapabilitiesResult(SortedSet<String> requiredCapabilities, SortedSet<String> obsoleteCapabilities) {
-            this.requiredCapabilities = Collections.unmodifiableSortedSet(requiredCapabilities);
-            this.obsoleteCapabilities = Collections.unmodifiableSortedSet(obsoleteCapabilities);
-        }
-    }
-
-
-    @VisibleForTesting
-    static StripCapabilitiesResult stripCapabilities(XmlElement configElement, Set<String> allCapabilitiesFromHello) {
-        // collect all namespaces
-        Set<String> foundNamespacesInXML = getNamespaces(configElement);
-        LOG.trace("All capabilities {}\nFound namespaces in XML {}", allCapabilitiesFromHello, foundNamespacesInXML);
-        // required are referenced both in xml and hello
-        SortedSet<String> requiredCapabilities = new TreeSet<>();
-        // can be removed
-        SortedSet<String> obsoleteCapabilities = new TreeSet<>();
-        for (String capability : allCapabilitiesFromHello) {
-            String namespace = capability.replaceAll("\\?.*","");
-            if (foundNamespacesInXML.contains(namespace)) {
-                requiredCapabilities.add(capability);
-            } else {
-                obsoleteCapabilities.add(capability);
-            }
-        }
-
-        LOG.trace("Required capabilities {}, \nObsolete capabilities {}",
-                requiredCapabilities, obsoleteCapabilities);
-
-        return new StripCapabilitiesResult(requiredCapabilities, obsoleteCapabilities);
-    }
-
-    static Set<String> getNamespaces(XmlElement element){
-        Set<String> result = new HashSet<>();
-        for (Entry<String,Attr> attribute : element.getAttributes().entrySet()) {
-            if  (attribute.getKey().startsWith("xmlns")){
-                result.add(attribute.getValue().getValue());
-            }
-        }
-        for(XmlElement child: element.getChildElements()) {
-            result.addAll(getNamespaces(child));
-        }
-        return result;
-    }
-
-    @Override
-    public SortedSet<String> getCapabilities() {
-        return stripCapabilitiesResult.requiredCapabilities;
-    }
-
-    @VisibleForTesting
-    Set<String> getObsoleteCapabilities(){
-        return stripCapabilitiesResult.obsoleteCapabilities;
-    }
-
-    @Override
-    public String getConfigSnapshot() {
-        return configSnapshot;
-    }
-}
diff --git a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/ConfigPersisterNotificationHandler.java b/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/ConfigPersisterNotificationHandler.java
deleted file mode 100644 (file)
index fe7b3da..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.persist.impl;
-
-import java.io.Closeable;
-import java.io.IOException;
-import javax.annotation.concurrent.ThreadSafe;
-import javax.management.InstanceNotFoundException;
-import javax.management.MBeanServerConnection;
-import javax.management.Notification;
-import javax.management.NotificationListener;
-import javax.management.ObjectName;
-import org.opendaylight.controller.config.persist.api.Persister;
-import org.opendaylight.controller.netconf.api.jmx.CommitJMXNotification;
-import org.opendaylight.controller.netconf.api.jmx.DefaultCommitOperationMXBean;
-import org.opendaylight.controller.netconf.api.jmx.NetconfJMXNotification;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Responsible for listening for notifications from netconf (via JMX) containing latest
- * committed configuration that should be persisted, and also for loading last
- * configuration.
- */
-@ThreadSafe
-public class ConfigPersisterNotificationHandler implements Closeable {
-
-    private static final Logger LOG = LoggerFactory.getLogger(ConfigPersisterNotificationHandler.class);
-    private final MBeanServerConnection mBeanServerConnection;
-    private final NotificationListener listener;
-
-
-    public ConfigPersisterNotificationHandler(final MBeanServerConnection mBeanServerConnection, final Persister persisterAggregator) {
-        this(mBeanServerConnection, new ConfigPersisterNotificationListener(persisterAggregator));
-    }
-
-    public ConfigPersisterNotificationHandler(final MBeanServerConnection mBeanServerConnection, final NotificationListener notificationListener) {
-        this.mBeanServerConnection = mBeanServerConnection;
-        this.listener = notificationListener;
-        registerAsJMXListener(mBeanServerConnection, listener);
-    }
-
-    private static void registerAsJMXListener(final MBeanServerConnection mBeanServerConnection, final NotificationListener listener) {
-        LOG.trace("Called registerAsJMXListener");
-        try {
-            mBeanServerConnection.addNotificationListener(DefaultCommitOperationMXBean.OBJECT_NAME, listener, null, null);
-        } catch (InstanceNotFoundException | IOException e) {
-            throw new IllegalStateException("Cannot register as JMX listener to netconf", e);
-        }
-    }
-
-    @Override
-    public synchronized void close() {
-        // unregister from JMX
-        final ObjectName on = DefaultCommitOperationMXBean.OBJECT_NAME;
-        try {
-            if (mBeanServerConnection.isRegistered(on)) {
-                mBeanServerConnection.removeNotificationListener(on, listener);
-            }
-        } catch (final Exception e) {
-            LOG.warn("Unable to unregister {} as listener for {}", listener, on, e);
-        }
-    }
-}
-
-class ConfigPersisterNotificationListener implements NotificationListener {
-    private static final Logger LOG = LoggerFactory.getLogger(ConfigPersisterNotificationListener.class);
-
-    private final Persister persisterAggregator;
-
-    ConfigPersisterNotificationListener(final Persister persisterAggregator) {
-        this.persisterAggregator = persisterAggregator;
-    }
-
-    @Override
-    public void handleNotification(final Notification notification, final Object handback) {
-        if (!(notification instanceof NetconfJMXNotification)) {
-            return;
-        }
-
-        // Socket should not be closed at this point
-        // Activator unregisters this as JMX listener before close is called
-
-        LOG.trace("Received notification {}", notification);
-        if (notification instanceof CommitJMXNotification) {
-            try {
-                handleAfterCommitNotification((CommitJMXNotification) notification);
-            } catch (final Exception e) {
-                // log exceptions from notification Handler here since
-                // notificationBroadcastSupport logs only DEBUG level
-                LOG.warn("Failed to handle notification {}", notification, e);
-                throw e;
-            }
-        } else {
-            throw new IllegalStateException("Unknown config registry notification type " + notification);
-        }
-    }
-
-    private void handleAfterCommitNotification(final CommitJMXNotification notification) {
-        try {
-            persisterAggregator.persistConfig(new CapabilityStrippingConfigSnapshotHolder(notification.getConfigSnapshot(),
-                    notification.getCapabilities()));
-            LOG.trace("Configuration persisted successfully");
-        } catch (final IOException e) {
-            throw new RuntimeException("Unable to persist configuration snapshot", e);
-        }
-    }
-}
diff --git a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/ConfigPusherImpl.java b/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/ConfigPusherImpl.java
deleted file mode 100644 (file)
index c41a2f4..0000000
+++ /dev/null
@@ -1,410 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.persist.impl;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.google.common.base.Function;
-import com.google.common.base.Stopwatch;
-import com.google.common.collect.Collections2;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.SortedSet;
-import java.util.TreeMap;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.TimeUnit;
-import javax.annotation.Nonnull;
-import javax.annotation.concurrent.Immutable;
-import javax.management.MBeanServerConnection;
-import org.opendaylight.controller.config.api.ConflictingVersionException;
-import org.opendaylight.controller.config.persist.api.ConfigPusher;
-import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
-import org.opendaylight.controller.config.persist.api.Persister;
-import org.opendaylight.controller.netconf.api.Capability;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.mapping.api.HandlingPriority;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperation;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationChainedExecution;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactory;
-import org.opendaylight.controller.netconf.util.NetconfUtil;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.xml.sax.SAXException;
-
-@Immutable
-public class ConfigPusherImpl implements ConfigPusher {
-    private static final Logger LOG = LoggerFactory.getLogger(ConfigPusherImpl.class);
-
-    private final long maxWaitForCapabilitiesMillis;
-    private final long conflictingVersionTimeoutMillis;
-    private final NetconfOperationServiceFactory configNetconfConnector;
-    private static final int QUEUE_SIZE = 100;
-    private BlockingQueue<List<? extends ConfigSnapshotHolder>> queue = new LinkedBlockingQueue<List<? extends ConfigSnapshotHolder>>(QUEUE_SIZE);
-
-    public ConfigPusherImpl(NetconfOperationServiceFactory configNetconfConnector, long maxWaitForCapabilitiesMillis,
-                        long conflictingVersionTimeoutMillis) {
-        this.configNetconfConnector = configNetconfConnector;
-        this.maxWaitForCapabilitiesMillis = maxWaitForCapabilitiesMillis;
-        this.conflictingVersionTimeoutMillis = conflictingVersionTimeoutMillis;
-    }
-
-    public void process(List<AutoCloseable> autoCloseables, MBeanServerConnection platformMBeanServer, Persister persisterAggregator) throws InterruptedException {
-        List<? extends ConfigSnapshotHolder> configs;
-        while(true) {
-            configs = queue.take();
-            try {
-                internalPushConfigs(configs);
-                ConfigPersisterNotificationHandler jmxNotificationHandler = new ConfigPersisterNotificationHandler(platformMBeanServer, persisterAggregator);
-                synchronized (autoCloseables) {
-                    autoCloseables.add(jmxNotificationHandler);
-                }
-
-                LOG.debug("ConfigPusher has pushed configs {}", configs);
-            } catch (NetconfDocumentedException e) {
-                LOG.error("Error pushing configs {}",configs);
-                throw new IllegalStateException(e);
-            }
-        }
-    }
-
-    public void pushConfigs(List<? extends ConfigSnapshotHolder> configs) throws InterruptedException {
-        LOG.debug("Requested to push configs {}", configs);
-        this.queue.put(configs);
-    }
-
-    private LinkedHashMap<? extends ConfigSnapshotHolder, EditAndCommitResponse> internalPushConfigs(List<? extends ConfigSnapshotHolder> configs) throws NetconfDocumentedException {
-        LOG.debug("Last config snapshots to be pushed to netconf: {}", configs);
-        LinkedHashMap<ConfigSnapshotHolder, EditAndCommitResponse> result = new LinkedHashMap<>();
-        // start pushing snapshots:
-        for (ConfigSnapshotHolder configSnapshotHolder : configs) {
-            if(configSnapshotHolder != null) {
-                EditAndCommitResponse editAndCommitResponseWithRetries = null;
-                try {
-                    editAndCommitResponseWithRetries = pushConfigWithConflictingVersionRetries(configSnapshotHolder);
-                } catch (ConfigSnapshotFailureException e) {
-                    LOG.warn("Failed to apply configuration snapshot: {}. Config snapshot is not semantically correct and will be IGNORED. " +
-                            "for detailed information see enclosed exception.", e.getConfigIdForReporting(), e);
-                    throw new IllegalStateException("Failed to apply configuration snapshot " + e.getConfigIdForReporting(), e);
-                }
-                LOG.debug("Config snapshot pushed successfully: {}, result: {}", configSnapshotHolder, result);
-                result.put(configSnapshotHolder, editAndCommitResponseWithRetries);
-            }
-        }
-        LOG.debug("All configuration snapshots have been pushed successfully.");
-        return result;
-    }
-
-    /**
-     * First calls {@link #getOperationServiceWithRetries(java.util.Set, String)} in order to wait until
-     * expected capabilities are present, then tries to push configuration. If {@link ConflictingVersionException}
-     * is caught, whole process is retried - new service instance need to be obtained from the factory. Closes
-     * {@link NetconfOperationService} after each use.
-     */
-    private synchronized EditAndCommitResponse pushConfigWithConflictingVersionRetries(ConfigSnapshotHolder configSnapshotHolder) throws ConfigSnapshotFailureException {
-        ConflictingVersionException lastException;
-        Stopwatch stopwatch = Stopwatch.createUnstarted();
-        do {
-            String idForReporting = configSnapshotHolder.toString();
-            SortedSet<String> expectedCapabilities = checkNotNull(configSnapshotHolder.getCapabilities(),
-                    "Expected capabilities must not be null - %s, check %s", idForReporting,
-                    configSnapshotHolder.getClass().getName());
-            try (NetconfOperationService operationService = getOperationServiceWithRetries(expectedCapabilities, idForReporting)) {
-                if(!stopwatch.isRunning()) {
-                    stopwatch.start();
-                }
-                return pushConfig(configSnapshotHolder, operationService);
-            } catch (ConflictingVersionException e) {
-                lastException = e;
-                LOG.info("Conflicting version detected, will retry after timeout");
-                sleep();
-            }
-        } while (stopwatch.elapsed(TimeUnit.MILLISECONDS) < conflictingVersionTimeoutMillis);
-        throw new IllegalStateException("Max wait for conflicting version stabilization timeout after " + stopwatch.elapsed(TimeUnit.MILLISECONDS) + " ms",
-                lastException);
-    }
-
-    private NetconfOperationService getOperationServiceWithRetries(Set<String> expectedCapabilities, String idForReporting) {
-        Stopwatch stopwatch = Stopwatch.createStarted();
-        ConfigPusherException lastException;
-        do {
-            try {
-                return getOperationService(expectedCapabilities, idForReporting);
-            } catch (ConfigPusherException e) {
-                LOG.debug("Not enough capabilities: {}", e.toString());
-                lastException = e;
-                sleep();
-            }
-        } while (stopwatch.elapsed(TimeUnit.MILLISECONDS) < maxWaitForCapabilitiesMillis);
-
-        if(lastException instanceof NotEnoughCapabilitiesException) {
-            LOG.error("Unable to push configuration due to missing yang models." +
-                            " Yang models that are missing, but required by the configuration: {}." +
-                            " For each mentioned model check: " +
-                            " 1. that the mentioned yang model namespace/name/revision is identical to those in the yang model itself" +
-                            " 2. the yang file is present in the system" +
-                            " 3. the bundle with that yang file is present in the system and active" +
-                            " 4. the yang parser did not fail while attempting to parse that model",
-                    ((NotEnoughCapabilitiesException) lastException).getMissingCaps());
-            throw new IllegalStateException("Unable to push configuration due to missing yang models." +
-                    " Required yang models that are missing: "
-                    + ((NotEnoughCapabilitiesException) lastException).getMissingCaps(), lastException);
-        } else {
-            final String msg = "Unable to push configuration due to missing netconf service";
-            LOG.error(msg, lastException);
-            throw new IllegalStateException(msg, lastException);
-        }
-    }
-
-    private static class ConfigPusherException extends Exception {
-
-        public ConfigPusherException(final String message) {
-            super(message);
-        }
-
-        public ConfigPusherException(final String message, final Throwable cause) {
-            super(message, cause);
-        }
-    }
-
-    private static class NotEnoughCapabilitiesException extends ConfigPusherException {
-        private static final long serialVersionUID = 1L;
-        private Set<String> missingCaps;
-
-        private NotEnoughCapabilitiesException(String message, Set<String> missingCaps) {
-            super(message);
-            this.missingCaps = missingCaps;
-        }
-
-        public Set<String> getMissingCaps() {
-            return missingCaps;
-        }
-    }
-
-    private static final class NetconfServiceNotAvailableException extends ConfigPusherException {
-
-        public NetconfServiceNotAvailableException(final String s, final RuntimeException e) {
-            super(s, e);
-        }
-    }
-
-    private static final class ConfigSnapshotFailureException extends ConfigPusherException {
-
-        private final String configIdForReporting;
-
-        public ConfigSnapshotFailureException(final String configIdForReporting, final String operationNameForReporting, final Exception e) {
-            super(String.format("Failed to apply config snapshot: %s during phase: %s", configIdForReporting, operationNameForReporting), e);
-            this.configIdForReporting = configIdForReporting;
-        }
-
-        public String getConfigIdForReporting() {
-            return configIdForReporting;
-        }
-    }
-
-    /**
-     * Get NetconfOperationService iif all required capabilities are present.
-     *
-     * @param expectedCapabilities that must be provided by configNetconfConnector
-     * @param idForReporting
-     * @return service if capabilities are present, otherwise absent value
-     */
-    private NetconfOperationService getOperationService(Set<String> expectedCapabilities, String idForReporting) throws ConfigPusherException {
-        NetconfOperationService serviceCandidate;
-        try {
-            serviceCandidate = configNetconfConnector.createService(idForReporting);
-        } catch(RuntimeException e) {
-            throw new NetconfServiceNotAvailableException("Netconf service not stable for config pusher." +
-                    " Cannot push any configuration", e);
-        }
-        Set<String> notFoundDiff = computeNotFoundCapabilities(expectedCapabilities, configNetconfConnector);
-        if (notFoundDiff.isEmpty()) {
-            return serviceCandidate;
-        } else {
-            serviceCandidate.close();
-            LOG.debug("Netconf server did not provide required capabilities for {} ", idForReporting,
-                    "Expected but not found: {}, all expected {}, current {}",
-                     notFoundDiff, expectedCapabilities, configNetconfConnector.getCapabilities()
-            );
-            throw new NotEnoughCapabilitiesException("Not enough capabilities for " + idForReporting + ". Expected but not found: " + notFoundDiff, notFoundDiff);
-        }
-    }
-
-    private static Set<String> computeNotFoundCapabilities(Set<String> expectedCapabilities, NetconfOperationServiceFactory serviceCandidate) {
-        Collection<String> actual = Collections2.transform(serviceCandidate.getCapabilities(), new Function<Capability, String>() {
-            @Override
-            public String apply(@Nonnull final Capability input) {
-                return input.getCapabilityUri();
-            }
-        });
-        Set<String> allNotFound = new HashSet<>(expectedCapabilities);
-        allNotFound.removeAll(actual);
-        return allNotFound;
-    }
-
-    private void sleep() {
-        try {
-            Thread.sleep(100);
-        } catch (InterruptedException e) {
-            Thread.currentThread().interrupt();
-            throw new IllegalStateException(e);
-        }
-    }
-
-    /**
-     * Sends two RPCs to the netconf server: edit-config and commit.
-     *
-     * @param configSnapshotHolder
-     * @throws ConflictingVersionException if commit fails on optimistic lock failure inside of config-manager
-     * @throws java.lang.RuntimeException  if edit-config or commit fails otherwise
-     */
-    private synchronized EditAndCommitResponse pushConfig(ConfigSnapshotHolder configSnapshotHolder, NetconfOperationService operationService)
-            throws ConflictingVersionException, ConfigSnapshotFailureException {
-
-        Element xmlToBePersisted;
-        try {
-            xmlToBePersisted = XmlUtil.readXmlToElement(configSnapshotHolder.getConfigSnapshot());
-        } catch (SAXException | IOException e) {
-            throw new IllegalStateException("Cannot parse " + configSnapshotHolder);
-        }
-        LOG.trace("Pushing last configuration to netconf: {}", configSnapshotHolder);
-        Stopwatch stopwatch = Stopwatch.createStarted();
-        NetconfMessage editConfigMessage = createEditConfigMessage(xmlToBePersisted);
-
-        Document editResponseMessage = sendRequestGetResponseCheckIsOK(editConfigMessage, operationService,
-                "edit-config", configSnapshotHolder.toString());
-
-        Document commitResponseMessage = sendRequestGetResponseCheckIsOK(getCommitMessage(), operationService,
-                "commit", configSnapshotHolder.toString());
-
-        if (LOG.isTraceEnabled()) {
-            StringBuilder response = new StringBuilder("editConfig response = {");
-            response.append(XmlUtil.toString(editResponseMessage));
-            response.append("}");
-            response.append("commit response = {");
-            response.append(XmlUtil.toString(commitResponseMessage));
-            response.append("}");
-            LOG.trace("Last configuration loaded successfully");
-            LOG.trace("Detailed message {}", response);
-            LOG.trace("Total time spent {} ms", stopwatch.elapsed(TimeUnit.MILLISECONDS));
-        }
-        return new EditAndCommitResponse(editResponseMessage, commitResponseMessage);
-    }
-
-    private NetconfOperation findOperation(NetconfMessage request, NetconfOperationService operationService) {
-        TreeMap<HandlingPriority, NetconfOperation> allOperations = new TreeMap<>();
-        Set<NetconfOperation> netconfOperations = operationService.getNetconfOperations();
-        if (netconfOperations.isEmpty()) {
-            throw new IllegalStateException("Possible code error: no config operations");
-        }
-        for (NetconfOperation netconfOperation : netconfOperations) {
-            HandlingPriority handlingPriority = null;
-            try {
-                handlingPriority = netconfOperation.canHandle(request.getDocument());
-            } catch (NetconfDocumentedException e) {
-                throw new IllegalStateException("Possible code error: canHandle threw exception", e);
-            }
-            allOperations.put(handlingPriority, netconfOperation);
-        }
-        Entry<HandlingPriority, NetconfOperation> highestEntry = allOperations.lastEntry();
-        if (highestEntry.getKey().isCannotHandle()) {
-            throw new IllegalStateException("Possible code error: operation with highest priority is CANNOT_HANDLE");
-        }
-        return highestEntry.getValue();
-    }
-
-    private Document sendRequestGetResponseCheckIsOK(NetconfMessage request, NetconfOperationService operationService,
-                                                     String operationNameForReporting, String configIdForReporting)
-            throws ConflictingVersionException, ConfigSnapshotFailureException {
-
-        NetconfOperation operation = findOperation(request, operationService);
-        Document response;
-        try {
-            response = operation.handle(request.getDocument(), NetconfOperationChainedExecution.EXECUTION_TERMINATION_POINT);
-            return NetconfUtil.checkIsMessageOk(response);
-        } catch (NetconfDocumentedException e) {
-            if (e.getCause() instanceof ConflictingVersionException) {
-                throw (ConflictingVersionException) e.getCause();
-            }
-            throw new ConfigSnapshotFailureException(configIdForReporting, operationNameForReporting, e);
-        }
-    }
-
-    // load editConfig.xml template, populate /rpc/edit-config/config with parameter
-    private static NetconfMessage createEditConfigMessage(Element dataElement) {
-        String editConfigResourcePath = "/netconfOp/editConfig.xml";
-        try (InputStream stream = ConfigPersisterNotificationHandler.class.getResourceAsStream(editConfigResourcePath)) {
-            checkNotNull(stream, "Unable to load resource " + editConfigResourcePath);
-
-            Document doc = XmlUtil.readXmlToDocument(stream);
-
-            XmlElement editConfigElement = XmlElement.fromDomDocument(doc).getOnlyChildElement();
-            XmlElement configWrapper = editConfigElement.getOnlyChildElement(XmlNetconfConstants.CONFIG_KEY);
-            editConfigElement.getDomElement().removeChild(configWrapper.getDomElement());
-            for (XmlElement el : XmlElement.fromDomElement(dataElement).getChildElements()) {
-                boolean deep = true;
-                configWrapper.appendChild((Element) doc.importNode(el.getDomElement(), deep));
-            }
-            editConfigElement.appendChild(configWrapper.getDomElement());
-            return new NetconfMessage(doc);
-        } catch (IOException | SAXException | NetconfDocumentedException e) {
-            // error reading the xml file bundled into the jar
-            throw new IllegalStateException("Error while opening local resource " + editConfigResourcePath, e);
-        }
-    }
-
-    private static NetconfMessage getCommitMessage() {
-        String resource = "/netconfOp/commit.xml";
-        try (InputStream stream = ConfigPusherImpl.class.getResourceAsStream(resource)) {
-            checkNotNull(stream, "Unable to load resource " + resource);
-            return new NetconfMessage(XmlUtil.readXmlToDocument(stream));
-        } catch (SAXException | IOException e) {
-            // error reading the xml file bundled into the jar
-            throw new IllegalStateException("Error while opening local resource " + resource, e);
-        }
-    }
-
-    static class EditAndCommitResponse {
-        private final Document editResponse, commitResponse;
-
-        EditAndCommitResponse(Document editResponse, Document commitResponse) {
-            this.editResponse = editResponse;
-            this.commitResponse = commitResponse;
-        }
-
-        public Document getEditResponse() {
-            return editResponse;
-        }
-
-        public Document getCommitResponse() {
-            return commitResponse;
-        }
-
-        @Override
-        public String toString() {
-            return "EditAndCommitResponse{" +
-                    "editResponse=" + editResponse +
-                    ", commitResponse=" + commitResponse +
-                    '}';
-        }
-    }
-}
diff --git a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/NoOpStorageAdapter.java b/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/NoOpStorageAdapter.java
deleted file mode 100644 (file)
index 26e4973..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.persist.impl;
-
-import java.io.IOException;
-import java.util.Collections;
-import java.util.List;
-import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
-import org.opendaylight.controller.config.persist.api.Persister;
-import org.opendaylight.controller.config.persist.api.PropertiesProvider;
-import org.opendaylight.controller.config.persist.api.StorageAdapter;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class NoOpStorageAdapter implements StorageAdapter, Persister {
-    private static final Logger LOG = LoggerFactory.getLogger(NoOpStorageAdapter.class);
-
-    @Override
-    public Persister instantiate(PropertiesProvider propertiesProvider) {
-        LOG.debug("instantiate called with {}", propertiesProvider);
-        return this;
-    }
-
-    @Override
-    public void persistConfig(ConfigSnapshotHolder holder) throws IOException {
-        LOG.debug("persistConfig called with {}", holder);
-    }
-
-    @Override
-    public List<ConfigSnapshotHolder> loadLastConfigs() throws IOException {
-        LOG.debug("loadLastConfig called");
-        return Collections.emptyList();
-    }
-
-    @Override
-    public void close() {
-        LOG.debug("close called");
-    }
-}
diff --git a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/PersisterAggregator.java b/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/PersisterAggregator.java
deleted file mode 100644 (file)
index 0c51166..0000000
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.persist.impl;
-
-import com.google.common.annotations.VisibleForTesting;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.ListIterator;
-import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
-import org.opendaylight.controller.config.persist.api.Persister;
-import org.opendaylight.controller.config.persist.api.PropertiesProvider;
-import org.opendaylight.controller.config.persist.api.StorageAdapter;
-import org.opendaylight.controller.netconf.persist.impl.osgi.ConfigPersisterActivator;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * {@link Persister} implementation that delegates persisting functionality to
- * underlying {@link Persister} storages. Each storage has unique id, class, readonly value.
- *
- * Storage adapters are low level persisters that do the heavy lifting for this
- * class. Instances of storage adapters can be injected directly via constructor
- * or instantiated from a full name of its class provided in a properties file.
- *
- * Example configuration:<pre>
- netconf.config.persister.active=2,3
- # read startup configuration
- netconf.config.persister.1.storageAdapterClass=org.opendaylight.controller.config.persist.storage.directory.xml.XmlDirectoryStorageAdapter
- netconf.config.persister.1.properties.fileStorage=configuration/initial/
-
- netconf.config.persister.2.storageAdapterClass=org.opendaylight.controller.config.persist.storage.file.xml.XmlFileStorageAdapter
- netconf.config.persister.2.readonly=true
- netconf.config.persister.2.properties.fileStorage=configuration/current/controller.config.1.xml
-
- netconf.config.persister.3.storageAdapterClass=org.opendaylight.controller.config.persist.storage.file.xml.XmlFileStorageAdapter
- netconf.config.persister.3.properties.fileStorage=configuration/current/controller.config.2.xml
- netconf.config.persister.3.properties.numberOfBackups=3
-
- </pre>
- * During server startup {@link ConfigPersisterNotificationHandler} requests last snapshot from underlying storages.
- * Each storage can respond by giving snapshot or absent response.
- * The {@link #loadLastConfigs()} will search for first non-absent response from storages ordered backwards as user
- * specified (first '3', then '2').
- *
- * When a commit notification is received, '2' will be omitted because readonly flag is set to true, so
- * only '3' will have a chance to persist new configuration. If readonly was false or not specified, both storage adapters
- * would be called in order specified by 'netconf.config.persister' property.
- *
- */
-public final class PersisterAggregator implements Persister {
-    private static final Logger LOG = LoggerFactory.getLogger(PersisterAggregator.class);
-
-    public static class PersisterWithConfiguration {
-
-        private final Persister storage;
-        private final boolean readOnly;
-
-        public PersisterWithConfiguration(Persister storage, boolean readOnly) {
-            this.storage = storage;
-            this.readOnly = readOnly;
-        }
-
-        @VisibleForTesting
-        public Persister getStorage() {
-            return storage;
-        }
-
-        @VisibleForTesting
-        public boolean isReadOnly() {
-            return readOnly;
-        }
-
-        @Override
-        public String toString() {
-            return "PersisterWithConfiguration{" +
-                    "storage=" + storage +
-                    ", readOnly=" + readOnly +
-                    '}';
-        }
-    }
-
-    private static PersisterWithConfiguration loadConfiguration(final String index, final PropertiesProvider propertiesProvider) {
-
-        String classKey = index + "." + ConfigPersisterActivator.STORAGE_ADAPTER_CLASS_PROP_SUFFIX;
-        String storageAdapterClass = propertiesProvider.getProperty(classKey);
-        StorageAdapter storageAdapter;
-        if (storageAdapterClass == null || storageAdapterClass.equals("")) {
-            throw new IllegalStateException("No persister is defined in " +
-                    propertiesProvider.getFullKeyForReporting(classKey)
-                    + " property. Persister is not operational");
-        }
-
-        try {
-            Class<?> clazz = Class.forName(storageAdapterClass);
-            boolean implementsCorrectIfc = StorageAdapter.class.isAssignableFrom(clazz);
-            if (!implementsCorrectIfc) {
-                throw new IllegalArgumentException("Storage adapter " + clazz + " does not implement " + StorageAdapter.class);
-            }
-            storageAdapter = StorageAdapter.class.cast(clazz.newInstance());
-
-            boolean readOnly = false;
-            String readOnlyProperty = propertiesProvider.getProperty(index + "." + "readonly");
-            if (readOnlyProperty != null && readOnlyProperty.equals("true")) {
-                readOnly = true;
-            }
-
-            PropertiesProviderAdapterImpl innerProvider = new PropertiesProviderAdapterImpl(propertiesProvider, index);
-            Persister storage = storageAdapter.instantiate(innerProvider);
-            return new PersisterWithConfiguration(storage, readOnly);
-        } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
-            throw new IllegalArgumentException("Unable to instantiate storage adapter from " + storageAdapterClass, e);
-        }
-    }
-
-    /**
-     * Persisters ordered by 'netconf.config.persister' property.
-     */
-    private final List<PersisterWithConfiguration> persisterWithConfigurations;
-
-    public PersisterAggregator(List<PersisterWithConfiguration> persisterWithConfigurations) {
-        this.persisterWithConfigurations = persisterWithConfigurations;
-
-    }
-
-    public static PersisterAggregator createFromProperties(PropertiesProvider propertiesProvider) {
-        List<PersisterWithConfiguration> persisterWithConfigurations = new ArrayList<>();
-        String prefixes = propertiesProvider.getProperty("active");
-        if (prefixes!=null && !prefixes.isEmpty()) {
-            String [] keys = prefixes.split(",");
-            for (String index: keys) {
-                persisterWithConfigurations.add(PersisterAggregator.loadConfiguration(index, propertiesProvider));
-            }
-        }
-        LOG.debug("Initialized persister with following adapters {}", persisterWithConfigurations);
-        return new PersisterAggregator(persisterWithConfigurations);
-    }
-
-    @Override
-    public void persistConfig(ConfigSnapshotHolder holder) throws IOException {
-        for (PersisterWithConfiguration persisterWithConfiguration: persisterWithConfigurations){
-            if (!persisterWithConfiguration.readOnly){
-                LOG.debug("Calling {}.persistConfig", persisterWithConfiguration.getStorage());
-                persisterWithConfiguration.getStorage().persistConfig(holder);
-            }
-        }
-    }
-
-    /**
-     * @return last non-empty result from input persisters
-     */
-    @Override
-    public List<ConfigSnapshotHolder> loadLastConfigs()  {
-        // iterate in reverse order
-        ListIterator<PersisterWithConfiguration> li = persisterWithConfigurations.listIterator(persisterWithConfigurations.size());
-        while(li.hasPrevious()) {
-            PersisterWithConfiguration persisterWithConfiguration = li.previous();
-            List<ConfigSnapshotHolder> configs = null;
-            try {
-                configs = persisterWithConfiguration.storage.loadLastConfigs();
-            } catch (IOException e) {
-                throw new RuntimeException("Error while calling loadLastConfig on " +  persisterWithConfiguration, e);
-            }
-            if (!configs.isEmpty()) {
-                LOG.debug("Found non empty configs using {}:{}", persisterWithConfiguration, configs);
-                return configs;
-            }
-        }
-        // no storage had an answer
-        LOG.debug("No non-empty list of configuration snapshots found");
-        return Collections.emptyList();
-    }
-
-    @VisibleForTesting
-    List<PersisterWithConfiguration> getPersisterWithConfigurations() {
-        return persisterWithConfigurations;
-    }
-
-    @Override
-    public void close() {
-        RuntimeException lastException = null;
-        for (PersisterWithConfiguration persisterWithConfiguration: persisterWithConfigurations){
-            try{
-                persisterWithConfiguration.storage.close();
-            }catch(RuntimeException e) {
-                LOG.error("Error while closing {}", persisterWithConfiguration.storage, e);
-                if (lastException == null){
-                    lastException = e;
-                } else {
-                    lastException.addSuppressed(e);
-                }
-            }
-        }
-        if (lastException != null){
-            throw lastException;
-        }
-    }
-
-    @Override
-    public String toString() {
-        return "PersisterAggregator{" +
-                "persisterWithConfigurations=" + persisterWithConfigurations +
-                '}';
-    }
-}
diff --git a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/PropertiesProviderAdapterImpl.java b/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/PropertiesProviderAdapterImpl.java
deleted file mode 100644 (file)
index 238661f..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.persist.impl;
-
-import org.opendaylight.controller.config.persist.api.PropertiesProvider;
-
-public class PropertiesProviderAdapterImpl implements PropertiesProvider {
-    private final PropertiesProvider inner;
-    private final String index;
-
-    public PropertiesProviderAdapterImpl(PropertiesProvider inner, String index) {
-        this.inner = inner;
-        this.index = index;
-    }
-
-    @Override
-    public String getProperty(String key) {
-        String fullKey = getFullKeyForReporting(key);
-        return inner.getPropertyWithoutPrefix(fullKey);
-    }
-
-    public String getPrefix() {
-        return inner.getPrefix() + "." + index + ".properties";
-    }
-
-    @Override
-    public String getPropertyWithoutPrefix(String fullKey) {
-        return inner.getPropertyWithoutPrefix(fullKey);
-    }
-
-
-    @Override
-    public String getFullKeyForReporting(String key) {
-        return getPrefix()  + "." + key;
-    }
-}
diff --git a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/osgi/ConfigPersisterActivator.java b/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/osgi/ConfigPersisterActivator.java
deleted file mode 100644 (file)
index b27bec3..0000000
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.persist.impl.osgi;
-
-import com.google.common.annotations.VisibleForTesting;
-import java.lang.management.ManagementFactory;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-import javax.management.MBeanServer;
-import org.opendaylight.controller.config.persist.api.ConfigPusher;
-import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactory;
-import org.opendaylight.controller.netconf.persist.impl.ConfigPusherImpl;
-import org.opendaylight.controller.netconf.persist.impl.PersisterAggregator;
-import org.opendaylight.controller.netconf.util.CloseableUtil;
-import org.osgi.framework.BundleActivator;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.Filter;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.ServiceRegistration;
-import org.osgi.util.tracker.ServiceTracker;
-import org.osgi.util.tracker.ServiceTrackerCustomizer;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ConfigPersisterActivator implements BundleActivator {
-
-    private static final Logger LOG = LoggerFactory.getLogger(ConfigPersisterActivator.class);
-    private static final MBeanServer platformMBeanServer = ManagementFactory.getPlatformMBeanServer();
-
-    public static final String MAX_WAIT_FOR_CAPABILITIES_MILLIS_PROPERTY = "maxWaitForCapabilitiesMillis";
-    private static final long MAX_WAIT_FOR_CAPABILITIES_MILLIS_DEFAULT = TimeUnit.MINUTES.toMillis(2);
-    public static final String CONFLICTING_VERSION_TIMEOUT_MILLIS_PROPERTY = "conflictingVersionTimeoutMillis";
-    private static final long CONFLICTING_VERSION_TIMEOUT_MILLIS_DEFAULT = TimeUnit.MINUTES.toMillis(1);
-
-    public static final String NETCONF_CONFIG_PERSISTER = "netconf.config.persister";
-
-    public static final String STORAGE_ADAPTER_CLASS_PROP_SUFFIX = "storageAdapterClass";
-
-    private List<AutoCloseable> autoCloseables;
-    private volatile BundleContext context;
-
-    ServiceRegistration<?> registration;
-
-    @Override
-    public void start(final BundleContext context) throws Exception {
-        LOG.debug("ConfigPersister starting");
-        this.context = context;
-
-        autoCloseables = new ArrayList<>();
-        PropertiesProviderBaseImpl propertiesProvider = new PropertiesProviderBaseImpl(context);
-
-        final PersisterAggregator persisterAggregator = PersisterAggregator.createFromProperties(propertiesProvider);
-        autoCloseables.add(persisterAggregator);
-        long maxWaitForCapabilitiesMillis = getMaxWaitForCapabilitiesMillis(propertiesProvider);
-        List<ConfigSnapshotHolder> configs = persisterAggregator.loadLastConfigs();
-        long conflictingVersionTimeoutMillis = getConflictingVersionTimeoutMillis(propertiesProvider);
-        LOG.debug("Following configs will be pushed: {}", configs);
-
-        InnerCustomizer innerCustomizer = new InnerCustomizer(configs, maxWaitForCapabilitiesMillis,
-                conflictingVersionTimeoutMillis, persisterAggregator);
-        OuterCustomizer outerCustomizer = new OuterCustomizer(context, innerCustomizer);
-        new ServiceTracker<>(context, NetconfOperationServiceFactory.class, outerCustomizer).open();
-    }
-
-    private long getConflictingVersionTimeoutMillis(PropertiesProviderBaseImpl propertiesProvider) {
-        String timeoutProperty = propertiesProvider.getProperty(CONFLICTING_VERSION_TIMEOUT_MILLIS_PROPERTY);
-        return timeoutProperty == null ? CONFLICTING_VERSION_TIMEOUT_MILLIS_DEFAULT : Long.valueOf(timeoutProperty);
-    }
-
-    private long getMaxWaitForCapabilitiesMillis(PropertiesProviderBaseImpl propertiesProvider) {
-        String timeoutProperty = propertiesProvider.getProperty(MAX_WAIT_FOR_CAPABILITIES_MILLIS_PROPERTY);
-        return timeoutProperty == null ? MAX_WAIT_FOR_CAPABILITIES_MILLIS_DEFAULT : Long.valueOf(timeoutProperty);
-    }
-
-    @Override
-    public void stop(BundleContext context) throws Exception {
-        synchronized(autoCloseables) {
-            CloseableUtil.closeAll(autoCloseables);
-            if (registration != null) {
-                registration.unregister();
-            }
-            this.context = null;
-        }
-    }
-
-
-    @VisibleForTesting
-    public static String getFilterString() {
-        return "(&" +
-                "(" + Constants.OBJECTCLASS + "=" + NetconfOperationServiceFactory.class.getName() + ")" +
-                "(name" + "=" + "config-netconf-connector" + ")" +
-                ")";
-    }
-
-    class OuterCustomizer implements ServiceTrackerCustomizer<NetconfOperationServiceFactory, NetconfOperationServiceFactory> {
-        private final BundleContext context;
-        private final InnerCustomizer innerCustomizer;
-
-        OuterCustomizer(BundleContext context, InnerCustomizer innerCustomizer) {
-            this.context = context;
-            this.innerCustomizer = innerCustomizer;
-        }
-
-        @Override
-        public NetconfOperationServiceFactory addingService(ServiceReference<NetconfOperationServiceFactory> reference) {
-            LOG.trace("Got OuterCustomizer.addingService {}", reference);
-            // JMX was registered, track config-netconf-connector
-            Filter filter;
-            try {
-                filter = context.createFilter(getFilterString());
-            } catch (InvalidSyntaxException e) {
-                throw new IllegalStateException(e);
-            }
-            new ServiceTracker<>(context, filter, innerCustomizer).open();
-            return null;
-        }
-
-        @Override
-        public void modifiedService(ServiceReference<NetconfOperationServiceFactory> reference, NetconfOperationServiceFactory service) {
-
-        }
-
-        @Override
-        public void removedService(ServiceReference<NetconfOperationServiceFactory> reference, NetconfOperationServiceFactory service) {
-
-        }
-    }
-
-    class InnerCustomizer implements ServiceTrackerCustomizer<NetconfOperationServiceFactory, NetconfOperationServiceFactory> {
-        private final List<ConfigSnapshotHolder> configs;
-        private final PersisterAggregator persisterAggregator;
-        private final long maxWaitForCapabilitiesMillis, conflictingVersionTimeoutMillis;
-        // This inner customizer has its filter to find the right operation service, but it gets triggered after any
-        // operation service appears. This means that it could start pushing thread up to N times (N = number of operation services spawned in OSGi)
-        private final AtomicBoolean alreadyStarted = new AtomicBoolean(false);
-
-        InnerCustomizer(List<ConfigSnapshotHolder> configs, long maxWaitForCapabilitiesMillis, long conflictingVersionTimeoutMillis,
-                        PersisterAggregator persisterAggregator) {
-            this.configs = configs;
-            this.maxWaitForCapabilitiesMillis = maxWaitForCapabilitiesMillis;
-            this.conflictingVersionTimeoutMillis = conflictingVersionTimeoutMillis;
-            this.persisterAggregator = persisterAggregator;
-        }
-
-        @Override
-        public NetconfOperationServiceFactory addingService(ServiceReference<NetconfOperationServiceFactory> reference) {
-            if(alreadyStarted.compareAndSet(false, true) == false) {
-                //Prevents multiple calls to this method spawning multiple pushing threads
-                return reference.getBundle().getBundleContext().getService(reference);
-            }
-            LOG.trace("Got InnerCustomizer.addingService {}", reference);
-            NetconfOperationServiceFactory service = reference.getBundle().getBundleContext().getService(reference);
-
-            LOG.debug("Creating new job queue");
-
-            final ConfigPusherImpl configPusher = new ConfigPusherImpl(service, maxWaitForCapabilitiesMillis, conflictingVersionTimeoutMillis);
-            LOG.debug("Configuration Persister got {}", service);
-            LOG.debug("Context was {}", context);
-            LOG.debug("Registration was {}", registration);
-
-            final Thread pushingThread = new Thread(new Runnable() {
-                @Override
-                public void run() {
-                    try {
-                        if(configs != null && !configs.isEmpty()) {
-                            configPusher.pushConfigs(configs);
-                        }
-                        if(context != null) {
-                            registration = context.registerService(ConfigPusher.class.getName(), configPusher, null);
-                            configPusher.process(autoCloseables, platformMBeanServer, persisterAggregator);
-                        } else {
-                            LOG.warn("Unable to process configs as BundleContext is null");
-                        }
-                    } catch (InterruptedException e) {
-                        LOG.info("ConfigPusher thread stopped",e);
-                    }
-                    LOG.info("Configuration Persister initialization completed.");
-                }
-            }, "config-pusher");
-            synchronized (autoCloseables) {
-                autoCloseables.add(new AutoCloseable() {
-                    @Override
-                    public void close() {
-                        pushingThread.interrupt();
-                    }
-                });
-            }
-            pushingThread.start();
-            return service;
-        }
-
-        @Override
-        public void modifiedService(ServiceReference<NetconfOperationServiceFactory> reference, NetconfOperationServiceFactory service) {
-            LOG.trace("Got InnerCustomizer.modifiedService {}", reference);
-        }
-
-        @Override
-        public void removedService(ServiceReference<NetconfOperationServiceFactory> reference, NetconfOperationServiceFactory service) {
-            LOG.trace("Got InnerCustomizer.removedService {}", reference);
-        }
-
-    }
-}
-
diff --git a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/osgi/PropertiesProviderBaseImpl.java b/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/osgi/PropertiesProviderBaseImpl.java
deleted file mode 100644 (file)
index d73f3b8..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.persist.impl.osgi;
-
-import org.opendaylight.controller.config.persist.api.PropertiesProvider;
-import org.osgi.framework.BundleContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class PropertiesProviderBaseImpl implements PropertiesProvider {
-
-    private static final Logger LOG = LoggerFactory.getLogger(PropertiesProviderBaseImpl.class);
-    private final BundleContext bundleContext;
-
-    public PropertiesProviderBaseImpl(BundleContext bundleContext) {
-        this.bundleContext = bundleContext;
-    }
-
-    @Override
-    public String getProperty(String key) {
-        String fullKey = getFullKeyForReporting(key);
-        return getPropertyWithoutPrefix(fullKey);
-    }
-
-    public String getPropertyWithoutPrefix(String fullKey){
-        LOG.trace("Full key {}", fullKey);
-        return bundleContext.getProperty(fullKey);
-    }
-
-    public String getPrefix(){
-        return ConfigPersisterActivator.NETCONF_CONFIG_PERSISTER;
-    }
-
-    @Override
-    public String getFullKeyForReporting(String key) {
-        return getPrefix() + "." + key;
-    }
-}
diff --git a/opendaylight/netconf/config-persister-impl/src/main/resources/netconfOp/client_hello.xml b/opendaylight/netconf/config-persister-impl/src/main/resources/netconfOp/client_hello.xml
deleted file mode 100644 (file)
index b1f7833..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-    <hello xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
-        <capabilities>
-            <capability>urn:ietf:params:netconf:base:1.0</capability>
-        </capabilities>
-    </hello>
diff --git a/opendaylight/netconf/config-persister-impl/src/main/resources/netconfOp/commit.xml b/opendaylight/netconf/config-persister-impl/src/main/resources/netconfOp/commit.xml
deleted file mode 100644 (file)
index ae1f6e8..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="persister_commit" notify="false">
-    <commit></commit>
-</rpc>
\ No newline at end of file
diff --git a/opendaylight/netconf/config-persister-impl/src/main/resources/netconfOp/editConfig.xml b/opendaylight/netconf/config-persister-impl/src/main/resources/netconfOp/editConfig.xml
deleted file mode 100644 (file)
index 8f6ec9c..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="persister_edit">
-    <edit-config>
-        <target>
-            <candidate/>
-        </target>
-        <default-operation>merge</default-operation>
-
-        <config>
-        </config>
-
-    </edit-config>
-</rpc>
\ No newline at end of file
diff --git a/opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/CapabilityStrippingConfigSnapshotHolderTest.java b/opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/CapabilityStrippingConfigSnapshotHolderTest.java
deleted file mode 100644 (file)
index 554e134..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.persist.impl;
-
-import static org.junit.Assert.assertEquals;
-import com.google.common.base.Charsets;
-import com.google.common.collect.Sets;
-import com.google.common.io.Resources;
-import java.io.IOException;
-import java.util.HashSet;
-import java.util.Set;
-import org.junit.Test;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
-import org.w3c.dom.Element;
-
-public class CapabilityStrippingConfigSnapshotHolderTest {
-
-    @Test
-    public void testCapabilityStripping() throws Exception {
-        Set<String> allCapabilities = readLines("/capabilities-all.txt");
-        Set<String> expectedCapabilities = readLines("/capabilities-stripped.txt");
-        String snapshotAsString = readToString("/snapshot.xml");
-        Element element = XmlUtil.readXmlToElement(snapshotAsString);
-        CapabilityStrippingConfigSnapshotHolder tested = new CapabilityStrippingConfigSnapshotHolder(
-                element, allCapabilities);
-        assertEquals(expectedCapabilities, tested.getCapabilities());
-
-        Set<String> obsoleteCapabilities = Sets.difference(allCapabilities, expectedCapabilities);
-
-        assertEquals(obsoleteCapabilities, tested.getObsoleteCapabilities());
-    }
-
-    private Set<String> readLines(String fileName) throws IOException {
-        return new HashSet<>(Resources.readLines(getClass().getResource(fileName), Charsets.UTF_8));
-    }
-
-    private String readToString(String fileName) throws IOException {
-        return Resources.toString(getClass().getResource(fileName), Charsets.UTF_8);
-    }
-
-}
diff --git a/opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/ConfigPersisterNotificationHandlerTest.java b/opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/ConfigPersisterNotificationHandlerTest.java
deleted file mode 100644 (file)
index e96b547..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.persist.impl;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyObject;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import javax.management.MBeanServerConnection;
-import javax.management.NotificationFilter;
-import javax.management.NotificationListener;
-import javax.management.ObjectName;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.opendaylight.controller.config.persist.api.Persister;
-
-public class ConfigPersisterNotificationHandlerTest {
-
-    @Mock
-    private MBeanServerConnection mBeanServer;
-    @Mock
-    private Persister notificationListener;
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-        doNothing().when(mBeanServer).addNotificationListener(any(ObjectName.class), any(NotificationListener.class),
-                any(NotificationFilter.class), anyObject());
-    }
-
-    @Test
-    public void testNotificationHandler() throws Exception {
-        doReturn(true).when(mBeanServer).isRegistered(any(ObjectName.class));
-        doThrow(Exception.class).when(mBeanServer).removeNotificationListener(any(ObjectName.class), any(NotificationListener.class));
-
-        final ConfigPersisterNotificationHandler testedHandler = new ConfigPersisterNotificationHandler(mBeanServer, notificationListener);
-        verify(mBeanServer).addNotificationListener(any(ObjectName.class), any(NotificationListener.class),
-                any(NotificationFilter.class), anyObject());
-
-        testedHandler.close();
-        verify(mBeanServer).removeNotificationListener(any(ObjectName.class), any(NotificationListener.class));
-    }
-
-    @Test
-    public void testNotificationHandlerCloseNotRegistered() throws Exception {
-        doReturn(false).when(mBeanServer).isRegistered(any(ObjectName.class));
-
-        final ConfigPersisterNotificationHandler testedHandler = new ConfigPersisterNotificationHandler(mBeanServer, notificationListener);
-
-        testedHandler.close();
-        verify(mBeanServer, times(0)).removeNotificationListener(any(ObjectName.class), any(NotificationListener.class));
-    }
-}
diff --git a/opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/ConfigPersisterNotificationListenerTest.java b/opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/ConfigPersisterNotificationListenerTest.java
deleted file mode 100644 (file)
index f0cd267..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.persist.impl;
-
-import com.google.common.collect.Lists;
-import java.util.Collections;
-import javax.management.Notification;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Matchers;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
-import org.opendaylight.controller.config.persist.api.Persister;
-import org.opendaylight.controller.netconf.api.jmx.CommitJMXNotification;
-import org.opendaylight.controller.netconf.api.jmx.NetconfJMXNotification;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
-
-public class ConfigPersisterNotificationListenerTest {
-
-    @Mock
-    private Persister mockPersister;
-    private PersisterAggregator persisterAggregator;
-
-    @Mock
-    private NetconfJMXNotification unknownNetconfNotif;
-    @Mock
-    private CommitJMXNotification commitNetconfNotif;
-    @Mock
-    private Notification unknownNotif;
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-
-        Mockito.doNothing().when(mockPersister).persistConfig(Matchers.any(ConfigSnapshotHolder.class));
-        Mockito.doReturn("persister").when(mockPersister).toString();
-        final PersisterAggregator.PersisterWithConfiguration withCfg = new PersisterAggregator.PersisterWithConfiguration(mockPersister, false);
-        persisterAggregator = new PersisterAggregator(Lists.newArrayList(withCfg));
-
-        Mockito.doReturn("netconfUnknownNotification").when(unknownNetconfNotif).toString();
-        Mockito.doReturn("netconfCommitNotification").when(commitNetconfNotif).toString();
-
-        Mockito.doReturn(XmlUtil.readXmlToElement("<config-snapshot/>")).when(commitNetconfNotif).getConfigSnapshot();
-        Mockito.doReturn(Collections.emptySet()).when(commitNetconfNotif).getCapabilities();
-
-    }
-
-    @Test
-    public void testNotificationListenerUnknownNotification() throws Exception {
-        final ConfigPersisterNotificationListener testeListener = new ConfigPersisterNotificationListener(persisterAggregator);
-        testeListener.handleNotification(unknownNotif, null);
-        Mockito.verifyZeroInteractions(mockPersister);
-    }
-
-    @Test
-    public void testNotificationListenerUnknownNetconfNotification() throws Exception {
-        final ConfigPersisterNotificationListener testeListener = new ConfigPersisterNotificationListener(persisterAggregator);
-        try {
-            testeListener.handleNotification(unknownNetconfNotif, null);
-            Assert.fail("Unknown netconf notification should fail");
-        } catch (final IllegalStateException e) {
-            Mockito.verifyZeroInteractions(mockPersister);
-        }
-    }
-
-    @Test
-    public void testNotificationListenerCommitNetconfNotification() throws Exception {
-        final ConfigPersisterNotificationListener testeListener = new ConfigPersisterNotificationListener(persisterAggregator);
-        testeListener.handleNotification(commitNetconfNotif, null);
-        Mockito.verify(mockPersister).persistConfig(Matchers.any(ConfigSnapshotHolder.class));
-    }
-}
diff --git a/opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/DummyAdapter.java b/opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/DummyAdapter.java
deleted file mode 100644 (file)
index 792f8cd..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.persist.impl;
-
-import java.io.IOException;
-import java.util.Collections;
-import java.util.List;
-import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
-import org.opendaylight.controller.config.persist.api.Persister;
-import org.opendaylight.controller.config.persist.api.PropertiesProvider;
-import org.opendaylight.controller.config.persist.api.StorageAdapter;
-
-public class DummyAdapter implements StorageAdapter, Persister {
-
-    static int persist = 0;
-
-    @Override
-    public void persistConfig(ConfigSnapshotHolder holder) throws IOException {
-        persist++;
-    }
-
-    static int load = 0;
-
-    @Override
-    public List<ConfigSnapshotHolder> loadLastConfigs() throws IOException {
-        load++;
-        return Collections.emptyList();
-    }
-
-    static int props = 0;
-
-    @Override
-    public Persister instantiate(PropertiesProvider propertiesProvider) {
-        props++;
-        return this;
-    }
-
-    @Override
-    public void close() {
-    }
-
-}
diff --git a/opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/PersisterAggregatorTest.java b/opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/PersisterAggregatorTest.java
deleted file mode 100644 (file)
index c962a46..0000000
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.persist.impl;
-
-import static org.hamcrest.CoreMatchers.containsString;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.fail;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.opendaylight.controller.netconf.persist.impl.PersisterAggregator.PersisterWithConfiguration;
-
-import com.google.common.collect.Lists;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Properties;
-import org.junit.Before;
-import org.junit.Test;
-import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
-import org.opendaylight.controller.config.persist.api.Persister;
-import org.opendaylight.controller.config.persist.storage.file.xml.XmlFileStorageAdapter;
-import org.opendaylight.controller.netconf.persist.impl.osgi.ConfigPersisterActivator;
-import org.opendaylight.controller.netconf.persist.impl.osgi.PropertiesProviderBaseImpl;
-
-public class PersisterAggregatorTest {
-
-    static class TestingPropertiesProvider extends PropertiesProviderBaseImpl {
-
-        private final Properties prop;
-
-        public TestingPropertiesProvider(Properties prop) {
-            super(null);
-            this.prop = prop;
-        }
-
-        public static TestingPropertiesProvider loadFile(String fileName) {
-            Properties prop = new Properties();
-            try {
-                prop.load(TestingPropertiesProvider.class.getClassLoader().getResourceAsStream(fileName));
-            } catch (IOException e) {
-                throw new RuntimeException(e);
-            }
-            return new TestingPropertiesProvider(prop);
-        }
-
-        @Override
-        public String getFullKeyForReporting(String key) {
-            return ConfigPersisterActivator.NETCONF_CONFIG_PERSISTER + "." + key;
-        }
-
-        @Override
-        public String getProperty(String key) {
-            return prop.getProperty(getFullKeyForReporting(key));
-        }
-
-        @Override
-        public String getPropertyWithoutPrefix(String fullKey){
-            return prop.getProperty(fullKey);
-        }
-    }
-
-    @Before
-    public void setUp() throws Exception {
-        if(XmlFileStorageAdapter.getInstance().isPresent()) {
-            XmlFileStorageAdapter.getInstance().get().reset();
-        }
-    }
-
-    @Test
-    public void testDummyAdapter() throws Exception {
-        PersisterAggregator persisterAggregator = PersisterAggregator.createFromProperties(TestingPropertiesProvider.loadFile("test1.properties"));
-        List<PersisterWithConfiguration> persisters = persisterAggregator.getPersisterWithConfigurations();
-        assertEquals(1, persisters.size());
-        PersisterWithConfiguration persister = persisters.get(0);
-        assertEquals(DummyAdapter.class.getName(), persister.getStorage().getClass().getName());
-        assertFalse(persister.isReadOnly());
-
-        persisterAggregator.persistConfig(null);
-        persisterAggregator.loadLastConfigs();
-        persisterAggregator.persistConfig(null);
-        persisterAggregator.loadLastConfigs();
-
-        assertEquals(2, DummyAdapter.persist);
-        assertEquals(2, DummyAdapter.load);
-        assertEquals(1, DummyAdapter.props);
-    }
-
-    @Test
-    public void testNoopAdapter() throws Exception {
-        final NoOpStorageAdapter noOpStorageAdapter = new NoOpStorageAdapter();
-        final PersisterAggregator persisterAggregator =
-                new PersisterAggregator(Lists.newArrayList(new PersisterWithConfiguration(noOpStorageAdapter, false)));
-
-        noOpStorageAdapter.instantiate(null);
-
-        persisterAggregator.persistConfig(null);
-        persisterAggregator.loadLastConfigs();
-        persisterAggregator.persistConfig(null);
-        persisterAggregator.loadLastConfigs();
-
-        noOpStorageAdapter.close();
-    }
-
-    @Test
-    public void testLoadFromPropertyFile() throws Exception {
-        PersisterAggregator persisterAggregator = PersisterAggregator.createFromProperties(TestingPropertiesProvider.loadFile("test2.properties"));
-        List<PersisterWithConfiguration> persisters = persisterAggregator.getPersisterWithConfigurations();
-        assertEquals(1, persisters.size());
-        PersisterWithConfiguration persister = persisters.get(0);
-        assertEquals(XmlFileStorageAdapter.class.getName() ,persister.getStorage().getClass().getName());
-        assertFalse(persister.isReadOnly());
-    }
-
-    @Test
-    public void testFileStorageNumberOfBackups() throws Exception {
-        try {
-            PersisterAggregator.createFromProperties(TestingPropertiesProvider.loadFile("test3.properties"));
-            fail();
-        } catch (RuntimeException e) {
-            assertThat(
-                    e.getMessage(),
-                    containsString("numberOfBackups property should be either set to positive value, or ommited. Can not be set to 0."));
-        }
-    }
-
-    private ConfigSnapshotHolder mockHolder(String name){
-        ConfigSnapshotHolder result = mock(ConfigSnapshotHolder.class);
-        doReturn("mock:" + name).when(result).toString();
-        return result;
-    }
-
-    private Persister mockPersister(String name){
-        Persister result = mock(Persister.class);
-        doReturn("mock:" + name).when(result).toString();
-        return result;
-    }
-
-    @Test
-    public void loadLastConfig() throws Exception {
-        List<PersisterWithConfiguration> persisterWithConfigurations = new ArrayList<>();
-        PersisterWithConfiguration first = new PersisterWithConfiguration(mock(Persister.class), false);
-
-        ConfigSnapshotHolder ignored = mockHolder("ignored");
-        doReturn(Arrays.asList(ignored)).when(first.getStorage()).loadLastConfigs(); // should be ignored
-
-
-        ConfigSnapshotHolder used = mockHolder("used");
-        PersisterWithConfiguration second = new PersisterWithConfiguration(mockPersister("p1"), false);
-        doReturn(Arrays.asList(used)).when(second.getStorage()).loadLastConfigs(); // should be used
-
-        PersisterWithConfiguration third = new PersisterWithConfiguration(mockPersister("p2"), false);
-        doReturn(Arrays.asList()).when(third.getStorage()).loadLastConfigs();
-
-        persisterWithConfigurations.add(first);
-        persisterWithConfigurations.add(second);
-        persisterWithConfigurations.add(third);
-
-        PersisterAggregator persisterAggregator = new PersisterAggregator(persisterWithConfigurations);
-        List<ConfigSnapshotHolder> configSnapshotHolderOptional = persisterAggregator.loadLastConfigs();
-        assertEquals(1, configSnapshotHolderOptional.size());
-        assertEquals(used, configSnapshotHolderOptional.get(0));
-    }
-}
diff --git a/opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/osgi/ConfigPersisterTest.java b/opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/osgi/ConfigPersisterTest.java
deleted file mode 100644 (file)
index b998b9e..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.persist.impl.osgi;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
-import com.google.common.collect.Sets;
-import java.io.IOException;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.opendaylight.controller.config.api.ConflictingVersionException;
-import org.opendaylight.controller.netconf.api.Capability;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.mapping.api.HandlingPriority;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperation;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationChainedExecution;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService;
-import org.opendaylight.controller.netconf.persist.impl.osgi.MockedBundleContext.DummyAdapterWithInitialSnapshot;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.xml.sax.SAXException;
-
-public class ConfigPersisterTest {
-    private static final Logger LOG = LoggerFactory.getLogger(ConfigPersisterTest.class);
-
-    private MockedBundleContext ctx;
-    private ConfigPersisterActivator configPersisterActivator;
-    private TestingExceptionHandler handler;
-
-    private void setUpContext(String requiredCapability) throws Exception {
-        DummyAdapterWithInitialSnapshot.expectedCapability = requiredCapability;
-        ctx = new MockedBundleContext(1000, 1000);
-        configPersisterActivator = new ConfigPersisterActivator();
-    }
-
-    private void setUpContextAndStartPersister(String requiredCapability, final NetconfOperationService conflictingService) throws Exception {
-        setUpContext(requiredCapability);
-        doReturn(conflictingService).when(ctx.serviceFactory).createService(anyString());
-        configPersisterActivator.start(ctx.getBundleContext());
-    }
-
-    @Before
-    public void setUp() {
-        handler = new TestingExceptionHandler();
-        Thread.setDefaultUncaughtExceptionHandler(handler);
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        Thread.setDefaultUncaughtExceptionHandler(null);
-        configPersisterActivator.stop(ctx.getBundleContext());
-    }
-
-    @Test
-    public void testPersisterNotAllCapabilitiesProvided() throws Exception {
-        setUpContextAndStartPersister("required-cap", getConflictingService());
-        Thread.sleep(2000);
-        handler.assertException(IllegalStateException.class, "Required yang models that are missing: [required-cap]");
-
-    }
-
-    @Test
-    public void testPersisterSuccessfulPush() throws Exception {
-        setUpContextAndStartPersister("cap1", getWorkingService(getOKDocument()));
-        Thread.sleep(2000);
-        assertCannotRegisterAsJMXListener_pushWasSuccessful();
-    }
-
-    // this means pushing of config was successful
-    public void assertCannotRegisterAsJMXListener_pushWasSuccessful() {
-        handler.assertException(IllegalStateException.class, "Cannot register as JMX listener to netconf");
-    }
-
-    public NetconfOperationService getWorkingService(Document document) throws SAXException, IOException, NetconfDocumentedException {
-        NetconfOperationService service = mock(NetconfOperationService.class);
-        Capability capability = mock(Capability.class);
-//        doReturn(Sets.newHashSet(capability)).when(service).getCapabilities();
-        doReturn("cap1").when(capability).getCapabilityUri();
-
-
-        NetconfOperation mockedOperation = mock(NetconfOperation.class);
-        doReturn(Sets.newHashSet(mockedOperation)).when(service).getNetconfOperations();
-        doReturn(HandlingPriority.getHandlingPriority(1)).when(mockedOperation).canHandle(any(Document.class));
-        doReturn(document).when(mockedOperation).handle(any(Document.class), any(NetconfOperationChainedExecution.class));
-        doNothing().when(service).close();
-        return service;
-    }
-
-    private Document getOKDocument() throws SAXException, IOException {
-        return XmlUtil.readXmlToDocument(
-                "<rpc-reply message-id=\"1\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n" +
-                        "<ok/>\n" +
-                        "</rpc-reply>"
-        );
-    }
-
-
-    @Test
-    public void testPersisterConflictingVersionException() throws Exception {
-        setUpContextAndStartPersister("cap1", getConflictingService());
-
-        Thread.sleep(2000);
-        handler.assertException(IllegalStateException.class, "Max wait for conflicting version stabilization timeout");
-    }
-
-    private NetconfOperationService getConflictingService() throws Exception {
-        NetconfOperationService service =  getWorkingService(getOKDocument());
-        ConflictingVersionException cve = new ConflictingVersionException("");
-        try {
-            NetconfDocumentedException.wrap(cve);
-            throw new AssertionError("Should throw an exception");
-        }catch(NetconfDocumentedException e) {
-            NetconfOperation mockedOperation = service.getNetconfOperations().iterator().next();
-            doThrow(e).when(mockedOperation).handle(any(Document.class), any(NetconfOperationChainedExecution.class));
-            return service;
-        }
-    }
-
-    @Test
-    public void testSuccessConflictingVersionException() throws Exception {
-        LOG.info("testSuccessConflictingVersionException starting");
-
-        setUpContext("cap1");
-
-        NetconfOperationService conflictingService = getConflictingService();
-        NetconfOperationService workingService = getWorkingService(getOKDocument());
-
-        doReturn(conflictingService).doReturn(conflictingService).doReturn(conflictingService).
-            doReturn(workingService).when(ctx.serviceFactory).createService(anyString());
-
-        configPersisterActivator.start(ctx.getBundleContext());
-
-        Thread.sleep(1000);
-        assertCannotRegisterAsJMXListener_pushWasSuccessful();
-    }
-
-}
diff --git a/opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/osgi/MockedBundleContext.java b/opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/osgi/MockedBundleContext.java
deleted file mode 100644 (file)
index bd18c8c..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.persist.impl.osgi;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-import java.io.Closeable;
-import java.io.IOException;
-import java.util.Collections;
-import java.util.Dictionary;
-import java.util.List;
-import java.util.SortedSet;
-import java.util.TreeSet;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.opendaylight.controller.config.persist.api.ConfigPusher;
-import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
-import org.opendaylight.controller.config.persist.api.Persister;
-import org.opendaylight.controller.config.persist.api.PropertiesProvider;
-import org.opendaylight.controller.netconf.api.Capability;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactory;
-import org.opendaylight.controller.netconf.persist.impl.DummyAdapter;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Filter;
-import org.osgi.framework.ServiceListener;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.ServiceRegistration;
-
-final class MockedBundleContext {
-    @Mock
-    private BundleContext context;
-    @Mock
-    private Filter outerFilter, innerFilter;
-    @Mock
-    private ServiceReference<?> serviceReference;
-    @Mock
-    private Bundle bundle;
-    @Mock
-    NetconfOperationServiceFactory serviceFactory;
-    @Mock
-    private NetconfOperationService service;
-    @Mock
-    private ServiceRegistration<?> registration;
-
-    MockedBundleContext(long maxWaitForCapabilitiesMillis, long conflictingVersionTimeoutMillis) throws Exception {
-        MockitoAnnotations.initMocks(this);
-        doReturn(null).when(context).getProperty(anyString());
-        initContext(maxWaitForCapabilitiesMillis, conflictingVersionTimeoutMillis);
-
-        String outerFilterString = "(objectClass=org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactory)";
-        doReturn(outerFilter).when(context).createFilter(outerFilterString);
-        doNothing().when(context).addServiceListener(any(ServiceListener.class), eq(outerFilterString));
-        ServiceReference<?>[] toBeReturned = {serviceReference};
-        doReturn(toBeReturned).when(context).getServiceReferences(NetconfOperationServiceFactory.class.getName(), null);
-
-        String innerFilterString = "innerfilter";
-        doReturn(innerFilterString).when(outerFilter).toString();
-
-        doReturn(innerFilter).when(context).createFilter(ConfigPersisterActivator.getFilterString());
-        doReturn(innerFilterString).when(innerFilter).toString();
-        doNothing().when(context).addServiceListener(any(ServiceListener.class), eq(innerFilterString));
-
-        doReturn(toBeReturned).when(context).getServiceReferences((String) null, innerFilterString);
-        doReturn(bundle).when(serviceReference).getBundle();
-        doReturn(context).when(bundle).getBundleContext();
-        doReturn("").when(serviceReference).toString();
-        doReturn("context").when(context).toString();
-        doReturn(serviceFactory).when(context).getService(any(ServiceReference.class));
-        doReturn(service).when(serviceFactory).createService(anyString());
-        final Capability cap = mock(Capability.class);
-        doReturn("cap1").when(cap).getCapabilityUri();
-        doReturn(Collections.singleton(cap)).when(serviceFactory).getCapabilities();
-        doNothing().when(service).close();
-        doReturn("serviceFactoryMock").when(serviceFactory).toString();
-
-        doNothing().when(registration).unregister();
-        doReturn(registration).when(context).registerService(
-                eq(ConfigPusher.class.getName()), any(Closeable.class),
-                any(Dictionary.class));
-    }
-
-    public BundleContext getBundleContext() {
-        return context;
-    }
-
-    private void initContext(long maxWaitForCapabilitiesMillis, long conflictingVersionTimeoutMillis) {
-        initProp(context, "active", "1");
-        initProp(context, "1." + ConfigPersisterActivator.STORAGE_ADAPTER_CLASS_PROP_SUFFIX, DummyAdapterWithInitialSnapshot.class.getName());
-        initProp(context, "1." + "readonly", "false");
-        initProp(context, "1." + ".properties.fileStorage", "target/configuration-persister-test/initial/");
-        initProp(context, ConfigPersisterActivator.MAX_WAIT_FOR_CAPABILITIES_MILLIS_PROPERTY, String.valueOf(maxWaitForCapabilitiesMillis));
-        initProp(context, ConfigPersisterActivator.CONFLICTING_VERSION_TIMEOUT_MILLIS_PROPERTY, String.valueOf(conflictingVersionTimeoutMillis));
-    }
-
-    private void initProp(BundleContext context, String key, String value) {
-        initPropNoPrefix(context, ConfigPersisterActivator.NETCONF_CONFIG_PERSISTER + "." + key, value);
-    }
-
-    private void initPropNoPrefix(BundleContext context, String key, String value) {
-        doReturn(value).when(context).getProperty(key);
-    }
-
-    public static class DummyAdapterWithInitialSnapshot extends DummyAdapter {
-
-        public static final String CONFIG_SNAPSHOT = "config-snapshot";
-        public static String expectedCapability = "cap2";
-
-        @Override
-        public List<ConfigSnapshotHolder> loadLastConfigs() throws IOException {
-            return Lists.newArrayList(getConfigSnapshot());
-        }
-
-        @Override
-        public Persister instantiate(PropertiesProvider propertiesProvider) {
-            return this;
-        }
-
-        public ConfigSnapshotHolder getConfigSnapshot() {
-            return new ConfigSnapshotHolder() {
-                @Override
-                public String getConfigSnapshot() {
-                    return "<data><" + CONFIG_SNAPSHOT + "/></data>";
-                }
-
-                @Override
-                public SortedSet<String> getCapabilities() {
-                    TreeSet<String> strings = Sets.newTreeSet();
-                    strings.add(expectedCapability);
-                    return strings;
-                }
-
-                @Override
-                public String toString() {
-                    return getConfigSnapshot();
-                }
-            };
-        }
-    }
-}
diff --git a/opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/osgi/TestingExceptionHandler.java b/opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/osgi/TestingExceptionHandler.java
deleted file mode 100644 (file)
index fcd39d6..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.persist.impl.osgi;
-
-import static org.hamcrest.CoreMatchers.containsString;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.fail;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-final class TestingExceptionHandler implements Thread.UncaughtExceptionHandler {
-
-    private static final Logger LOG = LoggerFactory.getLogger(TestingExceptionHandler.class);
-
-    private Throwable t;
-
-    @Override
-    public void uncaughtException(Thread t, Throwable e) {
-        LOG.debug("Uncaught exception in thread {}", t, e);
-        this.t = e;
-    }
-
-    public void assertException(Class<? extends Exception> exType, String exMessageToContain) {
-        assertException(exMessageToContain, exType, exMessageToContain);
-    }
-
-    public void assertException(String failMessageSuffix, Class<? extends Exception> exType, String exMessageToContain) {
-        if(t == null) {
-            fail("Should fail to " + failMessageSuffix);
-        }
-        else {
-            assertException(t, exType, exMessageToContain);
-        }
-    }
-
-    public void assertNoException() {
-        assertNull("No exception expected but was " + t, t);
-    }
-
-    private void assertException(Throwable t, Class<? extends Exception> exType, String exMessageToContain) {
-        assertEquals("Expected exception of type " + exType + " but was " + t, exType, t.getClass());
-        if(exMessageToContain!=null) {
-            assertThat(t.getMessage(), containsString(exMessageToContain));
-        }
-    }
-
-    public void assertException(String failMessageSuffix, Class<? extends Exception> exType,
-            String exMessageToContain, Class<? extends Exception> nestedExType, String nestedExMessageToContain,
-            int nestedExDepth) {
-        assertException(failMessageSuffix, exType, exMessageToContain);
-        assertNotNull("Expected nested exception in " + t, t.getCause());
-        assertException(getNestedException(t, nestedExDepth), nestedExType, nestedExMessageToContain);
-    }
-
-    private Throwable getNestedException(Throwable t, int nestedExDepth) {
-
-        int depth = 0;
-        while(t.getCause() != null) {
-            t = t.getCause();
-            depth++;
-            if(nestedExDepth == depth)
-                return t;
-        }
-        throw new IllegalArgumentException("Unable to get nested exception from " + t + " from depth " + nestedExDepth);
-    }
-}
diff --git a/opendaylight/netconf/config-persister-impl/src/test/resources/capabilities-all.txt b/opendaylight/netconf/config-persister-impl/src/test/resources/capabilities-all.txt
deleted file mode 100644 (file)
index 84c85b7..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-urn:opendaylight:l2:types?module=opendaylight-l2-types&revision=2013-08-27
-urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding?module=opendaylight-md-sal-binding&revision=2013-10-28
-urn:opendaylight:params:xml:ns:yang:controller:threadpool?module=threadpool&revision=2013-04-09
-urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom?module=opendaylight-md-sal-dom&revision=2013-10-28
-urn:opendaylight:params:xml:ns:yang:controller:config?module=config&revision=2013-04-05
-urn:ietf:params:netconf:capability:candidate:1.0
-urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring?module=ietf-netconf-monitoring&revision=2010-10-04
-urn:opendaylight:params:xml:ns:yang:controller:netty:eventexecutor?module=netty-event-executor&revision=2013-11-12
-urn:ietf:params:xml:ns:yang:rpc-context?module=rpc-context&revision=2013-06-17
-urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl?module=opendaylight-sal-binding-broker-impl&revision=2013-10-28
-urn:ietf:params:xml:ns:yang:ietf-inet-types?module=ietf-inet-types&revision=2010-09-24
-urn:ietf:params:netconf:capability:rollback-on-error:1.0
-urn:ietf:params:xml:ns:yang:ietf-yang-types?module=ietf-yang-types&revision=2010-09-24
-urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl?module=threadpool-impl&revision=2013-04-05
-urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl?module=opendaylight-sal-dom-broker-impl&revision=2013-10-28
-urn:opendaylight:params:xml:ns:yang:controller:logback:config?module=config-logging&revision=2013-07-16
-urn:opendaylight:yang:extension:yang-ext?module=yang-ext&revision=2013-07-09
-urn:opendaylight:params:xml:ns:yang:iana?module=iana&revision=2013-08-16
-urn:opendaylight:params:xml:ns:yang:controller:md:sal:common?module=opendaylight-md-sal-common&revision=2013-10-28
-urn:opendaylight:params:xml:ns:yang:ieee754?module=ieee754&revision=2013-08-19
diff --git a/opendaylight/netconf/config-persister-impl/src/test/resources/capabilities-stripped.txt b/opendaylight/netconf/config-persister-impl/src/test/resources/capabilities-stripped.txt
deleted file mode 100644 (file)
index 4a0b7ff..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding?module=opendaylight-md-sal-binding&revision=2013-10-28
-urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom?module=opendaylight-md-sal-dom&revision=2013-10-28
-urn:opendaylight:params:xml:ns:yang:controller:config?module=config&revision=2013-04-05
-urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl?module=opendaylight-sal-binding-broker-impl&revision=2013-10-28
-urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl?module=opendaylight-sal-dom-broker-impl&revision=2013-10-28
diff --git a/opendaylight/netconf/config-persister-impl/src/test/resources/logback-test.xml b/opendaylight/netconf/config-persister-impl/src/test/resources/logback-test.xml
deleted file mode 100644 (file)
index a4ff3ab..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-<configuration scan="true">
-
-    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
-        <encoder>
-            <pattern>%date{"yyyy-MM-dd HH:mm:ss.SSS z"} [%thread] %-5level %logger{36} - %msg%n</pattern>
-        </encoder>
-    </appender>
-
-    <root level="error">
-        <appender-ref ref="STDOUT" />
-    </root>
-    <logger name="org.opendaylight.controller.netconf.persist.impl" level="TRACE"/>
-</configuration>
diff --git a/opendaylight/netconf/config-persister-impl/src/test/resources/snapshot.xml b/opendaylight/netconf/config-persister-impl/src/test/resources/snapshot.xml
deleted file mode 100644 (file)
index a6a57d7..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-<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:md:sal:dom:impl">prefix:schema-service-singleton</type>
-            <name>yang-schema-service</name>
-        </module>
-        <module>
-            <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:hash-map-data-store</type>
-            <name>hash-map-data-store</name>
-        </module>
-        <module>
-            <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:dom-broker-impl</type>
-            <name>dom-broker</name>
-            <data-store xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">
-                <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-data-store</type>
-                <name>ref_hash-map-data-store</name>
-            </data-store>
-        </module>
-        <module>
-            <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-broker-impl</type>
-            <name>binding-broker-impl</name>
-            <notification-service xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
-                <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-notification-service</type>
-                <name>ref_binding-notification-broker</name>
-            </notification-service>
-            <data-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
-                <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-data-broker</type>
-                <name>ref_binding-data-broker</name>
-            </data-broker>
-        </module>
-        <module>
-            <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:runtime-generated-mapping</type>
-            <name>runtime-mapping-singleton</name>
-        </module>
-        <module>
-            <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-notification-broker</type>
-            <name>binding-notification-broker</name>
-        </module>
-        <module>
-            <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-data-broker</type>
-            <name>binding-data-broker</name>
-            <dom-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
-                <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-broker-osgi-registry</type>
-                <name>ref_dom-broker</name>
-            </dom-broker>
-            <mapping-service xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
-                <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">binding:binding-dom-mapping-service</type>
-                <name>ref_runtime-mapping-singleton</name>
-            </mapping-service>
-        </module>
-    </modules>
-    <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
-        <service>
-            <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:schema-service</type>
-            <instance>
-                <name>ref_yang-schema-service</name>
-                <provider>/config/modules/module[name='schema-service-singleton']/instance[name='yang-schema-service']</provider>
-            </instance>
-        </service>
-        <service>
-            <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-notification-service</type>
-            <instance>
-                <name>ref_binding-notification-broker</name>
-                <provider>/config/modules/module[name='binding-notification-broker']/instance[name='binding-notification-broker']</provider>
-            </instance>
-        </service>
-        <service>
-            <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-data-store</type>
-            <instance>
-                <name>ref_hash-map-data-store</name>
-                <provider>/config/modules/module[name='hash-map-data-store']/instance[name='hash-map-data-store']</provider>
-            </instance>
-        </service>
-        <service>
-            <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-broker-osgi-registry</type>
-            <instance>
-                <name>ref_binding-broker-impl</name>
-                <provider>/config/modules/module[name='binding-broker-impl']/instance[name='binding-broker-impl']</provider>
-            </instance>
-        </service>
-        <service>
-            <type xmlns:binding-impl="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">binding-impl:binding-dom-mapping-service</type>
-            <instance>
-                <name>ref_runtime-mapping-singleton</name>
-                <provider>/config/modules/module[name='runtime-generated-mapping']/instance[name='runtime-mapping-singleton']</provider>
-            </instance>
-        </service>
-        <service>
-            <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-broker-osgi-registry</type>
-            <instance>
-                <name>ref_dom-broker</name>
-                <provider>/config/modules/module[name='dom-broker-impl']/instance[name='dom-broker']</provider>
-            </instance>
-        </service>
-        <service>
-            <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-data-broker</type>
-            <instance>
-                <name>ref_binding-data-broker</name>
-                <provider>/config/modules/module[name='binding-data-broker']/instance[name='binding-data-broker']</provider>
-            </instance>
-        </service>
-    </services>
-</data>
diff --git a/opendaylight/netconf/config-persister-impl/src/test/resources/test1.properties b/opendaylight/netconf/config-persister-impl/src/test/resources/test1.properties
deleted file mode 100644 (file)
index 851c599..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-netconf.config.persister.active=1
-netconf.config.persister.1.storageAdapterClass=org.opendaylight.controller.netconf.persist.impl.DummyAdapter
-netconf.config.persister.1.properties.fileStorage=target/configuration/initial/
diff --git a/opendaylight/netconf/config-persister-impl/src/test/resources/test2.properties b/opendaylight/netconf/config-persister-impl/src/test/resources/test2.properties
deleted file mode 100644 (file)
index 729c67d..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-netconf.config.persister.active=2
-# read startup configuration
-netconf.config.persister.1.storageAdapterClass=org.opendaylight.controller.config.persist.storage.directory.xml.XmlDirectoryStorageAdapter
-netconf.config.persister.1.properties.directoryStorage=target/configuration/initial/
-netconf.config.persister.1.readonly=true
-
-netconf.config.persister.2.storageAdapterClass=org.opendaylight.controller.config.persist.storage.file.xml.XmlFileStorageAdapter
-netconf.config.persister.2.properties.fileStorage=target/configuration/current/controller.config.2.txt
-netconf.config.persister.2.properties.numberOfBackups=3
diff --git a/opendaylight/netconf/config-persister-impl/src/test/resources/test3.properties b/opendaylight/netconf/config-persister-impl/src/test/resources/test3.properties
deleted file mode 100644 (file)
index 90ba772..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-netconf.config.persister.active=3
-netconf.config.persister.3.storageAdapterClass=org.opendaylight.controller.config.persist.storage.file.xml.XmlFileStorageAdapter
-netconf.config.persister.3.properties.fileStorage=target/configuration/current/controller.config.2.txt
-netconf.config.persister.3.properties.numberOfBackups=0
diff --git a/opendaylight/netconf/features/netconf-connector/pom.xml b/opendaylight/netconf/features/netconf-connector/pom.xml
new file mode 100644 (file)
index 0000000..731266c
--- /dev/null
@@ -0,0 +1,180 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ and is available at http://www.eclipse.org/legal/epl-v10.html
+--><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+   <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.opendaylight.controller</groupId>
+        <artifactId>netconf-subsystem</artifactId>
+        <version>0.4.0-SNAPSHOT</version>
+        <relativePath>../../</relativePath>
+    </parent>
+   <artifactId>features-netconf-connector</artifactId>
+
+    <!-- Preserve mdsal version-->
+   <version>${mdsal.version}</version>
+   <packaging>jar</packaging>
+   <properties>
+      <features.file>features.xml</features.file>
+   </properties>
+   <dependencies>
+    <dependency>
+          <groupId>org.opendaylight.yangtools</groupId>
+          <artifactId>features-yangtools</artifactId>
+          <version>${yangtools.version}</version>
+          <classifier>features</classifier>
+          <type>xml</type>
+        </dependency>
+        <dependency>
+          <groupId>org.opendaylight.controller</groupId>
+          <artifactId>features-mdsal</artifactId>
+          <version>${mdsal.version}</version>
+          <classifier>features</classifier>
+          <type>xml</type>
+        </dependency>
+        <dependency>
+          <groupId>org.opendaylight.controller</groupId>
+          <artifactId>features-netconf</artifactId>
+          <classifier>features</classifier>
+          <type>xml</type>
+        </dependency>
+        <dependency>
+          <groupId>org.opendaylight.aaa</groupId>
+          <artifactId>features-aaa</artifactId>
+          <version>${aaa.version}</version>
+          <classifier>features</classifier>
+          <type>xml</type>
+        </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal-netconf-connector</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller.model</groupId>
+      <artifactId>model-inventory</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>netconf-config-dispatcher</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>netconf-tcp</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>netconf-ssh</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.bouncycastle</groupId>
+      <artifactId>bcpkix-jdk15on</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.bouncycastle</groupId>
+      <artifactId>bcprov-jdk15on</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>netconf-connector-config</artifactId>
+      <version>${netconf.version}</version>
+      <type>xml</type>
+      <classifier>config</classifier>
+    </dependency>
+
+    <!--
+      Optional TODO: Remove TODO comments.
+    -->
+    <!-- test to validate features.xml -->
+   <!--FIXME BUG-2195 When running single feature tests for netconf connector, features including ssh proxy server always fail (this behavior does not appear when running karaf distro directly)-->
+    <dependency>
+      <groupId>org.opendaylight.odlparent</groupId>
+      <artifactId>features-test</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <!-- dependency for opendaylight-karaf-empty for use by testing -->
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>opendaylight-karaf-empty</artifactId>
+      <version>${commons.opendaylight.version}</version>
+      <type>zip</type>
+    </dependency>
+    <!-- Uncomment this if you get an error : java.lang.NoSuchMethodError: org.slf4j.helpers.MessageFormatter.format(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)Lorg/slf4j/helpers/FormattingTuple;
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-simple</artifactId>
+      <version>1.7.2</version>
+    </dependency>
+    -->
+
+   </dependencies>
+   <build>
+      <resources>
+         <resource>
+            <directory>src/main/resources</directory>
+            <filtering>true</filtering>
+         </resource>
+      </resources>
+      <plugins>
+         <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-resources-plugin</artifactId>
+            <executions>
+               <execution>
+                  <id>filter</id>
+                  <phase>generate-resources</phase>
+                  <goals>
+                     <goal>resources</goal>
+                  </goals>
+               </execution>
+            </executions>
+         </plugin>
+         <plugin>
+            <groupId>org.codehaus.mojo</groupId>
+            <artifactId>build-helper-maven-plugin</artifactId>
+            <executions>
+               <execution>
+                  <id>attach-artifacts</id>
+                  <phase>package</phase>
+                  <goals>
+                     <goal>attach-artifact</goal>
+                  </goals>
+                  <configuration>
+                     <artifacts>
+                        <artifact>
+                           <file>${project.build.directory}/classes/${features.file}</file>
+                           <type>xml</type>
+                           <classifier>features</classifier>
+                        </artifact>
+                     </artifacts>
+                  </configuration>
+               </execution>
+            </executions>
+         </plugin>
+         <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-surefire-plugin</artifactId>
+            <configuration>
+              <systemPropertyVariables>
+                <karaf.distro.groupId>org.opendaylight.controller</karaf.distro.groupId>
+                <karaf.distro.artifactId>opendaylight-karaf-empty</karaf.distro.artifactId>
+                <karaf.distro.version>${commons.opendaylight.version}</karaf.distro.version>
+              </systemPropertyVariables>
+              <dependenciesToScan>
+               <dependency>org.opendaylight.odlparent:features-test</dependency>
+              </dependenciesToScan>
+            </configuration>
+          </plugin>
+      </plugins>
+   </build>
+   <scm>
+      <connection>scm:git:http://git.opendaylight.org/gerrit/controller.git</connection>
+      <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
+      <tag>HEAD</tag>
+      <url>https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=summary</url>
+   </scm>
+</project>
diff --git a/opendaylight/netconf/features/netconf-connector/src/main/resources/features.xml b/opendaylight/netconf/features/netconf-connector/src/main/resources/features.xml
new file mode 100644 (file)
index 0000000..70cbb4e
--- /dev/null
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<!--
+ Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ and is available at http://www.eclipse.org/legal/epl-v10.html
+-->
+<features name="odl-controller-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0"
+          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+          xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">
+    <repository>mvn:org.opendaylight.controller/features-mdsal/${mdsal.version}/xml/features</repository>
+    <repository>mvn:org.opendaylight.yangtools/features-yangtools/${yangtools.version}/xml/features</repository>
+    <repository>mvn:org.opendaylight.controller/features-netconf/${netconf.version}/xml/features</repository>
+
+    <feature name='odl-netconf-connector-all' version='${project.version}' description='OpenDaylight :: Netconf Connector :: All'>
+        <feature version='${project.version}'>odl-netconf-connector</feature>
+        <feature version='${project.version}'>odl-netconf-connector-ssh</feature>
+    </feature>
+
+    <feature name='odl-netconf-connector' version='${project.version}' description="OpenDaylight :: Netconf Connector :: Netconf Connector">
+        <feature version='${mdsal.version}'>odl-mdsal-broker</feature>
+        <feature version='${netconf.version}'>odl-netconf-client</feature>
+        <feature version='${yangtools.version}'>odl-yangtools-models</feature>
+        <bundle>mvn:org.opendaylight.controller/sal-netconf-connector/${project.version}</bundle>
+        <bundle>mvn:org.opendaylight.controller.model/model-inventory/${mdsal.version}</bundle>
+    </feature>
+
+    <feature name='odl-netconf-connector-ssh' version='${project.version}' description="OpenDaylight :: Netconf Connector :: Netconf Connector + Netconf SSH Server + loopback connection configuration">
+        <feature version='${netconf.version}'>odl-netconf-ssh</feature>
+        <feature version='${project.version}'>odl-netconf-connector</feature>
+        <configfile finalname="${config.configfile.directory}/${config.netconf.connector.configfile}">mvn:org.opendaylight.controller/netconf-connector-config/${netconf.version}/xml/config</configfile>
+    </feature>
+
+</features>
diff --git a/opendaylight/netconf/features/netconf/pom.xml b/opendaylight/netconf/features/netconf/pom.xml
new file mode 100644 (file)
index 0000000..90b4851
--- /dev/null
@@ -0,0 +1,267 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.opendaylight.controller</groupId>
+    <artifactId>netconf-subsystem</artifactId>
+    <version>0.4.0-SNAPSHOT</version>
+    <relativePath>../../</relativePath>
+  </parent>
+  <artifactId>features-netconf</artifactId>
+
+  <packaging>jar</packaging>
+
+  <properties>
+    <features.file>features.xml</features.file>
+  </properties>
+
+  <dependencies>
+    <!-- FIXME AAA netconf dependency loop-->
+    <dependency>
+      <groupId>org.opendaylight.aaa</groupId>
+      <artifactId>features-aaa</artifactId>
+      <version>${aaa.version}</version>
+      <classifier>features</classifier>
+      <type>xml</type>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>features-config</artifactId>
+      <classifier>features</classifier>
+      <type>xml</type>
+      <scope>runtime</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>features-protocol-framework</artifactId>
+      <classifier>features</classifier>
+      <type>xml</type>
+      <scope>runtime</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>features-config-persister</artifactId>
+      <classifier>features</classifier>
+      <type>xml</type>
+      <scope>runtime</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>netconf-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>netconf-config</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>netconf-auth</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>netconf-notifications-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>netconf-notifications-impl</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>ietf-netconf</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>ietf-netconf-monitoring</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>ietf-netconf-monitoring-extension</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>ietf-netconf-notifications</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.yangtools.model</groupId>
+      <artifactId>ietf-inet-types</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.yangtools.model</groupId>
+      <artifactId>ietf-yang-types</artifactId>
+    </dependency>
+      <dependency>
+          <groupId>org.opendaylight.yangtools</groupId>
+          <artifactId>yang-model-api</artifactId>
+      </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>netconf-mapping-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>netconf-util</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>netconf-impl</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>config-manager-facade-xml</artifactId>
+      <version>${config.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>config-netconf-connector</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>netconf-netty-util</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.sshd</groupId>
+      <artifactId>sshd-core</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>openexi</groupId>
+      <artifactId>nagasena</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>io.netty</groupId>
+      <artifactId>netty-codec</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>io.netty</groupId>
+      <artifactId>netty-handler</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>io.netty</groupId>
+      <artifactId>netty-common</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>io.netty</groupId>
+      <artifactId>netty-buffer</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>io.netty</groupId>
+      <artifactId>netty-transport</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>netconf-client</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>netconf-config</artifactId>
+      <version>${config.version}</version>
+      <type>xml</type>
+      <classifier>config</classifier>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>netconf-connector-config</artifactId>
+      <version>${netconf.version}</version>
+      <type>xml</type>
+      <classifier>config</classifier>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>netconf-monitoring</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>mdsal-netconf-monitoring</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>mdsal-netconf-connector</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>netconf-mdsal-config</artifactId>
+      <classifier>config</classifier>
+      <type>xml</type>
+    </dependency>
+    <!-- test to validate features.xml -->
+    <dependency>
+      <groupId>org.opendaylight.odlparent</groupId>
+      <artifactId>features-test</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <!-- dependency for opendaylight-karaf-empty for use by testing -->
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>opendaylight-karaf-empty</artifactId>
+      <version>${commons.opendaylight.version}</version>
+      <type>zip</type>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <resources>
+      <resource>
+        <filtering>true</filtering>
+        <directory>src/main/resources</directory>
+      </resource>
+    </resources>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-resources-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>filter</id>
+            <goals>
+              <goal>resources</goal>
+            </goals>
+            <phase>generate-resources</phase>
+          </execution>
+        </executions>
+      </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/${features.file}</file>
+                  <type>xml</type>
+                  <classifier>features</classifier>
+                </artifact>
+              </artifacts>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <!-- FIXME uncomment after merge -->
+      <!--<plugin>-->
+        <!--<groupId>org.apache.maven.plugins</groupId>-->
+        <!--<artifactId>maven-surefire-plugin</artifactId>-->
+        <!--<version>${surefire.version}</version>-->
+        <!--<configuration>-->
+          <!--<systemPropertyVariables>-->
+            <!--<karaf.distro.groupId>org.opendaylight.controller</karaf.distro.groupId>-->
+            <!--<karaf.distro.artifactId>opendaylight-karaf-empty</karaf.distro.artifactId>-->
+            <!--<karaf.distro.version>${commons.opendaylight.version}</karaf.distro.version>-->
+          <!--</systemPropertyVariables>-->
+          <!--<dependenciesToScan>-->
+            <!--<dependency>org.opendaylight.odlparent:features-test</dependency>-->
+          <!--</dependenciesToScan>-->
+        <!--</configuration>-->
+      <!--</plugin>-->
+    </plugins>
+  </build>
+  <scm>
+    <connection>scm:git:http://git.opendaylight.org/gerrit/controller.git</connection>
+    <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
+    <tag>HEAD</tag>
+    <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL</url>
+  </scm>
+</project>
diff --git a/opendaylight/netconf/features/netconf/src/main/resources/features.xml b/opendaylight/netconf/features/netconf/src/main/resources/features.xml
new file mode 100644 (file)
index 0000000..ab38cef
--- /dev/null
@@ -0,0 +1,145 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<features name="odl-netconf-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0"
+          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+          xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">
+  <repository>mvn:org.opendaylight.controller/features-protocol-framework/${protocol-framework.version}/xml/features</repository>
+  <repository>mvn:org.opendaylight.controller/features-config/${config.version}/xml/features</repository>
+  <repository>mvn:org.opendaylight.controller/features-config-persister/${config.version}/xml/features</repository>
+  <!-- FIXME: This introduces cycle between projects, which makes version updates
+              harder. Should be moved to different.
+      -->
+  <repository>mvn:org.opendaylight.aaa/features-aaa/${aaa.version}/xml/features</repository>
+
+  <feature name='odl-netconf-all' version='${project.version}' description="OpenDaylight :: Netconf :: All">
+    <feature version='${project.version}'>odl-netconf-api</feature>
+    <feature version='${project.version}'>odl-netconf-mapping-api</feature>
+    <feature version='${project.version}'>odl-netconf-util</feature>
+    <feature version='${project.version}'>odl-netconf-impl</feature>
+    <feature version='${project.version}'>odl-config-netconf-connector</feature>
+    <feature version='${project.version}'>odl-netconf-netty-util</feature>
+    <feature version='${project.version}'>odl-netconf-client</feature>
+    <feature version='${project.version}'>odl-netconf-monitoring</feature>
+  </feature>
+
+  <feature name='odl-netconf-api' version='${project.version}' description="OpenDaylight :: Netconf :: API">
+    <feature version='${protocol-framework.version}'>odl-protocol-framework</feature>
+    <bundle>mvn:org.opendaylight.yangtools/yang-model-api/${yangtools.version}</bundle>
+    <bundle>mvn:org.opendaylight.controller/config-util/${config.version}</bundle>
+    <bundle>mvn:org.opendaylight.controller/netconf-api/${project.version}</bundle>
+    <bundle>mvn:org.opendaylight.controller/netconf-auth/${project.version}</bundle>
+    <bundle>mvn:org.opendaylight.controller/ietf-netconf-monitoring/${project.version}</bundle>
+    <bundle>mvn:org.opendaylight.controller/ietf-netconf/${project.version}</bundle>
+    <bundle>mvn:org.opendaylight.controller/ietf-netconf-notifications/${project.version}</bundle>
+    <bundle>mvn:org.opendaylight.controller/ietf-netconf-monitoring-extension/${project.version}</bundle>
+    <bundle>mvn:org.opendaylight.yangtools.model/ietf-inet-types/${ietf-inet-types.version}</bundle>
+    <bundle>mvn:org.opendaylight.yangtools.model/ietf-yang-types/${ietf-yang-types.version}</bundle>
+    <bundle>mvn:org.opendaylight.yangtools.model/ietf-yang-types-20130715/2013.07.15.8-SNAPSHOT</bundle>
+  </feature>
+
+  <feature name='odl-netconf-mapping-api' version='${project.version}' description="OpenDaylight :: Netconf :: Mapping API">
+    <feature version='${project.version}'>odl-netconf-api</feature>
+    <bundle>mvn:org.opendaylight.controller/netconf-mapping-api/${project.version}</bundle>
+  </feature>
+
+  <feature name='odl-netconf-util' version='${project.version}'>
+    <feature version='${project.version}'>odl-netconf-mapping-api</feature>
+    <bundle>mvn:org.opendaylight.yangtools/yang-model-api/${yangtools.version}</bundle>
+    <bundle>mvn:org.opendaylight.yangtools/yang-data-api/${yangtools.version}</bundle>
+    <bundle>mvn:org.opendaylight.controller/netconf-util/${project.version}</bundle>
+  </feature>
+
+  <feature name='odl-netconf-impl' version='${project.version}' description="OpenDaylight :: Netconf :: Impl">
+    <bundle>mvn:org.opendaylight.controller/yang-jmx-generator/${project.version}</bundle>
+    <feature version='${project.version}'>odl-netconf-api</feature>
+    <feature version='${project.version}'>odl-netconf-mapping-api</feature>
+    <feature version='${project.version}'>odl-netconf-util</feature>
+    <feature version='${project.version}'>odl-netconf-netty-util</feature>
+    <!-- Netconf server without config connector is just an empty shell -->
+    <feature version='${project.version}'>odl-config-netconf-connector</feature>
+    <!-- Netconf will not provide schemas without monitoring -->
+    <bundle>mvn:org.opendaylight.controller/config-manager-facade-xml/${project.version}</bundle>
+    <feature version='${project.version}'>odl-netconf-monitoring</feature>
+    <feature version='${project.version}'>odl-netconf-notifications-impl</feature>
+    <bundle>mvn:org.opendaylight.controller/netconf-impl/${project.version}</bundle>
+  </feature>
+
+  <feature name='odl-config-netconf-connector' version='${project.version}' description="OpenDaylight :: Netconf :: Connector">
+    <bundle>mvn:org.opendaylight.controller/yang-jmx-generator/${project.version}</bundle>
+    <bundle>mvn:org.opendaylight.controller/config-manager-facade-xml/${project.version}</bundle>
+    <feature version='${config.version}'>odl-config-manager</feature>
+    <feature version='${project.version}'>odl-netconf-netty-util</feature>
+    <bundle>mvn:org.opendaylight.controller/netconf-impl/${project.version}</bundle>
+    <feature version='${project.version}'>odl-netconf-notifications-api</feature>
+    <bundle>mvn:org.opendaylight.controller/netconf-notifications-impl/${project.version}</bundle>
+    <bundle>mvn:org.opendaylight.controller/config-netconf-connector/${project.version}</bundle>
+  </feature>
+
+  <feature name='odl-netconf-netty-util' version='${project.version}' description="OpenDaylight :: Netconf :: Netty Util">
+    <feature version='${project.version}'>odl-netconf-api</feature>
+    <feature version='${project.version}'>odl-netconf-mapping-api</feature>
+    <feature version='${project.version}'>odl-netconf-util</feature>
+    <bundle>mvn:org.opendaylight.controller/netconf-netty-util/${project.version}</bundle>
+    <bundle>mvn:org.bouncycastle/bcpkix-jdk15on/${bouncycastle.version}</bundle>
+    <bundle>mvn:org.bouncycastle/bcprov-jdk15on/${bouncycastle.version}</bundle>
+    <bundle>mvn:org.apache.sshd/sshd-core/${sshd-core.version}</bundle>
+    <bundle>mvn:openexi/nagasena/${exi.nagasena.version}</bundle>
+    <bundle>mvn:io.netty/netty-codec/${netty.version}</bundle>
+    <bundle>mvn:io.netty/netty-handler/${netty.version}</bundle>
+    <bundle>mvn:io.netty/netty-common/${netty.version}</bundle>
+    <bundle>mvn:io.netty/netty-buffer/${netty.version}</bundle>
+    <bundle>mvn:io.netty/netty-transport/${netty.version}</bundle>
+  </feature>
+
+  <feature name='odl-netconf-client' version='${project.version}' description="OpenDaylight :: Netconf :: Client">
+    <feature version='${config.version}'>odl-config-all</feature>
+    <feature version='${project.version}'>odl-netconf-netty-util</feature>
+    <bundle>mvn:org.opendaylight.controller/netconf-client/${project.version}</bundle>
+    <bundle>mvn:org.opendaylight.controller/netconf-config-dispatcher/${config.version}</bundle>
+    <configfile finalname='${config.configfile.directory}/${config.netconf.client.configfile}'>mvn:org.opendaylight.controller/netconf-config/${project.version}/xml/config</configfile>
+  </feature>
+
+  <feature name='odl-netconf-monitoring' version='${project.version}' description="OpenDaylight :: Netconf :: Monitoring">
+    <feature version='${project.version}'>odl-netconf-util</feature>
+    <bundle>mvn:org.opendaylight.controller/netconf-monitoring/${project.version}</bundle>
+  </feature>
+
+  <feature name='odl-netconf-notifications-api' version='${project.version}' description="OpenDaylight :: Netconf :: Notification :: Api">
+    <feature version='${project.version}'>odl-config-manager-facade-xml</feature>
+    <feature version='${project.version}'>odl-netconf-api</feature>
+    <bundle>mvn:org.opendaylight.controller/netconf-notifications-api/${project.version}</bundle>
+  </feature>
+
+  <feature name='odl-netconf-notifications-impl' version='${project.version}' description="OpenDaylight :: Netconf :: Monitoring :: Impl">
+    <feature version='${project.version}'>odl-netconf-notifications-api</feature>
+    <feature version='${project.version}'>odl-netconf-util</feature>
+    <bundle>mvn:org.opendaylight.controller/netconf-notifications-impl/${project.version}</bundle>
+  </feature>
+
+  <feature name='odl-netconf-ssh' version='${project.version}' description="OpenDaylight :: Netconf Connector :: SSH">
+    <feature version='${project.version}'>odl-netconf-tcp</feature>
+    <!-- FIXME: This introduces cycle between projects, which makes version updates
+                harder. Should be moved to different.
+    -->
+    <feature version='${aaa.version}'>odl-aaa-netconf-plugin</feature>
+    <bundle>mvn:org.opendaylight.controller/netconf-ssh/${project.version}</bundle>
+  </feature>
+
+  <feature name='odl-netconf-tcp' version='${project.version}' description="OpenDaylight :: Netconf Connector :: TCP">
+    <feature version='${project.version}'>odl-netconf-impl</feature>
+    <feature version='${config.version}'>odl-config-netty</feature>
+    <bundle>mvn:org.opendaylight.controller/netconf-tcp/${project.version}</bundle>
+  </feature>
+
+  <feature name='odl-netconf-mdsal' version='${mdsal.version}' description="OpenDaylight :: Netconf :: Mdsal">
+    <feature version='${config.version}'>odl-config-all</feature>
+    <feature version='${project.version}'>odl-netconf-all</feature>
+    <feature version='${project.version}'>odl-netconf-tcp</feature>
+    <feature version='${project.version}'>odl-netconf-ssh</feature>
+    <feature version='${project.version}'>odl-netconf-client</feature>
+    <feature version='${mdsal.version}'>odl-mdsal-broker</feature>
+    <bundle>mvn:org.opendaylight.controller/mdsal-netconf-connector/${project.version}</bundle>
+    <bundle>mvn:org.opendaylight.controller/mdsal-netconf-monitoring/${project.version}</bundle>
+    <configfile finalname='${config.configfile.directory}/${config.netconf.mdsal.configfile}'>mvn:org.opendaylight.controller/netconf-mdsal-config/${project.version}/xml/config</configfile>
+  </feature>
+</features>
diff --git a/opendaylight/netconf/features/pom.xml b/opendaylight/netconf/features/pom.xml
new file mode 100644 (file)
index 0000000..55b9bc2
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.opendaylight.controller</groupId>
+    <artifactId>netconf-subsystem</artifactId>
+    <version>0.4.0-SNAPSHOT</version>
+    <relativePath>../</relativePath>
+  </parent>
+  <artifactId>features-netconf-parent</artifactId>
+  <packaging>pom</packaging>
+
+  <modules>
+    <module>netconf</module>
+    <module>netconf-connector</module>
+  </modules>
+</project>
index fc9ae83457d4b722cd031a4703e82172df994b78..14b0b69dfee67a997e88e432252930ba3a6853f7 100644 (file)
           </instructions>
         </configuration>
       </plugin>
-      <!--FIXME extract yang plugin definition into parent-->
       <plugin>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>yang-maven-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>config</id>
-            <goals>
-              <goal>generate-sources</goal>
-            </goals>
-            <configuration>
-              <codeGenerators>
-                <generator>
-                  <codeGeneratorClass>org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator</codeGeneratorClass>
-                  <outputBaseDir>${jmxGeneratorPath}</outputBaseDir>
-                  <additionalConfiguration>
-                    <namespaceToPackage1>urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang</namespaceToPackage1>
-                  </additionalConfiguration>
-                </generator>
-                <generator>
-                  <codeGeneratorClass>org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl</codeGeneratorClass>
-                  <outputBaseDir>${salGeneratorPath}</outputBaseDir>
-                </generator>
-              </codeGenerators>
-              <inspectDependencies>true</inspectDependencies>
-            </configuration>
-          </execution>
-        </executions>
-        <dependencies>
-          <dependency>
-            <groupId>org.opendaylight.controller</groupId>
-            <artifactId>yang-jmx-generator-plugin</artifactId>
-            <version>${config.version}</version>
-          </dependency>
-        </dependencies>
       </plugin>
     </plugins>
   </build>
index 1aa38eb80c0a1fab17ea8512cacce4bf83fd1fe7..c947027f742c9dbb08ab3bb6899cc17f6b00acd9 100644 (file)
@@ -13,7 +13,7 @@ import com.google.common.collect.Sets;
 import java.util.Collections;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicReference;
-import org.opendaylight.controller.netconf.api.Capability;
+import org.opendaylight.controller.config.util.capability.Capability;
 import org.opendaylight.controller.netconf.api.monitoring.CapabilityListener;
 import org.opendaylight.controller.sal.core.api.model.SchemaService;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
@@ -23,7 +23,7 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
 public class CurrentSchemaContext implements SchemaContextListener, AutoCloseable {
     final AtomicReference<SchemaContext> currentContext = new AtomicReference<SchemaContext>();
     private final ListenerRegistration<SchemaContextListener> schemaContextListenerListenerRegistration;
-    private final Set<CapabilityListener> listeners = Collections.synchronizedSet(Sets.<CapabilityListener>newHashSet());
+    private final Set<CapabilityListener> listeners1 = Collections.synchronizedSet(Sets.<CapabilityListener>newHashSet());
 
     public SchemaContext getCurrentContext() {
         Preconditions.checkState(currentContext.get() != null, "Current context not received");
@@ -39,25 +39,25 @@ public class CurrentSchemaContext implements SchemaContextListener, AutoCloseabl
         currentContext.set(schemaContext);
         // FIXME is notifying all the listeners from this callback wise ?
         final Set<Capability> addedCaps = MdsalNetconfOperationServiceFactory.transformCapabilities(currentContext.get());
-        for (final CapabilityListener listener : listeners) {
-            listener.onCapabilitiesAdded(addedCaps);
+        for (final CapabilityListener listener : listeners1) {
+            listener.onCapabilitiesChanged(addedCaps, Collections.<Capability>emptySet());
         }
     }
 
     @Override
     public void close() throws Exception {
-        listeners.clear();
+        listeners1.clear();
         schemaContextListenerListenerRegistration.close();
         currentContext.set(null);
     }
 
     public AutoCloseable registerCapabilityListener(final CapabilityListener listener) {
-        listener.onCapabilitiesAdded(MdsalNetconfOperationServiceFactory.transformCapabilities(currentContext.get()));
-        listeners.add(listener);
+        listener.onCapabilitiesChanged(MdsalNetconfOperationServiceFactory.transformCapabilities(currentContext.get()), Collections.<Capability>emptySet());
+        listeners1.add(listener);
         return new AutoCloseable() {
             @Override
             public void close() throws Exception {
-                listeners.remove(listener);
+                listeners1.remove(listener);
             }
         };
     }
index 96244fdc68a366c1e435705a11ac3ad2b60023ad..4cb9bdb006611aba0dc34242f3c5278ba99157ff 100644 (file)
@@ -14,13 +14,12 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.Set;
+import org.opendaylight.controller.config.util.capability.Capability;
+import org.opendaylight.controller.config.util.capability.YangModuleCapability;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
 import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
-import org.opendaylight.controller.netconf.api.Capability;
 import org.opendaylight.controller.netconf.api.monitoring.CapabilityListener;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactory;
-import org.opendaylight.controller.netconf.util.capability.BasicCapability;
-import org.opendaylight.controller.netconf.util.capability.YangModuleCapability;
 import org.opendaylight.controller.sal.core.api.Broker.ConsumerSession;
 import org.opendaylight.controller.sal.core.api.Consumer;
 import org.opendaylight.controller.sal.core.api.model.SchemaService;
@@ -60,8 +59,9 @@ public class MdsalNetconfOperationServiceFactory implements NetconfOperationServ
 
     static Set<Capability> transformCapabilities(final SchemaContext currentContext) {
         final Set<Capability> capabilities = new HashSet<>();
-        // [RFC6241] 8.3.  Candidate Configuration Capability
-        capabilities.add(new BasicCapability("urn:ietf:params:netconf:capability:candidate:1.0"));
+
+        // Added by netconf-impl by default
+//        capabilities.add(new BasicCapability("urn:ietf:params:netconf:capability:candidate:1.0"));
 
         final Set<Module> modules = currentContext.getModules();
         for (final Module module : modules) {
index f1b214b83e712f5997e443f4f9759f0bbb31a310..eddd08b112f3e98b4b6f8a00f2d015a590a01f19 100644 (file)
@@ -13,13 +13,13 @@ import com.google.common.base.Preconditions;
 import com.google.common.util.concurrent.CheckedFuture;
 import java.util.ArrayList;
 import java.util.List;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorSeverity;
+import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorTag;
+import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorType;
 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.DOMDataReadWriteTransaction;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorSeverity;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorTag;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorType;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -71,9 +71,9 @@ public class TransactionProvider implements AutoCloseable{
         return candidateTransaction;
     }
 
-    public synchronized boolean commitTransaction() throws NetconfDocumentedException {
+    public synchronized boolean commitTransaction() throws DocumentedException {
         if (!getCandidateTransaction().isPresent()) {
-            throw new NetconfDocumentedException(NO_TRANSACTION_FOUND_FOR_SESSION + netconfSessionIdForReporting,
+            throw new DocumentedException(NO_TRANSACTION_FOUND_FOR_SESSION + netconfSessionIdForReporting,
                     ErrorType.application, ErrorTag.operation_failed, ErrorSeverity.error);
         }
 
@@ -82,7 +82,7 @@ public class TransactionProvider implements AutoCloseable{
             future.checkedGet();
         } catch (TransactionCommitFailedException e) {
             LOG.debug("Transaction {} failed on", candidateTransaction, e);
-            throw new NetconfDocumentedException("Transaction commit failed on " + e.getMessage() + " " + netconfSessionIdForReporting,
+            throw new DocumentedException("Transaction commit failed on " + e.getMessage() + " " + netconfSessionIdForReporting,
                     ErrorType.application, ErrorTag.operation_failed, ErrorSeverity.error);
         }
         allOpenReadWriteTransactions.remove(candidateTransaction);
@@ -106,7 +106,7 @@ public class TransactionProvider implements AutoCloseable{
         return runningTransaction;
     }
 
-    public synchronized boolean commitRunningTransaction(DOMDataReadWriteTransaction tx) throws NetconfDocumentedException {
+    public synchronized boolean commitRunningTransaction(DOMDataReadWriteTransaction tx) throws DocumentedException {
         allOpenReadWriteTransactions.remove(tx);
 
         CheckedFuture<Void, TransactionCommitFailedException> future = tx.submit();
@@ -114,7 +114,7 @@ public class TransactionProvider implements AutoCloseable{
             future.checkedGet();
         } catch (TransactionCommitFailedException e) {
             LOG.debug("Transaction {} failed on", tx, e);
-            throw new NetconfDocumentedException("Transaction commit failed on " + e.getMessage() + " " + netconfSessionIdForReporting,
+            throw new DocumentedException("Transaction commit failed on " + e.getMessage() + " " + netconfSessionIdForReporting,
                     ErrorType.application, ErrorTag.operation_failed, ErrorSeverity.error);
         }
 
index 47e8f80585cdfc9411c15856722149906610d145..bc8abc5d75ce35530ca3c6cc6f9d57a3921e5a9f 100644 (file)
@@ -9,12 +9,12 @@
 package org.opendaylight.controller.netconf.mdsal.connector.ops;
 
 import com.google.common.base.Optional;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.config.util.xml.XmlElement;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
 import org.opendaylight.controller.netconf.mdsal.connector.TransactionProvider;
 import org.opendaylight.controller.netconf.util.mapping.AbstractSingletonNetconfOperation;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
@@ -34,7 +34,7 @@ public class Commit extends AbstractSingletonNetconfOperation {
     }
 
     @Override
-    protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement operationElement) throws NetconfDocumentedException {
+    protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement operationElement) throws DocumentedException {
 
         boolean commitStatus = transactionProvider.commitTransaction();
         LOG.trace("Transaction commited succesfuly {}", commitStatus);
index ce4de18ee6b5ef5554232d566d8259cba251eca5..f575197b59e6899498aba796c3abe5f1fb1eb022 100644 (file)
@@ -11,15 +11,15 @@ package org.opendaylight.controller.netconf.mdsal.connector.ops;
 import com.google.common.base.Optional;
 import java.util.HashMap;
 import java.util.Map;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorSeverity;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorTag;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorType;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorSeverity;
+import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorTag;
+import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorType;
+import org.opendaylight.controller.config.util.xml.XmlElement;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
 import org.opendaylight.controller.netconf.mdsal.connector.TransactionProvider;
 import org.opendaylight.controller.netconf.util.mapping.AbstractSingletonNetconfOperation;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
@@ -39,7 +39,7 @@ public class DiscardChanges extends AbstractSingletonNetconfOperation {
     }
 
     @Override
-    protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement operationElement) throws NetconfDocumentedException {
+    protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement operationElement) throws DocumentedException {
 
         try {
             transactionProvider.abortTransaction();
@@ -49,7 +49,7 @@ public class DiscardChanges extends AbstractSingletonNetconfOperation {
             errorInfo
                     .put(ErrorTag.operation_failed.name(),
                             "Operation failed. Use 'get-config' or 'edit-config' before triggering 'discard-changes' operation");
-            throw new NetconfDocumentedException(e.getMessage(), e, ErrorType.application, ErrorTag.operation_failed,
+            throw new DocumentedException(e.getMessage(), e, ErrorType.application, ErrorTag.operation_failed,
                     ErrorSeverity.error, errorInfo);
         }
         return XmlUtil.createElement(document, XmlNetconfConstants.OK, Optional.<String>absent());
index 914ff200068992b250f9d21f6feea395c449394c..889068940eebe626d3b60d97ac8d66fd7b10e7c3 100644 (file)
@@ -14,20 +14,20 @@ import java.net.URISyntaxException;
 import java.util.Collections;
 import java.util.List;
 import java.util.ListIterator;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorSeverity;
+import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorTag;
+import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorType;
+import org.opendaylight.controller.config.util.xml.XmlElement;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 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.DOMDataReadWriteTransaction;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorSeverity;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorTag;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorType;
 import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
 import org.opendaylight.controller.netconf.mdsal.connector.CurrentSchemaContext;
 import org.opendaylight.controller.netconf.mdsal.connector.TransactionProvider;
 import org.opendaylight.controller.netconf.mdsal.connector.ops.DataTreeChangeTracker.DataTreeChange;
 import org.opendaylight.controller.netconf.util.mapping.AbstractSingletonNetconfOperation;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.opendaylight.yangtools.yang.data.api.ModifyAction;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
@@ -61,10 +61,10 @@ public class EditConfig extends AbstractSingletonNetconfOperation {
     }
 
     @Override
-    protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement operationElement) throws NetconfDocumentedException {
+    protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement operationElement) throws DocumentedException {
         final Datastore targetDatastore = extractTargetParameter(operationElement);
         if (targetDatastore == Datastore.running) {
-            throw new NetconfDocumentedException("edit-config on running datastore is not supported",
+            throw new DocumentedException("edit-config on running datastore is not supported",
                     ErrorType.protocol,
                     ErrorTag.operation_not_supported,
                     ErrorSeverity.error);
@@ -88,7 +88,7 @@ public class EditConfig extends AbstractSingletonNetconfOperation {
         return XmlUtil.createElement(document, XmlNetconfConstants.OK, Optional.<String>absent());
     }
 
-    private void executeOperations(final DataTreeChangeTracker changeTracker) throws NetconfDocumentedException {
+    private void executeOperations(final DataTreeChangeTracker changeTracker) throws DocumentedException {
         final DOMDataReadWriteTransaction rwTx = transactionProvider.getOrCreateTransaction();
         final List<DataTreeChange> aa = changeTracker.getDataTreeChanges();
         final ListIterator<DataTreeChange> iterator = aa.listIterator(aa.size());
@@ -99,7 +99,7 @@ public class EditConfig extends AbstractSingletonNetconfOperation {
         }
     }
 
-    private void executeChange(final DOMDataReadWriteTransaction rwtx, final DataTreeChange change) throws NetconfDocumentedException {
+    private void executeChange(final DOMDataReadWriteTransaction rwtx, final DataTreeChange change) throws DocumentedException {
         switch (change.getAction()) {
         case NONE:
             return;
@@ -110,7 +110,7 @@ public class EditConfig extends AbstractSingletonNetconfOperation {
             try {
                 final Optional<NormalizedNode<?, ?>> readResult = rwtx.read(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.create(change.getPath())).checkedGet();
                 if (readResult.isPresent()) {
-                    throw new NetconfDocumentedException("Data already exists, cannot execute CREATE operation", ErrorType.protocol, ErrorTag.data_exists, ErrorSeverity.error);
+                    throw new DocumentedException("Data already exists, cannot execute CREATE operation", ErrorType.protocol, ErrorTag.data_exists, ErrorSeverity.error);
                 }
                 rwtx.put(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.create(change.getPath()), change.getChangeRoot());
             } catch (ReadFailedException e) {
@@ -124,7 +124,7 @@ public class EditConfig extends AbstractSingletonNetconfOperation {
             try {
                 final Optional<NormalizedNode<?, ?>> readResult = rwtx.read(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.create(change.getPath())).checkedGet();
                 if (!readResult.isPresent()) {
-                    throw new NetconfDocumentedException("Data is missing, cannot execute DELETE operation", ErrorType.protocol, ErrorTag.data_missing, ErrorSeverity.error);
+                    throw new DocumentedException("Data is missing, cannot execute DELETE operation", ErrorType.protocol, ErrorTag.data_missing, ErrorSeverity.error);
                 }
                 rwtx.delete(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.create(change.getPath()));
             } catch (ReadFailedException e) {
@@ -160,7 +160,7 @@ public class EditConfig extends AbstractSingletonNetconfOperation {
         throw new UnsupportedOperationException("implement exception if parse fails");
     }
 
-    private Optional<DataSchemaNode> getSchemaNodeFromNamespace(final String namespace, final XmlElement element) throws NetconfDocumentedException{
+    private Optional<DataSchemaNode> getSchemaNodeFromNamespace(final String namespace, final XmlElement element) throws DocumentedException{
         Optional<DataSchemaNode> dataSchemaNode = Optional.absent();
         try {
             //returns module with newest revision since findModuleByNamespace returns a set of modules and we only need the newest one
@@ -169,7 +169,7 @@ public class EditConfig extends AbstractSingletonNetconfOperation {
             if (schemaNode != null) {
                 dataSchemaNode = Optional.of(module.getDataChildByName(element.getName()));
             } else {
-                throw new NetconfDocumentedException("Unable to find node with namespace: " + namespace + "in module: " + module.toString(),
+                throw new DocumentedException("Unable to find node with namespace: " + namespace + "in module: " + module.toString(),
                         ErrorType.application,
                         ErrorTag.unknown_namespace,
                         ErrorSeverity.error);
@@ -181,25 +181,25 @@ public class EditConfig extends AbstractSingletonNetconfOperation {
         return dataSchemaNode;
     }
 
-    private Datastore extractTargetParameter(final XmlElement operationElement) throws NetconfDocumentedException {
+    private Datastore extractTargetParameter(final XmlElement operationElement) throws DocumentedException {
         final NodeList elementsByTagName = operationElement.getDomElement().getElementsByTagName(TARGET_KEY);
         // Direct lookup instead of using XmlElement class due to performance
         if (elementsByTagName.getLength() == 0) {
-            throw new NetconfDocumentedException("Missing target element", ErrorType.rpc, ErrorTag.missing_attribute, ErrorSeverity.error);
+            throw new DocumentedException("Missing target element", ErrorType.rpc, ErrorTag.missing_attribute, ErrorSeverity.error);
         } else if (elementsByTagName.getLength() > 1) {
-            throw new NetconfDocumentedException("Multiple target elements", ErrorType.rpc, ErrorTag.unknown_attribute, ErrorSeverity.error);
+            throw new DocumentedException("Multiple target elements", ErrorType.rpc, ErrorTag.unknown_attribute, ErrorSeverity.error);
         } else {
             final XmlElement targetChildNode = XmlElement.fromDomElement((Element) elementsByTagName.item(0)).getOnlyChildElement();
             return Datastore.valueOf(targetChildNode.getName());
         }
     }
 
-    private ModifyAction getDefaultOperation(final XmlElement operationElement) throws NetconfDocumentedException {
+    private ModifyAction getDefaultOperation(final XmlElement operationElement) throws DocumentedException {
         final NodeList elementsByTagName = operationElement.getDomElement().getElementsByTagName(DEFAULT_OPERATION_KEY);
         if(elementsByTagName.getLength() == 0) {
             return ModifyAction.MERGE;
         } else if(elementsByTagName.getLength() > 1) {
-            throw new NetconfDocumentedException("Multiple " + DEFAULT_OPERATION_KEY + " elements",
+            throw new DocumentedException("Multiple " + DEFAULT_OPERATION_KEY + " elements",
                     ErrorType.rpc, ErrorTag.unknown_attribute, ErrorSeverity.error);
         } else {
             return ModifyAction.fromXmlValue(elementsByTagName.item(0).getTextContent());
@@ -207,10 +207,10 @@ public class EditConfig extends AbstractSingletonNetconfOperation {
 
     }
 
-    private XmlElement getElement(final XmlElement operationElement, String elementName) throws NetconfDocumentedException {
+    private XmlElement getElement(final XmlElement operationElement, String elementName) throws DocumentedException {
         final Optional<XmlElement> childNode = operationElement.getOnlyChildElementOptionally(elementName);
         if (!childNode.isPresent()) {
-            throw new NetconfDocumentedException(elementName + " element is missing",
+            throw new DocumentedException(elementName + " element is missing",
                     ErrorType.protocol,
                     ErrorTag.missing_element,
                     ErrorSeverity.error);
index 252f4a637f04817cbc9f749ec10b339e57138880..22fe064885879c33f0fd10e6766b578072482150 100644 (file)
@@ -9,11 +9,11 @@
 package org.opendaylight.controller.netconf.mdsal.connector.ops;
 
 import com.google.common.base.Optional;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.config.util.xml.XmlElement;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
 import org.opendaylight.controller.netconf.util.mapping.AbstractSingletonNetconfOperation;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
@@ -31,18 +31,18 @@ public class Lock extends AbstractSingletonNetconfOperation {
     }
 
     @Override
-    protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement operationElement) throws NetconfDocumentedException {
+    protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement operationElement) throws DocumentedException {
         final Datastore targetDatastore = extractTargetParameter(operationElement);
         if (targetDatastore == Datastore.candidate) {
             LOG.debug("Locking candidate datastore on session: {}", getNetconfSessionIdForReporting());
             return XmlUtil.createElement(document, XmlNetconfConstants.OK, Optional.<String>absent());
         }
 
-        throw new NetconfDocumentedException("Unable to lock " + targetDatastore + " datastore", NetconfDocumentedException.ErrorType.application,
-                NetconfDocumentedException.ErrorTag.operation_not_supported, NetconfDocumentedException.ErrorSeverity.error);
+        throw new DocumentedException("Unable to lock " + targetDatastore + " datastore", DocumentedException.ErrorType.application,
+                DocumentedException.ErrorTag.operation_not_supported, DocumentedException.ErrorSeverity.error);
     }
 
-    static Datastore extractTargetParameter(final XmlElement operationElement) throws NetconfDocumentedException {
+    static Datastore extractTargetParameter(final XmlElement operationElement) throws DocumentedException {
         final XmlElement targetElement = operationElement.getOnlyChildElementWithSameNamespace(TARGET_KEY);
         final XmlElement targetChildNode = targetElement.getOnlyChildElementWithSameNamespace();
         return Datastore.valueOf(targetChildNode.getName());
index 51f9e220c54ff24c47886c920e5e15aa0d7afda2..0c35b898001b97ea97ff093373f4a4477878f451 100644 (file)
@@ -22,22 +22,22 @@ import javax.xml.stream.XMLOutputFactory;
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamWriter;
 import javax.xml.transform.dom.DOMResult;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorSeverity;
+import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorTag;
+import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorType;
+import org.opendaylight.controller.config.util.xml.XmlElement;
+import org.opendaylight.controller.config.util.xml.XmlMappingConstants;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 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.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorSeverity;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorTag;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorType;
 import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
 import org.opendaylight.controller.netconf.mapping.api.HandlingPriority;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperationChainedExecution;
 import org.opendaylight.controller.netconf.mdsal.connector.CurrentSchemaContext;
 import org.opendaylight.controller.netconf.util.OrderedNormalizedNodeWriter;
-import org.opendaylight.controller.netconf.util.exception.MissingNameSpaceException;
 import org.opendaylight.controller.netconf.util.mapping.AbstractSingletonNetconfOperation;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 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.NormalizedNode;
@@ -124,15 +124,15 @@ public class RuntimeRpc extends AbstractSingletonNetconfOperation {
     }
 
     @Override
-    protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement operationElement) throws NetconfDocumentedException {
+    protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement operationElement) throws DocumentedException {
 
         final String netconfOperationName = operationElement.getName();
         final String netconfOperationNamespace;
         try {
             netconfOperationNamespace = operationElement.getNamespace();
-        } catch (MissingNameSpaceException e) {
+        } catch (DocumentedException e) {
             LOG.debug("Cannot retrieve netconf operation namespace from message due to ", e);
-            throw new NetconfDocumentedException("Cannot retrieve netconf operation namespace from message",
+            throw new DocumentedException("Cannot retrieve netconf operation namespace from message",
                     ErrorType.protocol, ErrorTag.unknown_namespace, ErrorSeverity.error);
         }
 
@@ -140,7 +140,7 @@ public class RuntimeRpc extends AbstractSingletonNetconfOperation {
         final Optional<Module> moduleOptional = getModule(namespaceURI);
 
         if (!moduleOptional.isPresent()) {
-            throw new NetconfDocumentedException("Unable to find module in Schema Context with namespace and name : " +
+            throw new DocumentedException("Unable to find module in Schema Context with namespace and name : " +
                     namespaceURI + " " + netconfOperationName + schemaContext.getCurrentContext(),
                     ErrorType.application, ErrorTag.bad_element, ErrorSeverity.error);
         }
@@ -148,7 +148,7 @@ public class RuntimeRpc extends AbstractSingletonNetconfOperation {
         final Optional<RpcDefinition> rpcDefinitionOptional = getRpcDefinitionFromModule(moduleOptional.get(), namespaceURI, netconfOperationName);
 
         if (!rpcDefinitionOptional.isPresent()) {
-            throw new NetconfDocumentedException("Unable to find RpcDefinition with namespace and name : " + namespaceURI + " " + netconfOperationName,
+            throw new DocumentedException("Unable to find RpcDefinition with namespace and name : " + namespaceURI + " " + netconfOperationName,
                     ErrorType.application, ErrorTag.bad_element, ErrorSeverity.error);
         }
 
@@ -164,13 +164,13 @@ public class RuntimeRpc extends AbstractSingletonNetconfOperation {
             }
             return (Element) transformNormalizedNode(document, result.getResult(), rpcDefinition.getOutput().getPath());
         } catch (DOMRpcException e) {
-            throw NetconfDocumentedException.wrap(e);
+            throw DocumentedException.wrap(e);
         }
     }
 
     @Override
     public Document handle(final Document requestMessage,
-                           final NetconfOperationChainedExecution subsequentOperation) throws NetconfDocumentedException {
+                           final NetconfOperationChainedExecution subsequentOperation) throws DocumentedException {
 
         final XmlElement requestElement = getRequestElementWithCheck(requestMessage);
 
@@ -180,7 +180,7 @@ public class RuntimeRpc extends AbstractSingletonNetconfOperation {
         final Map<String, Attr> attributes = requestElement.getAttributes();
 
         final Element response = handle(document, operationElement, subsequentOperation);
-        final Element rpcReply = XmlUtil.createElement(document, XmlNetconfConstants.RPC_REPLY_KEY, Optional.of(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0));
+        final Element rpcReply = XmlUtil.createElement(document, XmlMappingConstants.RPC_REPLY_KEY, Optional.of(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0));
 
         if(XmlElement.fromDomElement(response).hasNamespace()) {
             rpcReply.appendChild(response);
@@ -204,7 +204,7 @@ public class RuntimeRpc extends AbstractSingletonNetconfOperation {
 
     //TODO move all occurences of this method in mdsal netconf(and xml factories) to a utility class
     private Node transformNormalizedNode(final Document document, final NormalizedNode<?, ?> data, final SchemaPath rpcOutputPath) {
-        final DOMResult result = new DOMResult(document.createElement(XmlNetconfConstants.RPC_REPLY_KEY));
+        final DOMResult result = new DOMResult(document.createElement(XmlMappingConstants.RPC_REPLY_KEY));
 
         final XMLStreamWriter xmlWriter = getXmlStreamWriter(result);
 
index 634be3e22f4bf9128f1b2c18283413d1b928a59f..4cea4cbdeb7b076f69043e7717e67b5125dd670d 100644 (file)
@@ -9,11 +9,11 @@
 package org.opendaylight.controller.netconf.mdsal.connector.ops;
 
 import com.google.common.base.Optional;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.config.util.xml.XmlElement;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
 import org.opendaylight.controller.netconf.util.mapping.AbstractSingletonNetconfOperation;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
@@ -30,15 +30,15 @@ public class Unlock extends AbstractSingletonNetconfOperation {
     }
 
     @Override
-    protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement operationElement) throws NetconfDocumentedException {
+    protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement operationElement) throws DocumentedException {
         final Datastore targetDatastore = Lock.extractTargetParameter(operationElement);
         if (targetDatastore == Datastore.candidate) {
             LOG.debug("Unlocking candidate datastore on session: {}", getNetconfSessionIdForReporting());
             return XmlUtil.createElement(document, XmlNetconfConstants.OK, Optional.<String>absent());
         }
 
-        throw new NetconfDocumentedException("Unable to unlock " + targetDatastore + " datastore", NetconfDocumentedException.ErrorType.application,
-                NetconfDocumentedException.ErrorTag.operation_not_supported, NetconfDocumentedException.ErrorSeverity.error);
+        throw new DocumentedException("Unable to unlock " + targetDatastore + " datastore", DocumentedException.ErrorType.application,
+                DocumentedException.ErrorTag.operation_not_supported, DocumentedException.ErrorSeverity.error);
     }
 
     @Override
index d028a89e36d6d34c8d2535988739e5807908224f..21372f8e45d9a0c200391980e849179364eef4c3 100644 (file)
@@ -22,15 +22,15 @@ import javax.xml.stream.XMLOutputFactory;
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamWriter;
 import javax.xml.transform.dom.DOMResult;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorSeverity;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorTag;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorType;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorSeverity;
+import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorTag;
+import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorType;
+import org.opendaylight.controller.config.util.xml.XmlElement;
 import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
 import org.opendaylight.controller.netconf.mdsal.connector.CurrentSchemaContext;
 import org.opendaylight.controller.netconf.mdsal.connector.ops.Datastore;
 import org.opendaylight.controller.netconf.util.mapping.AbstractSingletonNetconfOperation;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
@@ -128,7 +128,7 @@ public abstract class AbstractGet extends AbstractSingletonNetconfOperation {
         }
     }
 
-    private DataSchemaNode getSchemaNodeFromNamespace(final XmlElement element) throws NetconfDocumentedException {
+    private DataSchemaNode getSchemaNodeFromNamespace(final XmlElement element) throws DocumentedException {
 
         try {
             final Module module = schemaContext.getCurrentContext().findModuleByNamespaceAndRevision(new URI(element.getNamespace()), null);
@@ -142,7 +142,7 @@ public abstract class AbstractGet extends AbstractSingletonNetconfOperation {
             throw new IllegalArgumentException("Unable to parse element namespace, this should not happen since " +
                     "namespace of an xml element is valid and if the xml was parsed then the URI should be as well");
         }
-        throw new NetconfDocumentedException("Unable to find node with namespace: " + element.getNamespace() + "in schema context: " + schemaContext.getCurrentContext().toString(),
+        throw new DocumentedException("Unable to find node with namespace: " + element.getNamespace() + "in schema context: " + schemaContext.getCurrentContext().toString(),
                 ErrorType.application,
                 ErrorTag.unknown_namespace,
                 ErrorSeverity.error);
@@ -163,9 +163,9 @@ public abstract class AbstractGet extends AbstractSingletonNetconfOperation {
      * @return if Filter is present and not empty returns Optional of the InstanceIdentifier to the read location in datastore.
      *          empty filter returns Optional.absent() which should equal an empty <data/> container in the response.
      *         if filter is not present we want to read the entire datastore - return ROOT.
-     * @throws NetconfDocumentedException
+     * @throws DocumentedException
      */
-    protected Optional<YangInstanceIdentifier> getDataRootFromFilter(XmlElement operationElement) throws NetconfDocumentedException {
+    protected Optional<YangInstanceIdentifier> getDataRootFromFilter(XmlElement operationElement) throws DocumentedException {
         Optional<XmlElement> filterElement = operationElement.getOnlyChildElementOptionally(FILTER);
         if (filterElement.isPresent()) {
             if (filterElement.get().getChildElements().size() == 0) {
@@ -178,10 +178,10 @@ public abstract class AbstractGet extends AbstractSingletonNetconfOperation {
     }
 
     @VisibleForTesting
-    protected YangInstanceIdentifier getInstanceIdentifierFromFilter(XmlElement filterElement) throws NetconfDocumentedException {
+    protected YangInstanceIdentifier getInstanceIdentifierFromFilter(XmlElement filterElement) throws DocumentedException {
 
         if (filterElement.getChildElements().size() != 1) {
-            throw new NetconfDocumentedException("Multiple filter roots not supported yet",
+            throw new DocumentedException("Multiple filter roots not supported yet",
                     ErrorType.application, ErrorTag.operation_not_supported, ErrorSeverity.error);
         }
 
@@ -202,7 +202,7 @@ public abstract class AbstractGet extends AbstractSingletonNetconfOperation {
         return path;
     }
 
-    private NormalizedNode filterToNormalizedNode(XmlElement element, DataSchemaNode schemaNode) throws NetconfDocumentedException {
+    private NormalizedNode filterToNormalizedNode(XmlElement element, DataSchemaNode schemaNode) throws DocumentedException {
         DomToNormalizedNodeParserFactory parserFactory = DomToNormalizedNodeParserFactory
                 .getInstance(DomUtils.defaultValueCodecProvider(), schemaContext.getCurrentContext());
 
@@ -213,7 +213,7 @@ public abstract class AbstractGet extends AbstractSingletonNetconfOperation {
         } else if (schemaNode instanceof ListSchemaNode) {
             parsedNode = parserFactory.getMapNodeParser().parse(Collections.singletonList(element.getDomElement()), (ListSchemaNode) schemaNode);
         } else {
-            throw new NetconfDocumentedException("Schema node of the top level element is not an instance of container or list",
+            throw new DocumentedException("Schema node of the top level element is not an instance of container or list",
                     ErrorType.application, ErrorTag.unknown_element, ErrorSeverity.error);
         }
         return parsedNode;
@@ -230,24 +230,24 @@ public abstract class AbstractGet extends AbstractSingletonNetconfOperation {
             return datastore;
         }
 
-        static GetConfigExecution fromXml(final XmlElement xml, final String operationName) throws NetconfDocumentedException {
+        static GetConfigExecution fromXml(final XmlElement xml, final String operationName) throws DocumentedException {
             try {
                 validateInputRpc(xml, operationName);
-            } catch (final NetconfDocumentedException e) {
-                throw new NetconfDocumentedException("Incorrect RPC: " + e.getMessage(), e.getErrorType(), e.getErrorTag(), e.getErrorSeverity(), e.getErrorInfo());
+            } catch (final DocumentedException e) {
+                throw new DocumentedException("Incorrect RPC: " + e.getMessage(), e.getErrorType(), e.getErrorTag(), e.getErrorSeverity(), e.getErrorInfo());
             }
 
             final Optional<Datastore> sourceDatastore;
             try {
                 sourceDatastore = parseSource(xml);
-            } catch (final NetconfDocumentedException e) {
-                throw new NetconfDocumentedException("Get-config source attribute error: " + e.getMessage(), e.getErrorType(), e.getErrorTag(), e.getErrorSeverity(), e.getErrorInfo());
+            } catch (final DocumentedException e) {
+                throw new DocumentedException("Get-config source attribute error: " + e.getMessage(), e.getErrorType(), e.getErrorTag(), e.getErrorSeverity(), e.getErrorInfo());
             }
 
             return new GetConfigExecution(sourceDatastore);
         }
 
-        private static Optional<Datastore> parseSource(final XmlElement xml) throws NetconfDocumentedException {
+        private static Optional<Datastore> parseSource(final XmlElement xml) throws DocumentedException {
             final Optional<XmlElement> sourceElement = xml.getOnlyChildElementOptionally(XmlNetconfConstants.SOURCE_KEY,
                     XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
 
@@ -255,7 +255,7 @@ public abstract class AbstractGet extends AbstractSingletonNetconfOperation {
                     Optional.of(Datastore.valueOf(sourceElement.get().getOnlyChildElement().getName())) : Optional.<Datastore>absent();
         }
 
-        private static void validateInputRpc(final XmlElement xml, String operationName) throws NetconfDocumentedException{
+        private static void validateInputRpc(final XmlElement xml, String operationName) throws DocumentedException{
             xml.checkName(operationName);
             xml.checkNamespace(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
         }
index 1daccd265cc2c094d1617df94a2b1e1951e3508f..41d488aee9a9a668705472e6dbeb1a3d8d86d88a 100644 (file)
@@ -9,19 +9,19 @@
 package org.opendaylight.controller.netconf.mdsal.connector.ops.get;
 
 import com.google.common.base.Optional;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorSeverity;
+import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorTag;
+import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorType;
+import org.opendaylight.controller.config.util.xml.XmlElement;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 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.DOMDataReadWriteTransaction;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorSeverity;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorTag;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorType;
 import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
 import org.opendaylight.controller.netconf.mdsal.connector.CurrentSchemaContext;
 import org.opendaylight.controller.netconf.mdsal.connector.TransactionProvider;
 import org.opendaylight.controller.netconf.mdsal.connector.ops.Datastore;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.slf4j.Logger;
@@ -42,7 +42,7 @@ public class Get extends AbstractGet {
     }
 
     @Override
-    protected Element handleWithNoSubsequentOperations(Document document, XmlElement operationElement) throws NetconfDocumentedException {
+    protected Element handleWithNoSubsequentOperations(Document document, XmlElement operationElement) throws DocumentedException {
 
         final Optional<YangInstanceIdentifier> dataRootOptional = getDataRootFromFilter(operationElement);
         if (!dataRootOptional.isPresent()) {
@@ -67,13 +67,13 @@ public class Get extends AbstractGet {
         }
     }
 
-    private DOMDataReadWriteTransaction getTransaction(Datastore datastore) throws NetconfDocumentedException{
+    private DOMDataReadWriteTransaction getTransaction(Datastore datastore) throws DocumentedException{
         if (datastore == Datastore.candidate) {
             return transactionProvider.getOrCreateTransaction();
         } else if (datastore == Datastore.running) {
             return transactionProvider.createRunningTransaction();
         }
-        throw new NetconfDocumentedException("Incorrect Datastore: ", ErrorType.protocol, ErrorTag.bad_element, ErrorSeverity.error);
+        throw new DocumentedException("Incorrect Datastore: ", ErrorType.protocol, ErrorTag.bad_element, ErrorSeverity.error);
     }
 
     @Override
index 955666f2fe427dc9c9644878dcfdbafe8412762b..5f36ca5a3086f586aa3888daa97962d469fe577b 100644 (file)
@@ -10,19 +10,19 @@ package org.opendaylight.controller.netconf.mdsal.connector.ops.get;
 
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorSeverity;
+import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorTag;
+import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorType;
+import org.opendaylight.controller.config.util.xml.XmlElement;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 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.DOMDataReadWriteTransaction;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorSeverity;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorTag;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorType;
 import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
 import org.opendaylight.controller.netconf.mdsal.connector.CurrentSchemaContext;
 import org.opendaylight.controller.netconf.mdsal.connector.TransactionProvider;
 import org.opendaylight.controller.netconf.mdsal.connector.ops.Datastore;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.slf4j.Logger;
@@ -43,12 +43,12 @@ public class GetConfig extends AbstractGet {
     }
 
     @Override
-    protected Element handleWithNoSubsequentOperations(Document document, XmlElement operationElement) throws NetconfDocumentedException {
+    protected Element handleWithNoSubsequentOperations(Document document, XmlElement operationElement) throws DocumentedException {
         GetConfigExecution getConfigExecution = null;
         try {
             getConfigExecution = GetConfigExecution.fromXml(operationElement, OPERATION_NAME);
 
-        } catch (final NetconfDocumentedException e) {
+        } catch (final DocumentedException e) {
             LOG.warn("Get request processing failed on session: {}", getNetconfSessionIdForReporting(), e);
             throw e;
         }
@@ -81,13 +81,13 @@ public class GetConfig extends AbstractGet {
         }
     }
 
-    private DOMDataReadWriteTransaction getTransaction(Datastore datastore) throws NetconfDocumentedException{
+    private DOMDataReadWriteTransaction getTransaction(Datastore datastore) throws DocumentedException{
         if (datastore == Datastore.candidate) {
             return transactionProvider.getOrCreateTransaction();
         } else if (datastore == Datastore.running) {
             return transactionProvider.createRunningTransaction();
         }
-        throw new NetconfDocumentedException("Incorrect Datastore: ", ErrorType.protocol, ErrorTag.bad_element, ErrorSeverity.error);
+        throw new DocumentedException("Incorrect Datastore: ", ErrorType.protocol, ErrorTag.bad_element, ErrorSeverity.error);
     }
 
     @Override
index 1b680368aae92135cbadc79cfca0484919d0c060..3e17c16679eb839774e907f2b125afea54c0e39c 100644 (file)
@@ -37,12 +37,14 @@ import org.custommonkey.xmlunit.XMLUnit;
 import org.junit.Before;
 import org.junit.Test;
 import org.opendaylight.controller.cluster.datastore.ConcurrentDOMDataBroker;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorSeverity;
+import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorTag;
+import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorType;
+import org.opendaylight.controller.config.util.xml.XmlElement;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStoreFactory;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorSeverity;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorTag;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorType;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperation;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperationChainedExecution;
 import org.opendaylight.controller.netconf.mdsal.connector.CurrentSchemaContext;
@@ -51,8 +53,6 @@ import org.opendaylight.controller.netconf.mdsal.connector.ops.get.Get;
 import org.opendaylight.controller.netconf.mdsal.connector.ops.get.GetConfig;
 import org.opendaylight.controller.netconf.util.test.NetconfXmlUnitRecursiveQualifier;
 import org.opendaylight.controller.netconf.util.test.XmlFileLoader;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.opendaylight.controller.sal.core.api.model.SchemaService;
 import org.opendaylight.controller.sal.core.spi.data.DOMStore;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
@@ -152,7 +152,7 @@ public class NetconfMDSalMappingTest {
         try {
             discardChanges();
             fail("Should have failed, need to execute an edit before discard");
-        } catch (NetconfDocumentedException e) {
+        } catch (DocumentedException e) {
             assertTrue(e.getErrorSeverity() == ErrorSeverity.error);
             assertTrue(e.getErrorTag() == ErrorTag.operation_failed);
             assertTrue(e.getErrorType() == ErrorType.application);
@@ -165,7 +165,7 @@ public class NetconfMDSalMappingTest {
         try {
             executeOperation(new GetConfig(sessionIdForReporting, currentSchemaContext, transactionProvider), "messages/mapping/bad_getConfig.xml");
             fail("Should have failed, this is an incorrect request");
-        } catch (NetconfDocumentedException e) {
+        } catch (DocumentedException e) {
             assertTrue(e.getErrorSeverity() == ErrorSeverity.error);
             assertTrue(e.getErrorTag() == ErrorTag.operation_failed);
             assertTrue(e.getErrorType() == ErrorType.application);
@@ -174,7 +174,7 @@ public class NetconfMDSalMappingTest {
         try {
             executeOperation(new GetConfig(sessionIdForReporting, currentSchemaContext, transactionProvider), "messages/mapping/bad_namespace_getConfig.xml");
             fail("Should have failed, this is an incorrect request");
-        } catch (NetconfDocumentedException e) {
+        } catch (DocumentedException e) {
             assertTrue(e.getErrorSeverity() == ErrorSeverity.error);
             assertTrue(e.getErrorTag() == ErrorTag.operation_failed);
             assertTrue(e.getErrorType() == ErrorType.application);
@@ -189,7 +189,7 @@ public class NetconfMDSalMappingTest {
         try {
             edit("messages/mapping/editConfigs/editConfig_running.xml");
             fail("Should have failed - edit config on running datastore is not supported");
-        } catch (NetconfDocumentedException e) {
+        } catch (DocumentedException e) {
             assertTrue(e.getErrorSeverity() == ErrorSeverity.error);
             assertTrue(e.getErrorTag() == ErrorTag.operation_not_supported);
             assertTrue(e.getErrorType() == ErrorType.protocol);
@@ -274,7 +274,7 @@ public class NetconfMDSalMappingTest {
         try {
             lock();
             fail("Should have failed - locking of running datastore is not supported");
-        } catch (NetconfDocumentedException e) {
+        } catch (DocumentedException e) {
             assertTrue(e.getErrorSeverity() == ErrorSeverity.error);
             assertTrue(e.getErrorTag() == ErrorTag.operation_not_supported);
             assertTrue(e.getErrorType() == ErrorType.application);
@@ -284,7 +284,7 @@ public class NetconfMDSalMappingTest {
         try {
             lockWithoutTarget();
             fail("Should have failed, target is missing");
-        } catch (NetconfDocumentedException e) {
+        } catch (DocumentedException e) {
             assertTrue(e.getErrorSeverity() == ErrorSeverity.error);
             assertTrue(e.getErrorTag() == ErrorTag.invalid_value);
             assertTrue(e.getErrorType() == ErrorType.application);
@@ -299,7 +299,7 @@ public class NetconfMDSalMappingTest {
         try {
             unlock();
             fail("Should have failed - unlocking of running datastore is not supported");
-        } catch (NetconfDocumentedException e) {
+        } catch (DocumentedException e) {
             assertTrue(e.getErrorSeverity() == ErrorSeverity.error);
             assertTrue(e.getErrorTag() == ErrorTag.operation_not_supported);
             assertTrue(e.getErrorType() == ErrorType.application);
@@ -308,7 +308,7 @@ public class NetconfMDSalMappingTest {
         try {
             unlockWithoutTarget();
             fail("Should have failed, target is missing");
-        } catch (NetconfDocumentedException e) {
+        } catch (DocumentedException e) {
             assertTrue(e.getErrorSeverity() == ErrorSeverity.error);
             assertTrue(e.getErrorTag() == ErrorTag.invalid_value);
             assertTrue(e.getErrorType() == ErrorType.application);
@@ -325,7 +325,7 @@ public class NetconfMDSalMappingTest {
         try {
             edit("messages/mapping/editConfigs/editConfig_create.xml");
             fail("Create should have failed - data already exists");
-        } catch (NetconfDocumentedException e) {
+        } catch (DocumentedException e) {
             assertTrue(e.getErrorSeverity() == ErrorSeverity.error);
             assertTrue(e.getErrorTag() == ErrorTag.data_exists);
             assertTrue(e.getErrorType() == ErrorType.protocol);
@@ -344,7 +344,7 @@ public class NetconfMDSalMappingTest {
         try {
             edit("messages/mapping/editConfigs/editConfig_delete-top.xml");
             fail("Delete should have failed - data is missing");
-        } catch (NetconfDocumentedException e) {
+        } catch (DocumentedException e) {
             assertTrue(e.getErrorSeverity() == ErrorSeverity.error);
             assertTrue(e.getErrorTag() == ErrorTag.data_missing);
             assertTrue(e.getErrorType() == ErrorType.protocol);
@@ -401,7 +401,7 @@ public class NetconfMDSalMappingTest {
         try {
             edit("messages/mapping/editConfigs/editConfig_merge_multiple_operations_4_create_existing.xml");
             fail();
-        } catch (NetconfDocumentedException e) {
+        } catch (DocumentedException e) {
             assertTrue(e.getErrorSeverity() == ErrorSeverity.error);
             assertTrue(e.getErrorTag() == ErrorTag.data_exists);
             assertTrue(e.getErrorType() == ErrorType.protocol);
@@ -414,7 +414,7 @@ public class NetconfMDSalMappingTest {
         try {
             edit("messages/mapping/editConfigs/editConfig_merge_multiple_operations_4_delete-non-existing.xml");
             fail();
-        } catch (NetconfDocumentedException e) {
+        } catch (DocumentedException e) {
             assertTrue(e.getErrorSeverity() == ErrorSeverity.error);
             assertTrue(e.getErrorTag() == ErrorTag.data_missing);
             assertTrue(e.getErrorType() == ErrorType.protocol);
@@ -510,7 +510,7 @@ public class NetconfMDSalMappingTest {
             super(sessionId, schemaContext, transactionProvider);
         }
 
-        public YangInstanceIdentifier getInstanceIdentifierFromDocument(Document request) throws NetconfDocumentedException {
+        public YangInstanceIdentifier getInstanceIdentifierFromDocument(Document request) throws DocumentedException {
             XmlElement filterElement = XmlElement.fromDomDocument(request).getOnlyChildElement(GET_CONFIG).getOnlyChildElement(FILTER_NODE);
             return getInstanceIdentifierFromFilter(filterElement);
         }
@@ -550,77 +550,77 @@ public class NetconfMDSalMappingTest {
 
     }
 
-    private Document commit() throws NetconfDocumentedException, ParserConfigurationException, SAXException, IOException {
+    private Document commit() throws DocumentedException, ParserConfigurationException, SAXException, IOException {
         Commit commit = new Commit(sessionIdForReporting, transactionProvider);
         return executeOperation(commit, "messages/mapping/commit.xml");
     }
 
-    private Document discardChanges() throws NetconfDocumentedException, ParserConfigurationException, SAXException, IOException {
+    private Document discardChanges() throws DocumentedException, ParserConfigurationException, SAXException, IOException {
         DiscardChanges discardOp = new DiscardChanges(sessionIdForReporting, transactionProvider);
         return executeOperation(discardOp, "messages/mapping/discardChanges.xml");
     }
 
-    private Document edit(String resource) throws NetconfDocumentedException, ParserConfigurationException, SAXException, IOException {
+    private Document edit(String resource) throws DocumentedException, ParserConfigurationException, SAXException, IOException {
         EditConfig editConfig = new EditConfig(sessionIdForReporting, currentSchemaContext, transactionProvider);
         return executeOperation(editConfig, resource);
     }
 
-    private Document get() throws NetconfDocumentedException, ParserConfigurationException, SAXException, IOException {
+    private Document get() throws DocumentedException, ParserConfigurationException, SAXException, IOException {
         Get get = new Get(sessionIdForReporting, currentSchemaContext, transactionProvider);
         return executeOperation(get, "messages/mapping/get.xml");
     }
 
-    private Document getWithFilter(String resource) throws NetconfDocumentedException, ParserConfigurationException, SAXException, IOException {
+    private Document getWithFilter(String resource) throws DocumentedException, ParserConfigurationException, SAXException, IOException {
         Get get = new Get(sessionIdForReporting, currentSchemaContext, transactionProvider);
         return executeOperation(get, resource);
     }
 
-    private Document getConfigRunning() throws NetconfDocumentedException, ParserConfigurationException, SAXException, IOException {
+    private Document getConfigRunning() throws DocumentedException, ParserConfigurationException, SAXException, IOException {
         GetConfig getConfig = new GetConfig(sessionIdForReporting, currentSchemaContext, transactionProvider);
         return executeOperation(getConfig, "messages/mapping/getConfig.xml");
     }
 
-    private Document getConfigCandidate() throws NetconfDocumentedException, ParserConfigurationException, SAXException, IOException {
+    private Document getConfigCandidate() throws DocumentedException, ParserConfigurationException, SAXException, IOException {
         GetConfig getConfig = new GetConfig(sessionIdForReporting, currentSchemaContext, transactionProvider);
         return executeOperation(getConfig, "messages/mapping/getConfig_candidate.xml");
     }
 
-    private Document getConfigWithFilter(String resource) throws NetconfDocumentedException, ParserConfigurationException, SAXException, IOException {
+    private Document getConfigWithFilter(String resource) throws DocumentedException, ParserConfigurationException, SAXException, IOException {
         GetConfig getConfig = new GetConfig(sessionIdForReporting, currentSchemaContext, transactionProvider);
         return executeOperation(getConfig, resource);
     }
 
-    private Document lock() throws NetconfDocumentedException, ParserConfigurationException, SAXException, IOException {
+    private Document lock() throws DocumentedException, ParserConfigurationException, SAXException, IOException {
         Lock lock = new Lock(sessionIdForReporting);
         return executeOperation(lock, "messages/mapping/lock.xml");
     }
 
-    private Document unlock() throws NetconfDocumentedException, ParserConfigurationException, SAXException, IOException {
+    private Document unlock() throws DocumentedException, ParserConfigurationException, SAXException, IOException {
         Unlock unlock = new Unlock(sessionIdForReporting);
         return executeOperation(unlock, "messages/mapping/unlock.xml");
     }
 
-    private Document lockWithoutTarget() throws NetconfDocumentedException, ParserConfigurationException, SAXException, IOException {
+    private Document lockWithoutTarget() throws DocumentedException, ParserConfigurationException, SAXException, IOException {
         Lock lock = new Lock(sessionIdForReporting);
         return executeOperation(lock, "messages/mapping/lock_notarget.xml");
     }
 
-    private Document unlockWithoutTarget() throws NetconfDocumentedException, ParserConfigurationException, SAXException, IOException {
+    private Document unlockWithoutTarget() throws DocumentedException, ParserConfigurationException, SAXException, IOException {
         Unlock unlock = new Unlock(sessionIdForReporting);
         return executeOperation(unlock, "messages/mapping/unlock_notarget.xml");
     }
 
-    private Document lockCandidate() throws NetconfDocumentedException, ParserConfigurationException, SAXException, IOException {
+    private Document lockCandidate() throws DocumentedException, ParserConfigurationException, SAXException, IOException {
         Lock lock = new Lock(sessionIdForReporting);
         return executeOperation(lock, "messages/mapping/lock_candidate.xml");
     }
 
-    private Document unlockCandidate() throws NetconfDocumentedException, ParserConfigurationException, SAXException, IOException {
+    private Document unlockCandidate() throws DocumentedException, ParserConfigurationException, SAXException, IOException {
         Unlock unlock = new Unlock(sessionIdForReporting);
         return executeOperation(unlock, "messages/mapping/unlock_candidate.xml");
     }
 
-    private Document executeOperation(NetconfOperation op, String filename) throws ParserConfigurationException, SAXException, IOException, NetconfDocumentedException {
+    private Document executeOperation(NetconfOperation op, String filename) throws ParserConfigurationException, SAXException, IOException, DocumentedException {
         final Document request = XmlFileLoader.xmlFileToDocument(filename);
         final Document response = op.handle(request, NetconfOperationChainedExecution.EXECUTION_TERMINATION_POINT);
 
index aa6ff06c5f77b3beac4d5bd7524f7ad8af8709bd..02a9514651a957f2d8a6f7110de18f5233d98f3e 100644 (file)
@@ -40,20 +40,20 @@ import org.junit.Test;
 import org.mockito.Mock;
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorSeverity;
+import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorTag;
+import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorType;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 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.controller.md.sal.dom.spi.DefaultDOMRpcResult;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorSeverity;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorTag;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorType;
 import org.opendaylight.controller.netconf.mapping.api.HandlingPriority;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperationChainedExecution;
 import org.opendaylight.controller.netconf.mdsal.connector.CurrentSchemaContext;
 import org.opendaylight.controller.netconf.util.test.XmlFileLoader;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.opendaylight.controller.sal.core.api.model.SchemaService;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.common.RpcError;
@@ -225,7 +225,7 @@ public class RuntimeRpcTest {
         try {
             rpc.handle(rpcDocument, NetconfOperationChainedExecution.EXECUTION_TERMINATION_POINT);
             fail("should have failed with rpc invocation not implemented yet");
-        } catch (NetconfDocumentedException e) {
+        } catch (DocumentedException e) {
             assertTrue(e.getErrorType() == ErrorType.application);
             assertTrue(e.getErrorSeverity() == ErrorSeverity.error);
             assertTrue(e.getErrorTag() == ErrorTag.operation_failed);
@@ -253,7 +253,7 @@ public class RuntimeRpcTest {
         try {
             rpc.handle(rpcDocument, NetconfOperationChainedExecution.EXECUTION_TERMINATION_POINT);
             fail("Should have failed, rpc has bad namespace");
-        } catch (NetconfDocumentedException e) {
+        } catch (DocumentedException e) {
             assertTrue(e.getErrorSeverity() == ErrorSeverity.error);
             assertTrue(e.getErrorTag() == ErrorTag.bad_element);
             assertTrue(e.getErrorType() == ErrorType.application);
index 04585e183398a272d5cd8ba0de8b06b3d49c285b..b02a6d291c9e118f6ba14753c0c8b198a47884b6 100644 (file)
         <plugin>
             <groupId>org.opendaylight.yangtools</groupId>
             <artifactId>yang-maven-plugin</artifactId>
-            <executions>
-                <execution>
-                    <id>config</id>
-                    <goals>
-                        <goal>generate-sources</goal>
-                    </goals>
-                    <configuration>
-                        <codeGenerators>
-                            <generator>
-                                <codeGeneratorClass>org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator</codeGeneratorClass>
-                                <outputBaseDir>${jmxGeneratorPath}</outputBaseDir>
-                                <additionalConfiguration>
-                                    <namespaceToPackage1>urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang</namespaceToPackage1>
-                                </additionalConfiguration>
-                            </generator>
-                            <generator>
-                                <codeGeneratorClass>org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl</codeGeneratorClass>
-                                <outputBaseDir>${salGeneratorPath}</outputBaseDir>
-                            </generator>
-                        </codeGenerators>
-                        <inspectDependencies>true</inspectDependencies>
-                    </configuration>
-                </execution>
-            </executions>
-            <dependencies>
-                <dependency>
-                    <groupId>org.opendaylight.controller</groupId>
-                    <artifactId>yang-jmx-generator-plugin</artifactId>
-                    <version>${config.version}</version>
-                </dependency>
-            </dependencies>
         </plugin>
     </plugins>
   </build>
index 3c73c2c84c5f893b9058bb123033c3be9869a633..8256627d0190d29f363ba93c51a38f3403d5498a 100644 (file)
@@ -2,7 +2,7 @@ package org.opendaylight.controller.config.yang.netconf.mdsal.monitoring;
 
 import java.util.Collections;
 import java.util.Set;
-import org.opendaylight.controller.netconf.api.Capability;
+import org.opendaylight.controller.config.util.capability.Capability;
 import org.opendaylight.controller.netconf.api.monitoring.CapabilityListener;
 import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperation;
index cac15044f0fe0b57dd45dec7d14b8e7f89539e48..b959fa5c52935835042d577ef28dce19a9d5402e 100644 (file)
@@ -10,7 +10,7 @@ package org.opendaylight.controller.netconf.monitoring;
 
 import java.util.Collections;
 import java.util.Set;
-import org.opendaylight.controller.netconf.api.Capability;
+import org.opendaylight.controller.config.util.capability.Capability;
 import org.opendaylight.controller.netconf.api.monitoring.CapabilityListener;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactory;
similarity index 96%
rename from opendaylight/netconf/ietf-netconf-monitoring-extension/pom.xml
rename to opendaylight/netconf/models/ietf-netconf-monitoring-extension/pom.xml
index 760261b1e40e3a39eb0ad5c831f7ec485a79bdb9..0824b750fcd3bd76d68d71122ef4544db65f3320 100644 (file)
@@ -3,7 +3,7 @@
   <modelVersion>4.0.0</modelVersion>
   <parent>
     <groupId>org.opendaylight.controller</groupId>
-    <artifactId>netconf-subsystem</artifactId>
+    <artifactId>netconf-models</artifactId>
     <version>0.4.0-SNAPSHOT</version>
   </parent>
   <artifactId>ietf-netconf-monitoring-extension</artifactId>
similarity index 97%
rename from opendaylight/netconf/ietf-netconf-monitoring/pom.xml
rename to opendaylight/netconf/models/ietf-netconf-monitoring/pom.xml
index e4819c0a444e01360c85c15716954e52d465890f..68b5558accf2ce102ffa846cd6a535a02cf623d1 100644 (file)
@@ -3,7 +3,7 @@
   <modelVersion>4.0.0</modelVersion>
   <parent>
     <groupId>org.opendaylight.controller</groupId>
-    <artifactId>netconf-subsystem</artifactId>
+    <artifactId>netconf-models</artifactId>
     <version>0.4.0-SNAPSHOT</version>
   </parent>
   <artifactId>ietf-netconf-monitoring</artifactId>
similarity index 97%
rename from opendaylight/netconf/ietf-netconf-notifications/pom.xml
rename to opendaylight/netconf/models/ietf-netconf-notifications/pom.xml
index 763cb82c36b44d4b9764cf73e9c938a51db48c5c..f223634000e8e146abed68d870fa15ab374efc58 100644 (file)
@@ -11,7 +11,7 @@
   <modelVersion>4.0.0</modelVersion>
   <parent>
     <groupId>org.opendaylight.controller</groupId>
-    <artifactId>netconf-subsystem</artifactId>
+    <artifactId>netconf-models</artifactId>
     <version>0.4.0-SNAPSHOT</version>
   </parent>
   <artifactId>ietf-netconf-notifications</artifactId>
similarity index 97%
rename from opendaylight/netconf/ietf-netconf/pom.xml
rename to opendaylight/netconf/models/ietf-netconf/pom.xml
index 43ba3b17aa1f77888c044abb4b6710cd3f5fef7d..f2db7577ea58ca3b851eb0d3b7b2b4dba8ea7369 100644 (file)
@@ -11,7 +11,7 @@
     <modelVersion>4.0.0</modelVersion>
     <parent>
         <groupId>org.opendaylight.controller</groupId>
-        <artifactId>netconf-subsystem</artifactId>
+        <artifactId>netconf-models</artifactId>
         <version>0.4.0-SNAPSHOT</version>
     </parent>
     <artifactId>ietf-netconf</artifactId>
diff --git a/opendaylight/netconf/models/pom.xml b/opendaylight/netconf/models/pom.xml
new file mode 100644 (file)
index 0000000..bf87e42
--- /dev/null
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.opendaylight.controller</groupId>
+    <artifactId>netconf-subsystem</artifactId>
+    <version>0.4.0-SNAPSHOT</version>
+  </parent>
+  <artifactId>netconf-models</artifactId>
+
+  <version>0.4.0-SNAPSHOT</version>
+  <packaging>pom</packaging>
+  <name>${project.artifactId}</name>
+
+  <modules>
+    <module>ietf-netconf</module>
+    <module>ietf-netconf-monitoring</module>
+    <module>ietf-netconf-notifications</module>
+    <module>ietf-netconf-monitoring-extension</module>
+  </modules>
+
+  <build>
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <groupId>org.apache.felix</groupId>
+          <artifactId>maven-bundle-plugin</artifactId>
+          <extensions>true</extensions>
+          <configuration>
+            <instructions>
+              <Bundle-Name>${project.groupId}.${project.artifactId}</Bundle-Name>
+            </instructions>
+          </configuration>
+        </plugin>
+        <plugin>
+          <groupId>org.opendaylight.yangtools</groupId>
+          <artifactId>yang-maven-plugin</artifactId>
+        </plugin>
+      </plugins>
+
+    </pluginManagement>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-checkstyle-plugin</artifactId>
+        <configuration>
+          <failsOnError>false</failsOnError>
+          <failOnViolation>true</failOnViolation>
+          <configLocation>checkstyle-logging.xml</configLocation>
+          <consoleOutput>true</consoleOutput>
+          <includeTestSourceDirectory>true</includeTestSourceDirectory>
+          <sourceDirectory>${project.basedir}</sourceDirectory>
+          <includes>**\/*.java,**\/*.xml,**\/*.ini,**\/*.sh,**\/*.bat,**\/*.yang</includes>
+          <excludes>**\/target\/,**\/bin\/,**\/target-ide\/,**\/${jmxGeneratorPath}\/,**\/${salGeneratorPath}\/,**\/netconf\/test\/tool\/Main.java, **\/netconf\/test\/tool\/client\/stress\/StressClient.java</excludes>
+        </configuration>
+        <dependencies>
+          <dependency>
+            <groupId>org.opendaylight.yangtools</groupId>
+            <artifactId>checkstyle-logging</artifactId>
+            <version>${yangtools.version}</version>
+          </dependency>
+        </dependencies>
+        <executions>
+          <execution>
+            <goals>
+              <goal>check</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+      </plugin>
+    </plugins>
+  </build>
+</project>
index d1c2af36ffe93b5f0b093067db511c0bf61cec0c..6b5299111d3e877008e59b5427a8b6e4928f1e13 100644 (file)
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>config-api</artifactId>
     </dependency>
+      <dependency>
+          <groupId>org.opendaylight.controller</groupId>
+          <artifactId>config-manager-facade-xml</artifactId>
+      </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>protocol-framework</artifactId>
         <plugin>
             <groupId>org.opendaylight.yangtools</groupId>
             <artifactId>yang-maven-plugin</artifactId>
-            <executions>
-                <execution>
-                    <id>config</id>
-                    <goals>
-                        <goal>generate-sources</goal>
-                    </goals>
-                    <configuration>
-                        <codeGenerators>
-                            <generator>
-                                <codeGeneratorClass>org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator</codeGeneratorClass>
-                                <outputBaseDir>${jmxGeneratorPath}</outputBaseDir>
-                                <additionalConfiguration>
-                                    <namespaceToPackage1>urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang</namespaceToPackage1>
-                                </additionalConfiguration>
-                            </generator>
-                            <generator>
-                                <codeGeneratorClass>org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl</codeGeneratorClass>
-                                <outputBaseDir>${salGeneratorPath}</outputBaseDir>
-                            </generator>
-                        </codeGenerators>
-                        <inspectDependencies>true</inspectDependencies>
-                    </configuration>
-                </execution>
-            </executions>
-            <dependencies>
-                <dependency>
-                    <groupId>org.opendaylight.controller</groupId>
-                    <artifactId>yang-jmx-generator-plugin</artifactId>
-                    <version>${config.version}</version>
-                </dependency>
-            </dependencies>
         </plugin>
     </plugins>
   </build>
diff --git a/opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/Capability.java b/opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/Capability.java
deleted file mode 100644 (file)
index 6a061b1..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.api;
-
-import com.google.common.base.Optional;
-import java.util.Collection;
-
-/**
- * Contains capability URI announced by server hello message and optionally its
- * corresponding yang schema that can be retrieved by get-schema rpc.
- */
-public interface Capability {
-
-    public String getCapabilityUri();
-
-    public Optional<String> getModuleNamespace();
-
-    public Optional<String> getModuleName();
-
-    public Optional<String> getRevision();
-
-    public Optional<String> getCapabilitySchema();
-
-    public Collection<String> getLocation();
-}
index e1e932b55a31e709a5618dc23818cc848d07e088..9cf78c930be985c47b373501d982d723b1408f3f 100644 (file)
 
 package org.opendaylight.controller.netconf.api;
 
-import static org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants.ERROR_INFO;
-import static org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants.ERROR_MESSAGE;
-import static org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants.ERROR_SEVERITY;
-import static org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants.ERROR_TAG;
-import static org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants.ERROR_TYPE;
-import static org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants.RPC_ERROR;
-import static org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants.RPC_REPLY_KEY;
-import static org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0;
-
-import java.util.Collections;
-import java.util.HashMap;
 import java.util.Map;
-import java.util.Map.Entry;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import org.opendaylight.controller.config.api.ConflictingVersionException;
-import org.opendaylight.controller.config.api.ValidationException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
 import org.w3c.dom.Document;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
 
 /**
  * Checked exception to communicate an error that needs to be sent to the
  * netconf client.
  */
-public class NetconfDocumentedException extends Exception {
-
-    private static final long serialVersionUID = 1L;
-
-    private final static Logger LOG = LoggerFactory.getLogger( NetconfDocumentedException.class );
-
-    private static final DocumentBuilderFactory BUILDER_FACTORY;
-
-    static {
-        BUILDER_FACTORY = DocumentBuilderFactory.newInstance();
-        try {
-            BUILDER_FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
-            BUILDER_FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false);
-            BUILDER_FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
-            BUILDER_FACTORY.setXIncludeAware(false);
-            BUILDER_FACTORY.setExpandEntityReferences(false);
-        } catch (ParserConfigurationException e) {
-            throw new ExceptionInInitializerError(e);
-        }
-        BUILDER_FACTORY.setNamespaceAware(true);
-        BUILDER_FACTORY.setCoalescing(true);
-        BUILDER_FACTORY.setIgnoringElementContentWhitespace(true);
-        BUILDER_FACTORY.setIgnoringComments(true);
-    }
-
-    public enum ErrorType {
-        transport, rpc, protocol, application;
-
-        public String getTagValue() {
-            return name();
-        }
-
-        public static ErrorType from( String text ) {
-            try {
-                return valueOf( text );
-            }
-            catch( Exception e ) {
-                return application;
-            }
-        }
-    }
-
-    public enum ErrorTag {
-        access_denied("access-denied"),
-        bad_attribute("bad-attribute"),
-        bad_element("bad-element"),
-        data_exists("data-exists"),
-        data_missing("data-missing"),
-        in_use("in-use"),
-        invalid_value("invalid-value"),
-        lock_denied("lock-denied"),
-        malformed_message("malformed-message"),
-        missing_attribute("missing-attribute"),
-        missing_element("missing-element"),
-        operation_failed("operation-failed"),
-        operation_not_supported("operation-not-supported"),
-        resource_denied("resource-denied"),
-        rollback_failed("rollback-failed"),
-        too_big("too-big"),
-        unknown_attribute("unknown-attribute"),
-        unknown_element("unknown-element"),
-        unknown_namespace("unknown-namespace");
-
-        private final String tagValue;
-
-        ErrorTag(final String tagValue) {
-            this.tagValue = tagValue;
-        }
-
-        public String getTagValue() {
-            return this.tagValue;
-        }
+public class NetconfDocumentedException extends DocumentedException {
 
-        public static ErrorTag from( String text ) {
-            for( ErrorTag e: values() )
-            {
-                if( e.getTagValue().equals( text ) ) {
-                    return e;
-                }
-            }
-
-            return operation_failed;
-        }
-    }
-
-    public enum ErrorSeverity {
-        error, warning;
-
-        public String getTagValue() {
-            return name();
-        }
-
-        public static ErrorSeverity from( String text ) {
-            try {
-                return valueOf( text );
-            }
-            catch( Exception e ) {
-                return error;
-            }
-        }
-    }
-
-    private final ErrorType errorType;
-    private final ErrorTag errorTag;
-    private final ErrorSeverity errorSeverity;
-    private final Map<String, String> errorInfo;
-
-    public NetconfDocumentedException(String message) {
-        this(message,
-                NetconfDocumentedException.ErrorType.application,
-                NetconfDocumentedException.ErrorTag.invalid_value,
-                NetconfDocumentedException.ErrorSeverity.error
-        );
-    }
-
-    public NetconfDocumentedException(final String message, final ErrorType errorType, final ErrorTag errorTag,
-            final ErrorSeverity errorSeverity) {
-        this(message, errorType, errorTag, errorSeverity, Collections.<String, String> emptyMap());
-    }
-
-    public NetconfDocumentedException(final String message, final ErrorType errorType, final ErrorTag errorTag,
-            final ErrorSeverity errorSeverity, final Map<String, String> errorInfo) {
+    public NetconfDocumentedException(final String message) {
         super(message);
-        this.errorType = errorType;
-        this.errorTag = errorTag;
-        this.errorSeverity = errorSeverity;
-        this.errorInfo = errorInfo;
     }
 
-    public NetconfDocumentedException(final String message, final Exception cause, final ErrorType errorType,
-            final ErrorTag errorTag, final ErrorSeverity errorSeverity) {
-        this(message, cause, errorType, errorTag, errorSeverity, Collections.<String, String> emptyMap());
+    public NetconfDocumentedException(final String message, final ErrorType errorType, final ErrorTag errorTag, final ErrorSeverity errorSeverity) {
+        super(message, errorType, errorTag, errorSeverity);
     }
 
-    public NetconfDocumentedException(final String message, final Exception cause, final ErrorType errorType,
-            final ErrorTag errorTag, final ErrorSeverity errorSeverity, final Map<String, String> errorInfo) {
-        super(message, cause);
-        this.errorType = errorType;
-        this.errorTag = errorTag;
-        this.errorSeverity = errorSeverity;
-        this.errorInfo = errorInfo;
+    public NetconfDocumentedException(final String message, final ErrorType errorType, final ErrorTag errorTag, final ErrorSeverity errorSeverity, final Map<String, String> errorInfo) {
+        super(message, errorType, errorTag, errorSeverity, errorInfo);
     }
 
-    public static <E extends Exception> NetconfDocumentedException wrap(E exception) throws NetconfDocumentedException {
-        final Map<String, String> errorInfo = new HashMap<>();
-        errorInfo.put(ErrorTag.operation_failed.name(), "Exception thrown");
-        throw new NetconfDocumentedException(exception.getMessage(), exception, ErrorType.application, ErrorTag.operation_failed,
-                ErrorSeverity.error, errorInfo);
-    }
-    public static NetconfDocumentedException wrap(ValidationException e) throws NetconfDocumentedException {
-        final Map<String, String> errorInfo = new HashMap<>();
-        errorInfo.put(ErrorTag.operation_failed.name(), "Validation failed");
-        throw new NetconfDocumentedException(e.getMessage(), e, ErrorType.application, ErrorTag.operation_failed,
-                ErrorSeverity.error, errorInfo);
+    public NetconfDocumentedException(final String message, final Exception cause, final ErrorType errorType, final ErrorTag errorTag, final ErrorSeverity errorSeverity) {
+        super(message, cause, errorType, errorTag, errorSeverity);
     }
 
-    public static NetconfDocumentedException wrap(ConflictingVersionException e) throws NetconfDocumentedException {
-        final Map<String, String> errorInfo = new HashMap<>();
-        errorInfo.put(ErrorTag.operation_failed.name(), "Optimistic lock failed");
-        throw new NetconfDocumentedException(e.getMessage(), e, ErrorType.application, ErrorTag.operation_failed,
-                ErrorSeverity.error, errorInfo);
-    }
-
-    public static NetconfDocumentedException fromXMLDocument( Document fromDoc ) {
-
-        ErrorType errorType = ErrorType.application;
-        ErrorTag errorTag = ErrorTag.operation_failed;
-        ErrorSeverity errorSeverity = ErrorSeverity.error;
-        Map<String, String> errorInfo = null;
-        String errorMessage = "";
-
-        Node rpcReply = fromDoc.getDocumentElement();
-
-        // FIXME: BUG? - we only handle one rpc-error.
-
-        NodeList replyChildren = rpcReply.getChildNodes();
-        for( int i = 0; i < replyChildren.getLength(); i++ ) {
-            Node replyChild = replyChildren.item( i );
-            if( RPC_ERROR.equals( replyChild.getNodeName() ) )
-            {
-                NodeList rpcErrorChildren = replyChild.getChildNodes();
-                for( int j = 0; j < rpcErrorChildren.getLength(); j++ )
-                {
-                    Node rpcErrorChild = rpcErrorChildren.item( j );
-                    if( ERROR_TYPE.equals( rpcErrorChild.getNodeName() ) ) {
-                        errorType = ErrorType.from( rpcErrorChild.getTextContent() );
-                    }
-                    else if( ERROR_TAG.equals( rpcErrorChild.getNodeName() ) ) {
-                        errorTag = ErrorTag.from( rpcErrorChild.getTextContent() );
-                    }
-                    else if( ERROR_SEVERITY.equals( rpcErrorChild.getNodeName() ) ) {
-                        errorSeverity = ErrorSeverity.from( rpcErrorChild.getTextContent() );
-                    }
-                    else if( ERROR_MESSAGE.equals( rpcErrorChild.getNodeName() ) ) {
-                        errorMessage = rpcErrorChild.getTextContent();
-                    }
-                    else if( ERROR_INFO.equals( rpcErrorChild.getNodeName() ) ) {
-                        errorInfo = parseErrorInfo( rpcErrorChild );
-                    }
-                }
-
-                break;
-            }
-        }
-
-        return new NetconfDocumentedException( errorMessage, errorType, errorTag, errorSeverity, errorInfo );
-    }
-
-    private static Map<String, String> parseErrorInfo( Node node ) {
-        Map<String, String> infoMap = new HashMap<>();
-        NodeList children = node.getChildNodes();
-        for( int i = 0; i < children.getLength(); i++ ) {
-            Node child = children.item( i );
-            if( child.getNodeType() == Node.ELEMENT_NODE ) {
-                infoMap.put( child.getNodeName(), child.getTextContent() );
-            }
-        }
-
-        return infoMap;
-    }
-
-    public ErrorType getErrorType() {
-        return this.errorType;
-    }
-
-    public ErrorTag getErrorTag() {
-        return this.errorTag;
-    }
-
-    public ErrorSeverity getErrorSeverity() {
-        return this.errorSeverity;
-    }
-
-    public Map<String, String> getErrorInfo() {
-        return this.errorInfo;
-    }
-
-    public Document toXMLDocument() {
-        Document doc = null;
-        try {
-            doc = BUILDER_FACTORY.newDocumentBuilder().newDocument();
-
-            Node rpcReply = doc.createElementNS( URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0, RPC_REPLY_KEY );
-            doc.appendChild( rpcReply );
-
-            Node rpcError = doc.createElementNS( URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0, RPC_ERROR );
-            rpcReply.appendChild( rpcError );
-
-            rpcError.appendChild( createTextNode( doc, ERROR_TYPE, getErrorType().getTagValue() ) );
-            rpcError.appendChild( createTextNode( doc, ERROR_TAG, getErrorTag().getTagValue() ) );
-            rpcError.appendChild( createTextNode( doc, ERROR_SEVERITY, getErrorSeverity().getTagValue() ) );
-            rpcError.appendChild( createTextNode( doc, ERROR_MESSAGE, getLocalizedMessage() ) );
-
-            Map<String, String> errorInfoMap = getErrorInfo();
-            if( errorInfoMap != null && !errorInfoMap.isEmpty() ) {
-                /*
-                 * <error-info>
-                 *   <bad-attribute>message-id</bad-attribute>
-                 *   <bad-element>rpc</bad-element>
-                 * </error-info>
-                 */
-
-                Node errorInfoNode = doc.createElementNS( URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0, ERROR_INFO );
-                errorInfoNode.setPrefix( rpcReply.getPrefix() );
-                rpcError.appendChild( errorInfoNode );
-
-                for ( Entry<String, String> entry : errorInfoMap.entrySet() ) {
-                    errorInfoNode.appendChild( createTextNode( doc, entry.getKey(), entry.getValue() ) );
-                }
-            }
-        }
-        catch( ParserConfigurationException e ) {
-            LOG.error( "Error outputting to XML document", e ); // this shouldn't happen
-        }
-
-        return doc;
+    public NetconfDocumentedException(final String message, final Exception cause, final ErrorType errorType, final ErrorTag errorTag, final ErrorSeverity errorSeverity, final Map<String, String> errorInfo) {
+        super(message, cause, errorType, errorTag, errorSeverity, errorInfo);
     }
 
-    private Node createTextNode( Document doc, String tag, String textContent ) {
-        Node node = doc.createElementNS( URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0, tag );
-        node.setTextContent( textContent );
-        return node;
+    public NetconfDocumentedException(DocumentedException e) {
+        super(e.getMessage(), e.getErrorType(), e.getErrorTag(), e.getErrorSeverity(), e.getErrorInfo());
     }
 
-    @Override
-    public String toString() {
-        return "NetconfDocumentedException{" + "message=" + getMessage() + ", errorType=" + this.errorType
-                + ", errorTag=" + this.errorTag + ", errorSeverity=" + this.errorSeverity + ", errorInfo="
-                + this.errorInfo + '}';
+    public static NetconfDocumentedException fromXMLDocument( Document fromDoc) {
+        return new NetconfDocumentedException(DocumentedException.fromXMLDocument(fromDoc));
     }
 }
diff --git a/opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/jmx/CommitJMXNotification.java b/opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/jmx/CommitJMXNotification.java
deleted file mode 100644 (file)
index 4e3954a..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.api.jmx;
-
-import java.util.Set;
-import javax.management.NotificationBroadcasterSupport;
-import org.w3c.dom.Element;
-
-public class CommitJMXNotification extends NetconfJMXNotification {
-
-    private final Element configSnapshot;
-
-    private static final String AFTER_COMMIT_MESSAGE_TEMPLATE = "Commit successful: %s";
-    private final Set<String> capabilities;
-
-    CommitJMXNotification(NotificationBroadcasterSupport source, String message, Element cfgSnapshot,
-            Set<String> capabilities) {
-        super(TransactionProviderJMXNotificationType.commit, source, String.format(AFTER_COMMIT_MESSAGE_TEMPLATE, message));
-        this.configSnapshot = cfgSnapshot;
-        this.capabilities = capabilities;
-    }
-
-    public Element getConfigSnapshot() {
-        return configSnapshot;
-    }
-
-    public Set<String> getCapabilities() {
-        return capabilities;
-    }
-
-    @Override
-    public String toString() {
-        final StringBuffer sb = new StringBuffer("CommitJMXNotification{");
-        sb.append("configSnapshot=").append(configSnapshot);
-        sb.append(", capabilities=").append(getCapabilities());
-        sb.append('}');
-        return sb.toString();
-    }
-
-    /**
-     *
-     */
-    private static final long serialVersionUID = -8587623362011695514L;
-
-}
diff --git a/opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/jmx/DefaultCommitOperationMXBean.java b/opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/jmx/DefaultCommitOperationMXBean.java
deleted file mode 100644 (file)
index edc0bc9..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.api.jmx;
-
-import javax.management.ObjectName;
-import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
-
-public interface DefaultCommitOperationMXBean {
-
-    String TYPE_NAME = "NetconfNotificationProvider";
-    ObjectName OBJECT_NAME = ObjectNameUtil.createONWithDomainAndType(TYPE_NAME);
-
-}
diff --git a/opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/jmx/NetconfJMXNotification.java b/opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/jmx/NetconfJMXNotification.java
deleted file mode 100644 (file)
index cba98ee..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.api.jmx;
-
-import java.util.Set;
-import javax.management.Notification;
-import javax.management.NotificationBroadcasterSupport;
-import org.w3c.dom.Element;
-
-public abstract class NetconfJMXNotification extends Notification {
-
-    /**
-     *
-     */
-    private static final long serialVersionUID = 6754474563863772845L;
-
-    private static long sequenceNumber = 1;
-
-    private final TransactionProviderJMXNotificationType type;
-
-    protected NetconfJMXNotification(TransactionProviderJMXNotificationType type,
-            NotificationBroadcasterSupport source, String message) {
-        super(type.toString(), source, sequenceNumber++, System.nanoTime(), message);
-        this.type = type;
-    }
-
-    @Override
-    public String toString() {
-        return "TransactionProviderJMXNotification [type=" + type + "]";
-    }
-
-    /**
-     * Sends this notification using source that created it
-     */
-    public void send() {
-        ((NotificationBroadcasterSupport) getSource()).sendNotification(this);
-    }
-
-    /**
-     * Creates notification about successful commit execution.
-     *
-     * Intended for config-persister.
-     *
-     * @param transactionName
-     * @param cfgSnapshot
-     */
-    public static CommitJMXNotification afterCommit(NotificationBroadcasterSupport source, String message,
-            Element cfgSnapshot, Set<String> capabilities) {
-        return new CommitJMXNotification(source, message, cfgSnapshot, capabilities);
-    }
-
-    static enum TransactionProviderJMXNotificationType {
-        commit;
-    }
-
-}
index 5d9468c8ea1f57ce7b09fd0d1ee03b565cb74f11..0ea9f6b4937c6dcd78b95d5c793a5c969047717b 100644 (file)
@@ -9,11 +9,10 @@
 package org.opendaylight.controller.netconf.api.monitoring;
 
 import java.util.Set;
-import org.opendaylight.controller.netconf.api.Capability;
+import org.opendaylight.controller.config.util.capability.Capability;
 
 public interface CapabilityListener {
 
-    void onCapabilitiesAdded(Set<Capability> addedCaps);
+    void onCapabilitiesChanged(Set<Capability> added, Set<Capability> removed);
 
-    void onCapabilitiesRemoved(Set<Capability> removedCaps);
 }
index b9c4dcaf4a5cb5ce6c4123bf1a6dabe56a93cc34..4fec3cdd0fb6c2b4391d3904f74a485dd955550e 100644 (file)
@@ -8,6 +8,10 @@
 
 package org.opendaylight.controller.netconf.api.util;
 
+/**
+ * These constants mark operation service factories that are auto wired with netconf endpoint
+ * for config subsystem
+ */
 public final class NetconfConstants {
     /*
      * TODO define marker interface in mapping-api that the serviceFactories in cofing subsystem
index 1bcae151d7cc2d28895088dcc6bb8db282c4640a..3be447a249003087869cf65bb40e3dd3f9222ad4 100644 (file)
@@ -7,61 +7,35 @@
  */
 package org.opendaylight.controller.netconf.api.xml;
 
-public final class XmlNetconfConstants {
-
+import org.opendaylight.controller.config.util.xml.XmlMappingConstants;
 
+public final class XmlNetconfConstants {
 
     private XmlNetconfConstants() {}
 
-    public static final String MOUNTPOINTS = "mountpoints";
-    public static final String MOUNTPOINT = "mountpoint";
-    public static final String ID = "id";
     public static final String CAPABILITY = "capability";
     public static final String CAPABILITIES = "capabilities";
     public static final String COMMIT = "commit";
-    public static final String TYPE_KEY = "type";
-    public static final String MODULE_KEY = "module";
-    public static final String INSTANCE_KEY = "instance";
     public static final String OPERATION_ATTR_KEY = "operation";
-    public static final String SERVICES_KEY = "services";
     public static final String CONFIG_KEY = "config";
-    public static final String MODULES_KEY = "modules";
-    public static final String CONFIGURATION_KEY = "configuration";
     public static final String DATA_KEY = "data";
     public static final String OK = "ok";
     public static final String FILTER = "filter";
     public static final String SOURCE_KEY = "source";
     public static final String RPC_KEY = "rpc";
-    public static final String RPC_REPLY_KEY = "rpc-reply";
-    public static final String RPC_ERROR = "rpc-error";
-    public static final String ERROR_TYPE = "error-type";
-    public static final String ERROR_TAG = "error-tag";
-    public static final String ERROR_SEVERITY = "error-severity";
-    public static final String ERROR_APP_TAG = "error-app-tag";
-    public static final String ERROR_PATH = "error-path";
-    public static final String ERROR_MESSAGE = "error-message";
-    public static final String ERROR_INFO = "error-info";
-    public static final String NAME_KEY = "name";
     public static final String NOTIFICATION_ELEMENT_NAME = "notification";
 
-    public static final String PREFIX = "prefix";
-
     public static final String MESSAGE_ID = "message-id";
     public static final String SESSION_ID = "session-id";
 
-    //
-    // TODO duplicate
-    public static final String RFC4741_TARGET_NAMESPACE = "urn:ietf:params:xml:ns:netconf:base:1.0";
-    public static final String URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0 = "urn:ietf:params:xml:ns:netconf:base:1.0";
-//    public static final String URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_1 = "urn:ietf:params:xml:ns:netconf:base:1.1";
+    public static final String GET = "get";
+    public static final String GET_CONFIG = "get-config";
+
+    public static final String URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0 = XmlMappingConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0;
     public static final String URN_IETF_PARAMS_NETCONF_BASE_1_0 = "urn:ietf:params:netconf:base:1.0";
     public static final String URN_IETF_PARAMS_NETCONF_BASE_1_1 = "urn:ietf:params:netconf:base:1.1";
     public static final String URN_IETF_PARAMS_XML_NS_NETCONF_EXI_1_0 = "urn:ietf:params:xml:ns:netconf:exi:1.0";
 
     public static final String URN_IETF_PARAMS_NETCONF_CAPABILITY_EXI_1_0 = "urn:ietf:params:netconf:capability:exi:1.0";
     public static final String URN_IETF_PARAMS_XML_NS_YANG_IETF_NETCONF_MONITORING = "urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring";
-    // TODO where to store namespace of config ?
-    public static final String URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG = "urn:opendaylight:params:xml:ns:yang:controller:config";
-    public static final String GET = "get";
-    public static final String GET_CONFIG = "get-config";
 }
index dc18b106bf23ea6208bb28afd4c911d2bb7a9cc4..3621f83312982d5570d29c37541a5f8a6b51349f 100644 (file)
@@ -21,9 +21,7 @@ import javax.xml.xpath.XPathExpressionException;
 import javax.xml.xpath.XPathFactory;
 import org.junit.Before;
 import org.junit.Test;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorSeverity;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorTag;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorType;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
 import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
 import org.w3c.dom.Document;
 import org.w3c.dom.Node;
@@ -63,10 +61,10 @@ public class NetconfDocumentedExceptionTest {
     @Test
     public void testToAndFromXMLDocument() throws XPathExpressionException {
         String errorMessage = "mock error message";
-        NetconfDocumentedException ex = new NetconfDocumentedException( errorMessage, null,
-                                                                        ErrorType.protocol,
-                                                                        ErrorTag.data_exists,
-                                                                        ErrorSeverity.warning,
+        DocumentedException ex = new NetconfDocumentedException( errorMessage, null,
+                                                                        DocumentedException.ErrorType.protocol,
+                                                                        DocumentedException.ErrorTag.data_exists,
+                                                                        DocumentedException.ErrorSeverity.warning,
                                                                         ImmutableMap.of( "foo", "bar" ) );
 
         Document doc = ex.toXMLDocument();
@@ -82,17 +80,17 @@ public class NetconfDocumentedExceptionTest {
 
         Node errorTypeNode = getNode( "netconf:error-type", rpcErrorNode );
         assertNotNull( "error-type not found", errorTypeNode );
-        assertEquals( "error-type", ErrorType.protocol.getTagValue(),
+        assertEquals( "error-type", DocumentedException.ErrorType.protocol.getTagValue(),
                       errorTypeNode.getTextContent() );
 
         Node errorTagNode = getNode( "netconf:error-tag", rpcErrorNode );
         assertNotNull( "error-tag not found", errorTagNode );
-        assertEquals( "error-tag", ErrorTag.data_exists.getTagValue(),
+        assertEquals( "error-tag", DocumentedException.ErrorTag.data_exists.getTagValue(),
                       errorTagNode.getTextContent() );
 
         Node errorSeverityNode = getNode( "netconf:error-severity", rpcErrorNode );
         assertNotNull( "error-severity not found", errorSeverityNode );
-        assertEquals( "error-severity", ErrorSeverity.warning.getTagValue(),
+        assertEquals( "error-severity", DocumentedException.ErrorSeverity.warning.getTagValue(),
                       errorSeverityNode.getTextContent() );
 
         Node errorInfoNode = getNode( "netconf:error-info/netconf:foo", rpcErrorNode );
@@ -105,12 +103,12 @@ public class NetconfDocumentedExceptionTest {
 
         // Test fromXMLDocument
 
-        ex = NetconfDocumentedException.fromXMLDocument( doc );
+        ex = DocumentedException.fromXMLDocument( doc );
 
         assertNotNull( "NetconfDocumentedException is null", ex );
-        assertEquals( "getErrorSeverity", ErrorSeverity.warning, ex.getErrorSeverity() );
-        assertEquals( "getErrorTag", ErrorTag.data_exists, ex.getErrorTag() );
-        assertEquals( "getErrorType", ErrorType.protocol, ex.getErrorType() );
+        assertEquals( "getErrorSeverity", DocumentedException.ErrorSeverity.warning, ex.getErrorSeverity() );
+        assertEquals( "getErrorTag", DocumentedException.ErrorTag.data_exists, ex.getErrorTag() );
+        assertEquals( "getErrorType", DocumentedException.ErrorType.protocol, ex.getErrorType() );
         assertEquals( "getLocalizedMessage", errorMessage, ex.getLocalizedMessage() );
         assertEquals( "getErrorInfo", ImmutableMap.of( "foo", "bar" ), ex.getErrorInfo() );
     }
index 1d9e23edea41f8711b8ebcc57120ed61c9dedc65..269dd4d68c31256ce293be4bf5b920c78285fc1b 100644 (file)
     <version>0.4.0-SNAPSHOT</version>
     <packaging>pom</packaging>
 
+    <properties>
+        <mdsal.version>1.3.0-SNAPSHOT</mdsal.version>
+    </properties>
+
     <dependencyManagement>
         <dependencies>
             <dependency>
                 <artifactId>mdsal-netconf-monitoring</artifactId>
                 <version>${project.version}</version>
             </dependency>
+            <dependency>
+                <groupId>${project.groupId}</groupId>
+                <artifactId>mdsal-netconf-monitoring</artifactId>
+                <version>${project.version}</version>
+            </dependency>
             <dependency>
                 <groupId>${project.groupId}</groupId>
                 <artifactId>netconf-netty-util</artifactId>
                 <artifactId>netconf-util</artifactId>
                 <version>${project.version}</version>
             </dependency>
+            <dependency>
+                <groupId>${project.groupId}</groupId>
+                <artifactId>netconf-mdsal-config</artifactId>
+                <version>${project.version}</version>
+                <classifier>config</classifier>
+                <type>xml</type>
+            </dependency>
+            <dependency>
+                <groupId>${project.groupId}</groupId>
+                <artifactId>sal-netconf-connector</artifactId>
+                <version>${mdsal.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>${project.groupId}</groupId>
+                <artifactId>features-netconf-connector</artifactId>
+                <version>${mdsal.version}</version>
+                <classifier>features</classifier>
+                <type>xml</type>
+                <scope>runtime</scope>
+            </dependency>
 
             <dependency>
                 <groupId>${project.groupId}</groupId>
index b9a6f4104ff147c246a3ccb135e8bd9cdae5acbc..17f5608a1c3d0bafffe134f289ffee809324b572 100644 (file)
@@ -20,6 +20,7 @@ import io.netty.util.concurrent.Promise;
 import java.util.Collection;
 import javax.xml.xpath.XPathConstants;
 import javax.xml.xpath.XPathExpression;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.netconf.api.NetconfClientSessionPreferences;
 import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
 import org.opendaylight.controller.netconf.api.NetconfMessage;
@@ -30,7 +31,6 @@ import org.opendaylight.controller.netconf.nettyutil.handler.exi.NetconfStartExi
 import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessage;
 import org.opendaylight.controller.netconf.util.messages.NetconfMessageUtil;
 import org.opendaylight.controller.netconf.util.xml.XMLNetconfUtil;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
diff --git a/opendaylight/netconf/netconf-config-dispatcher/pom.xml b/opendaylight/netconf/netconf-config-dispatcher/pom.xml
new file mode 100644 (file)
index 0000000..ef657d2
--- /dev/null
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ and is available at http://www.eclipse.org/legal/epl-v10.html
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.opendaylight.controller</groupId>
+        <artifactId>netconf-subsystem</artifactId>
+        <version>0.4.0-SNAPSHOT</version>
+    </parent>
+
+  <artifactId>netconf-config-dispatcher</artifactId>
+  <packaging>bundle</packaging>
+
+  <dependencies>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>config-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>netconf-client</artifactId>
+    </dependency>
+
+      <dependency>
+          <groupId>${project.groupId}</groupId>
+          <artifactId>config-manager</artifactId>
+          <type>test-jar</type>
+          <scope>test</scope>
+      </dependency>
+      <dependency>
+          <groupId>${project.groupId}</groupId>
+          <artifactId>config-manager</artifactId>
+          <scope>test</scope>
+      </dependency>
+      <dependency>
+          <groupId>${project.groupId}</groupId>
+          <artifactId>config-util</artifactId>
+          <scope>test</scope>
+      </dependency>
+      <dependency>
+          <groupId>${project.groupId}</groupId>
+          <artifactId>netty-threadgroup-config</artifactId>
+          <scope>test</scope>
+      </dependency>
+      <dependency>
+          <groupId>${project.groupId}</groupId>
+          <artifactId>netty-timer-config</artifactId>
+          <scope>test</scope>
+      </dependency>
+      <dependency>
+          <groupId>org.opendaylight.yangtools</groupId>
+          <artifactId>mockito-configuration</artifactId>
+          <scope>test</scope>
+      </dependency>
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+      </plugin>
+        <plugin>
+        <groupId>org.opendaylight.yangtools</groupId>
+        <artifactId>yang-maven-plugin</artifactId>
+    </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/opendaylight/netconf/netconf-config-dispatcher/src/main/java/org/opendaylight/controller/config/yang/config/netconf/client/dispatcher/NetconfClientDispatcherModule.java b/opendaylight/netconf/netconf-config-dispatcher/src/main/java/org/opendaylight/controller/config/yang/config/netconf/client/dispatcher/NetconfClientDispatcherModule.java
new file mode 100644 (file)
index 0000000..0a10c2d
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.config.yang.config.netconf.client.dispatcher;
+
+import org.opendaylight.controller.netconf.client.NetconfClientDispatcherImpl;
+
+/**
+*
+*/
+public final class NetconfClientDispatcherModule extends org.opendaylight.controller.config.yang.config.netconf.client.dispatcher.AbstractNetconfClientDispatcherModule {
+
+    public NetconfClientDispatcherModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+        super(identifier, dependencyResolver);
+    }
+
+    public NetconfClientDispatcherModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver,
+            NetconfClientDispatcherModule oldModule, java.lang.AutoCloseable oldInstance) {
+
+        super(identifier, dependencyResolver, oldModule, oldInstance);
+    }
+
+    @Override
+    protected void customValidation(){
+    }
+
+    @Override
+    public java.lang.AutoCloseable createInstance() {
+        return new NetconfClientDispatcherImpl(getBossThreadGroupDependency(), getWorkerThreadGroupDependency(), getTimerDependency());
+    }
+}
diff --git a/opendaylight/netconf/netconf-config-dispatcher/src/main/java/org/opendaylight/controller/config/yang/config/netconf/client/dispatcher/NetconfClientDispatcherModuleFactory.java b/opendaylight/netconf/netconf-config-dispatcher/src/main/java/org/opendaylight/controller/config/yang/config/netconf/client/dispatcher/NetconfClientDispatcherModuleFactory.java
new file mode 100644 (file)
index 0000000..cfd4ef6
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.config.yang.config.netconf.client.dispatcher;
+
+/**
+*
+*/
+public class NetconfClientDispatcherModuleFactory extends org.opendaylight.controller.config.yang.config.netconf.client.dispatcher.AbstractNetconfClientDispatcherModuleFactory
+{
+
+
+}
diff --git a/opendaylight/netconf/netconf-config-dispatcher/src/main/yang/odl-netconf-cfg.yang b/opendaylight/netconf/netconf-config-dispatcher/src/main/yang/odl-netconf-cfg.yang
new file mode 100644 (file)
index 0000000..16c2bcb
--- /dev/null
@@ -0,0 +1,31 @@
+// vi: set smarttab et sw=4 tabstop=4:
+module odl-netconf-cfg {
+
+    yang-version 1;
+    namespace "urn:opendaylight:params:xml:ns:yang:controller:config:netconf";
+    prefix "cfg-net";
+
+    import config { prefix config; revision-date 2013-04-05; }
+
+    description
+        "This module contains the base YANG definitions for
+        netconf related services.
+
+        Copyright (c)2013 Cisco Systems, Inc. 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";
+
+    revision "2014-04-08" {
+        description
+            "Initial revision.";
+    }
+
+    identity netconf-client-dispatcher {
+
+        base "config:service-type";
+        config:java-class "org.opendaylight.controller.netconf.client.NetconfClientDispatcher";
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/netconf/netconf-config-dispatcher/src/main/yang/odl-netconfig-client-cfg.yang b/opendaylight/netconf/netconf-config-dispatcher/src/main/yang/odl-netconfig-client-cfg.yang
new file mode 100644 (file)
index 0000000..e00bdeb
--- /dev/null
@@ -0,0 +1,64 @@
+// vi: set smarttab et sw=4 tabstop=4:
+module odl-netconfig-client-cfg {
+
+    yang-version 1;
+    namespace "urn:opendaylight:params:xml:ns:yang:controller:config:netconf:client:dispatcher";
+    prefix "cfg-net-client";
+
+    import config { prefix config; revision-date 2013-04-05; }
+    import odl-netconf-cfg { prefix cfg-net; revision-date 2014-04-08; }
+    import netty {prefix netty; }
+
+    description
+        "This module contains the base YANG definitions for
+        netconf-client-dispatcher implementation.
+
+        Copyright (c)2013 Cisco Systems, Inc. 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";
+
+    revision "2014-04-08" {
+        description
+            "Initial revision.";
+    }
+
+    identity netconf-client-dispatcher {
+            base config:module-type;
+            config:provided-service cfg-net:netconf-client-dispatcher;
+            config:java-name-prefix NetconfClientDispatcher;
+    }
+
+    augment "/config:modules/config:module/config:configuration" {
+        case netconf-client-dispatcher {
+            when "/config:modules/config:module/config:type = 'netconf-client-dispatcher'";
+
+            container boss-thread-group {
+                uses config:service-ref {
+                    refine type {
+                        config:required-identity netty:netty-threadgroup;
+                    }
+                }
+            }
+
+            container worker-thread-group {
+                uses config:service-ref {
+                    refine type {
+                        config:required-identity netty:netty-threadgroup;
+                    }
+                }
+            }
+
+            container timer {
+                uses config:service-ref {
+                    refine type {
+                        config:required-identity netty:netty-timer;
+                    }
+                }
+            }
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/opendaylight/netconf/netconf-config-dispatcher/src/test/java/org/opendaylight/controller/config/yang/config/netconf/client/dispatcher/NetconfClientDispatcherModuleTest.java b/opendaylight/netconf/netconf-config-dispatcher/src/test/java/org/opendaylight/controller/config/yang/config/netconf/client/dispatcher/NetconfClientDispatcherModuleTest.java
new file mode 100644 (file)
index 0000000..85477a0
--- /dev/null
@@ -0,0 +1,102 @@
+package org.opendaylight.controller.config.yang.config.netconf.client.dispatcher;
+
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.InstanceNotFoundException;
+import javax.management.ObjectName;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.controller.config.api.ConflictingVersionException;
+import org.opendaylight.controller.config.api.ValidationException;
+import org.opendaylight.controller.config.api.jmx.CommitStatus;
+import org.opendaylight.controller.config.manager.impl.AbstractConfigTest;
+import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
+import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
+import org.opendaylight.controller.config.yang.netty.threadgroup.NettyThreadgroupModuleFactory;
+import org.opendaylight.controller.config.yang.netty.threadgroup.NettyThreadgroupModuleMXBean;
+import org.opendaylight.controller.config.yang.netty.timer.HashedWheelTimerModuleFactory;
+
+public class NetconfClientDispatcherModuleTest extends AbstractConfigTest{
+
+    private NetconfClientDispatcherModuleFactory factory;
+    private final String instanceName = "dispatch";
+
+    @Before
+    public void setUp() {
+        factory = new NetconfClientDispatcherModuleFactory();
+        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,factory,
+                new NettyThreadgroupModuleFactory(),
+                new HashedWheelTimerModuleFactory()));
+    }
+
+    @Test
+    public void testCreateBean() throws InstanceAlreadyExistsException, ValidationException, ConflictingVersionException {
+        ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
+
+        createInstance(transaction, instanceName, "timer", "thGroup");
+        createInstance(transaction, instanceName + 2, "timer2", "thGroup2");
+        transaction.validateConfig();
+        CommitStatus status = transaction.commit();
+
+        assertBeanCount(2, factory.getImplementationName());
+        assertStatus(status, 2 + 4, 0, 0);
+    }
+
+    @Test
+    public void testReusingOldInstance() throws InstanceAlreadyExistsException, ConflictingVersionException, ValidationException {
+
+        ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
+        createInstance(transaction, instanceName, "timer", "thGroup");
+
+        transaction.commit();
+
+        transaction = configRegistryClient.createTransaction();
+        assertBeanCount(1, factory.getImplementationName());
+        CommitStatus status = transaction.commit();
+
+        assertBeanCount(1, factory.getImplementationName());
+        assertStatus(status, 0, 0, 3);
+    }
+
+    @Test
+    public void testReconfigure() throws InstanceAlreadyExistsException, ConflictingVersionException,
+            ValidationException, InstanceNotFoundException {
+
+        ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
+        createInstance(transaction, instanceName, "timer", "thGroup");
+
+        transaction.commit();
+
+        transaction = configRegistryClient.createTransaction();
+        assertBeanCount(1, factory.getImplementationName());
+        NetconfClientDispatcherModuleMXBean mxBean = transaction.newMBeanProxy(
+                transaction.lookupConfigBean(NetconfClientDispatcherModuleFactory.NAME, instanceName),
+                NetconfClientDispatcherModuleMXBean.class);
+        mxBean.setBossThreadGroup(getThreadGroup(transaction, "group2"));
+        CommitStatus status = transaction.commit();
+
+        assertBeanCount(1, factory.getImplementationName());
+        assertStatus(status, 1, 1, 2);
+    }
+
+    private ObjectName createInstance(ConfigTransactionJMXClient transaction, String instanceName, String timerName, String threadGroupName)
+            throws InstanceAlreadyExistsException {
+        ObjectName nameCreated = transaction.createModule(factory.getImplementationName(), instanceName);
+        NetconfClientDispatcherModuleMXBean mxBean = transaction.newMBeanProxy(nameCreated, NetconfClientDispatcherModuleMXBean.class);
+        ObjectName thGroup = getThreadGroup(transaction, threadGroupName);
+        mxBean.setBossThreadGroup(thGroup);
+        mxBean.setWorkerThreadGroup(thGroup);
+        mxBean.setTimer(getTimer(transaction, timerName));
+        return nameCreated;
+    }
+
+    private ObjectName getTimer(ConfigTransactionJMXClient transaction, String name) throws InstanceAlreadyExistsException {
+        return transaction.createModule(HashedWheelTimerModuleFactory.NAME, name);
+    }
+
+    private ObjectName getThreadGroup(ConfigTransactionJMXClient transaction, String name) throws InstanceAlreadyExistsException {
+        ObjectName nameCreated = transaction.createModule(NettyThreadgroupModuleFactory.NAME, name);
+        NettyThreadgroupModuleMXBean mxBean = transaction.newMXBeanProxy(nameCreated, NettyThreadgroupModuleMXBean.class);
+        mxBean.setThreadCount(1);
+        return nameCreated;
+    }
+}
index 5bb624e38c9489f49b54a7b78787f67b3d91c60a..10f88c564ebb5a2cce477c0e5ca93297342e4182 100644 (file)
       <groupId>${project.groupId}</groupId>
       <artifactId>netconf-mapping-api</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>netconf-notifications-api</artifactId>
+    </dependency>
+    <dependency>
+       <groupId>org.opendaylight.controller</groupId>
+       <artifactId>netconf-notifications-impl</artifactId>
+    </dependency>
     <dependency>
       <groupId>${project.groupId}</groupId>
       <artifactId>netconf-netty-util</artifactId>
       <artifactId>ietf-inet-types</artifactId>
     </dependency>
 
-    <dependency>
-      <groupId>org.osgi</groupId>
-      <artifactId>org.osgi.core</artifactId>
-    </dependency>
     <dependency>
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-api</artifactId>
         <plugin>
             <groupId>org.opendaylight.yangtools</groupId>
             <artifactId>yang-maven-plugin</artifactId>
-            <executions>
-                <execution>
-                    <id>config</id>
-                    <goals>
-                        <goal>generate-sources</goal>
-                    </goals>
-                    <configuration>
-                        <codeGenerators>
-                            <generator>
-                                <codeGeneratorClass>org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator</codeGeneratorClass>
-                                <outputBaseDir>${jmxGeneratorPath}</outputBaseDir>
-                                <additionalConfiguration>
-                                    <namespaceToPackage1>urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang</namespaceToPackage1>
-                                </additionalConfiguration>
-                            </generator>
-                            <generator>
-                                <codeGeneratorClass>org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl</codeGeneratorClass>
-                                <outputBaseDir>${salGeneratorPath}</outputBaseDir>
-                            </generator>
-                        </codeGenerators>
-                        <inspectDependencies>true</inspectDependencies>
-                    </configuration>
-                </execution>
-            </executions>
-            <dependencies>
-                <dependency>
-                    <groupId>org.opendaylight.controller</groupId>
-                    <artifactId>yang-jmx-generator-plugin</artifactId>
-                    <version>${config.version}</version>
-                </dependency>
-            </dependencies>
         </plugin>
     </plugins>
   </build>
index 3c476608a2126b7a4a60eece2a03deca71037636..687ca933f000e5dde9001d15d7aaafdc47e1b41e 100644 (file)
@@ -2,7 +2,6 @@ package org.opendaylight.controller.config.yang.config.netconf.northbound.impl;
 
 import org.opendaylight.controller.config.api.JmxAttributeValidationException;
 import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService;
-import org.opendaylight.controller.netconf.impl.CommitNotifier;
 import org.opendaylight.controller.netconf.impl.NetconfServerDispatcherImpl;
 import org.opendaylight.controller.netconf.impl.NetconfServerSessionNegotiatorFactory;
 import org.opendaylight.controller.netconf.impl.SessionIdProvider;
@@ -29,7 +28,7 @@ public class NetconfServerDispatcherModule extends org.opendaylight.controller.c
         final AggregatedNetconfOperationServiceFactory aggregatedOpProvider = getAggregatedOpProvider();
         final NetconfMonitoringService monitoringService = getServerMonitorDependency();
         final NetconfServerSessionNegotiatorFactory serverNegotiatorFactory = new NetconfServerSessionNegotiatorFactory(
-                getTimerDependency(), aggregatedOpProvider, new SessionIdProvider(), getConnectionTimeoutMillis(), CommitNotifier.NoopCommitNotifier.getInstance(), monitoringService);
+                getTimerDependency(), aggregatedOpProvider, new SessionIdProvider(), getConnectionTimeoutMillis(), monitoringService);
         final NetconfServerDispatcherImpl.ServerChannelInitializer serverChannelInitializer = new NetconfServerDispatcherImpl.ServerChannelInitializer(
                 serverNegotiatorFactory);
 
diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/CommitNotifier.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/CommitNotifier.java
deleted file mode 100644 (file)
index d9f8e34..0000000
+++ /dev/null
@@ -1,32 +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.netconf.impl;
-
-import java.util.Set;
-import org.w3c.dom.Element;
-
-public interface CommitNotifier {
-    void sendCommitNotification(String message, Element cfgSnapshot, Set<String> capabilities);
-
-    public static final class NoopCommitNotifier implements CommitNotifier {
-
-        private static final CommitNotifier INSTANCE = new NoopCommitNotifier();
-
-        private NoopCommitNotifier() {}
-
-        public static CommitNotifier getInstance() {
-            return INSTANCE;
-        }
-
-        @Override
-        public void sendCommitNotification(final String message, final Element cfgSnapshot, final Set<String> capabilities) {
-            // NOOP
-        }
-    }
-}
diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/DefaultCommitNotificationProducer.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/DefaultCommitNotificationProducer.java
deleted file mode 100644 (file)
index 88ff928..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.impl;
-
-import java.util.Set;
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.InstanceNotFoundException;
-import javax.management.MBeanRegistrationException;
-import javax.management.MBeanServer;
-import javax.management.NotCompliantMBeanException;
-import javax.management.NotificationBroadcasterSupport;
-import javax.management.ObjectName;
-import org.opendaylight.controller.netconf.api.jmx.CommitJMXNotification;
-import org.opendaylight.controller.netconf.api.jmx.DefaultCommitOperationMXBean;
-import org.opendaylight.controller.netconf.api.jmx.NetconfJMXNotification;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Element;
-
-public class DefaultCommitNotificationProducer extends NotificationBroadcasterSupport implements
-        DefaultCommitOperationMXBean, AutoCloseable, CommitNotifier {
-
-    private static final Logger LOG = LoggerFactory.getLogger(DefaultCommitNotificationProducer.class);
-
-    private final MBeanServer mbeanServer;
-
-    private final ObjectName on = DefaultCommitOperationMXBean.OBJECT_NAME;
-
-    public DefaultCommitNotificationProducer(MBeanServer mBeanServer) {
-        this.mbeanServer = mBeanServer;
-        LOG.debug("Registering to JMX under {}", on);
-        registerMBean(this, mbeanServer, on);
-    }
-
-    private static void registerMBean(final Object instance, final MBeanServer mbs, final ObjectName on) {
-        try {
-            mbs.registerMBean(instance, on);
-        } catch (InstanceAlreadyExistsException | MBeanRegistrationException | NotCompliantMBeanException e) {
-            throw new IllegalStateException("Unable to register " + instance + " as " + on, e);
-        }
-    }
-
-    @Override
-    public void sendCommitNotification(String message, Element cfgSnapshot, Set<String> capabilities) {
-        CommitJMXNotification notif = NetconfJMXNotification.afterCommit(this, message, cfgSnapshot, capabilities);
-        LOG.debug("Notification about commit {} sent", notif);
-        sendNotification(notif);
-    }
-
-    @Override
-    public void close() {
-        try {
-            mbeanServer.unregisterMBean(on);
-        } catch (InstanceNotFoundException | MBeanRegistrationException e) {
-            LOG.warn("Ignoring exception while unregistering {} as {}", this, on, e);
-        }
-    }
-}
index bc6a2f7284e0c3eadd354924339f8ad26589d95c..b0dcf7876b3b398f141cb205d6885da69cf5b098 100644 (file)
@@ -11,7 +11,8 @@ package org.opendaylight.controller.netconf.impl;
 
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableMap;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.netconf.api.NetconfMessage;
 import org.opendaylight.controller.netconf.api.NetconfSessionListener;
 import org.opendaylight.controller.netconf.api.NetconfTerminationReason;
@@ -19,7 +20,6 @@ import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringServi
 import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
 import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationRouter;
 import org.opendaylight.controller.netconf.util.messages.SendErrorExceptionUtil;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
@@ -92,7 +92,7 @@ public class NetconfServerSessionListener implements NetconfSessionListener<Netc
             LOG.error("Unexpected exception", e);
             session.onIncommingRpcFail();
             throw new IllegalStateException("Unable to process incoming message " + netconfMessage, e);
-        } catch (NetconfDocumentedException e) {
+        } catch (DocumentedException e) {
             LOG.trace("Error occurred while processing message",e);
             session.onOutgoingRpcError();
             session.onIncommingRpcFail();
@@ -101,7 +101,7 @@ public class NetconfServerSessionListener implements NetconfSessionListener<Netc
     }
 
     private NetconfMessage processDocument(final NetconfMessage netconfMessage, final NetconfServerSession session)
-            throws NetconfDocumentedException {
+            throws DocumentedException {
 
         final Document incomingDocument = netconfMessage.getDocument();
         final Node rootNode = incomingDocument.getDocumentElement();
@@ -126,14 +126,14 @@ public class NetconfServerSessionListener implements NetconfSessionListener<Netc
              * unexpected element Description: An unexpected element is present.
              */
             // TODO add message to error info
-            throw new NetconfDocumentedException("Unknown tag " + rootNode.getNodeName(),
-                    NetconfDocumentedException.ErrorType.protocol, NetconfDocumentedException.ErrorTag.unknown_element,
-                    NetconfDocumentedException.ErrorSeverity.error, ImmutableMap.of("bad-element",
+            throw new DocumentedException("Unknown tag " + rootNode.getNodeName(),
+                    DocumentedException.ErrorType.protocol, DocumentedException.ErrorTag.unknown_element,
+                    DocumentedException.ErrorSeverity.error, ImmutableMap.of("bad-element",
                             rootNode.getNodeName()));
         }
     }
 
-    private static void checkMessageId(final Node rootNode) throws NetconfDocumentedException {
+    private static void checkMessageId(final Node rootNode) throws DocumentedException {
 
         NamedNodeMap attributes = rootNode.getAttributes();
 
@@ -145,10 +145,10 @@ public class NetconfServerSessionListener implements NetconfSessionListener<Netc
             return;
         }
 
-        throw new NetconfDocumentedException("Missing attribute" + rootNode.getNodeName(),
-                NetconfDocumentedException.ErrorType.protocol, NetconfDocumentedException.ErrorTag.missing_attribute,
-                NetconfDocumentedException.ErrorSeverity.error,
-                ImmutableMap.of(NetconfDocumentedException.ErrorTag.missing_attribute.toString(),
+        throw new DocumentedException("Missing attribute" + rootNode.getNodeName(),
+                DocumentedException.ErrorType.protocol, DocumentedException.ErrorTag.missing_attribute,
+                DocumentedException.ErrorSeverity.error,
+                ImmutableMap.of(DocumentedException.ErrorTag.missing_attribute.toString(),
                         XmlNetconfConstants.MESSAGE_ID));
     }
 }
index d010b5cefc0c20c364a5ad255c6aec0fbede7dce..ce83b7ee3dfe175ab6c4db9c649ad694be90b871 100644 (file)
@@ -8,7 +8,9 @@
 
 package org.opendaylight.controller.netconf.impl;
 
+import com.google.common.base.Function;
 import com.google.common.base.Preconditions;
+import com.google.common.collect.Collections2;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Sets;
 import io.netty.channel.Channel;
@@ -19,7 +21,6 @@ import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
 import org.opendaylight.controller.netconf.api.NetconfServerSessionPreferences;
 import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService;
 import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.impl.mapping.operations.DefaultCommit;
 import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationRouter;
 import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationRouterImpl;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService;
@@ -28,6 +29,8 @@ import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessage;
 import org.opendaylight.protocol.framework.SessionListenerFactory;
 import org.opendaylight.protocol.framework.SessionNegotiator;
 import org.opendaylight.protocol.framework.SessionNegotiatorFactory;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.Capabilities;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -44,7 +47,6 @@ public class NetconfServerSessionNegotiatorFactory implements SessionNegotiatorF
     private final SessionIdProvider idProvider;
     private final NetconfOperationServiceFactory aggregatedOpService;
     private final long connectionTimeoutMillis;
-    private final CommitNotifier commitNotificationProducer;
     private final NetconfMonitoringService monitoringService;
     private static final Logger LOG = LoggerFactory.getLogger(NetconfServerSessionNegotiatorFactory.class);
     private final Set<String> baseCapabilities;
@@ -52,21 +54,18 @@ public class NetconfServerSessionNegotiatorFactory implements SessionNegotiatorF
     // TODO too many params, refactor
     public NetconfServerSessionNegotiatorFactory(final Timer timer, final NetconfOperationServiceFactory netconfOperationProvider,
                                                  final SessionIdProvider idProvider, final long connectionTimeoutMillis,
-                                                 final CommitNotifier commitNot,
                                                  final NetconfMonitoringService monitoringService) {
-        this(timer, netconfOperationProvider, idProvider, connectionTimeoutMillis, commitNot, monitoringService, DEFAULT_BASE_CAPABILITIES);
+        this(timer, netconfOperationProvider, idProvider, connectionTimeoutMillis, monitoringService, DEFAULT_BASE_CAPABILITIES);
     }
 
     // TODO too many params, refactor
     public NetconfServerSessionNegotiatorFactory(final Timer timer, final NetconfOperationServiceFactory netconfOperationProvider,
                                                  final SessionIdProvider idProvider, final long connectionTimeoutMillis,
-                                                 final CommitNotifier commitNot,
                                                  final NetconfMonitoringService monitoringService, final Set<String> baseCapabilities) {
         this.timer = timer;
         this.aggregatedOpService = netconfOperationProvider;
         this.idProvider = idProvider;
         this.connectionTimeoutMillis = connectionTimeoutMillis;
-        this.commitNotificationProducer = commitNot;
         this.monitoringService = monitoringService;
         this.baseCapabilities = validateBaseCapabilities(baseCapabilities);
     }
@@ -115,13 +114,22 @@ public class NetconfServerSessionNegotiatorFactory implements SessionNegotiatorF
         final NetconfOperationService service =
                 this.aggregatedOpService.createService(netconfSessionIdForReporting);
         final NetconfOperationRouter operationRouter =
-                new NetconfOperationRouterImpl(service, commitNotificationProducer, monitoringService, netconfSessionIdForReporting);
+                new NetconfOperationRouterImpl(service, monitoringService, netconfSessionIdForReporting);
         return new NetconfServerSessionListener(operationRouter, monitoringService, service);
 
     }
 
     private NetconfHelloMessage createHelloMessage(final long sessionId, final NetconfMonitoringService capabilityProvider) throws NetconfDocumentedException {
-        return NetconfHelloMessage.createServerHello(Sets.union(DefaultCommit.transformCapabilities(capabilityProvider.getCapabilities()), baseCapabilities), sessionId);
+        return NetconfHelloMessage.createServerHello(Sets.union(transformCapabilities(capabilityProvider.getCapabilities()), baseCapabilities), sessionId);
+    }
+
+    public static Set<String> transformCapabilities(final Capabilities capabilities) {
+        return Sets.newHashSet(Collections2.transform(capabilities.getCapability(), new Function<Uri, String>() {
+            @Override
+            public String apply(final Uri uri) {
+                return uri.getValue();
+            }
+        }));
     }
 
 }
index d56648cdf059c4620b14625d9206cd34467d0484..597380e5c118e99fe7916e5ceca36290b611d0df 100644 (file)
@@ -11,11 +11,11 @@ package org.opendaylight.controller.netconf.impl;
 import com.google.common.base.Optional;
 import java.io.IOException;
 import java.util.Map;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.config.util.xml.XmlElement;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
 import org.opendaylight.controller.netconf.util.mapping.AbstractNetconfOperation.OperationNameAndNamespace;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Attr;
@@ -30,7 +30,7 @@ import org.xml.sax.SAXException;
 public class SubtreeFilter {
     private static final Logger LOG = LoggerFactory.getLogger(SubtreeFilter.class);
 
-    static Document applySubtreeFilter(Document requestDocument, Document rpcReply) throws NetconfDocumentedException {
+    static Document applySubtreeFilter(Document requestDocument, Document rpcReply) throws DocumentedException {
         OperationNameAndNamespace operationNameAndNamespace = new OperationNameAndNamespace(requestDocument);
         if (XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0.equals(operationNameAndNamespace.getNamespace()) &&
                 XmlNetconfConstants.GET.equals(operationNameAndNamespace.getOperationName()) ||
@@ -48,7 +48,7 @@ public class SubtreeFilter {
                 rpcReply = XmlUtil.readXmlToDocument(XmlUtil.toString(rpcReply, true));
             } catch (SAXException | IOException e) {
                 LOG.error("Cannot transform document", e);
-                throw new NetconfDocumentedException("Cannot transform document" + e);
+                throw new DocumentedException("Cannot transform document" + e);
             }
             XmlElement filter = maybeFilter.get();
             if ("subtree".equals(filter.getAttribute("type"))||
@@ -62,13 +62,13 @@ public class SubtreeFilter {
         return rpcReply; // return identical document
     }
 
-    private static Document filtered(XmlElement filter, Document originalReplyDocument) throws NetconfDocumentedException {
+    private static Document filtered(XmlElement filter, Document originalReplyDocument) throws DocumentedException {
         Document result = XmlUtil.newDocument();
         // even if filter is empty, copy /rpc/data
         Element rpcReply = originalReplyDocument.getDocumentElement();
         Node rpcReplyDst = result.importNode(rpcReply, false);
         result.appendChild(rpcReplyDst);
-        XmlElement dataSrc = XmlElement.fromDomElement(rpcReply).getOnlyChildElement("data", XmlNetconfConstants.RFC4741_TARGET_NAMESPACE);
+        XmlElement dataSrc = XmlElement.fromDomElement(rpcReply).getOnlyChildElement("data", XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
         Element dataDst = (Element) result.importNode(dataSrc.getDomElement(), false);
         rpcReplyDst.appendChild(dataDst);
         addSubtree(filter, dataSrc, XmlElement.fromDomElement(dataDst));
@@ -76,7 +76,7 @@ public class SubtreeFilter {
         return result;
     }
 
-    private static void addSubtree(XmlElement filter, XmlElement src, XmlElement dst) throws NetconfDocumentedException {
+    private static void addSubtree(XmlElement filter, XmlElement src, XmlElement dst) throws DocumentedException {
         for (XmlElement srcChild : src.getChildElements()) {
             for (XmlElement filterChild : filter.getChildElements()) {
                 addSubtree2(filterChild, srcChild, dst);
@@ -84,7 +84,7 @@ public class SubtreeFilter {
         }
     }
 
-    private static MatchingResult addSubtree2(XmlElement filter, XmlElement src, XmlElement dstParent) throws NetconfDocumentedException {
+    private static MatchingResult addSubtree2(XmlElement filter, XmlElement src, XmlElement dstParent) throws DocumentedException {
         Document document = dstParent.getDomElement().getOwnerDocument();
         MatchingResult matches = matches(src, filter);
         if (matches != MatchingResult.NO_MATCH && matches != MatchingResult.CONTENT_MISMATCH) {
@@ -126,7 +126,7 @@ public class SubtreeFilter {
      * Shallow compare src node to filter: tag name and namespace must match.
      * If filter node has no children and has text content, it also must match.
      */
-    private static MatchingResult matches(XmlElement src, XmlElement filter) throws NetconfDocumentedException {
+    private static MatchingResult matches(XmlElement src, XmlElement filter) throws DocumentedException {
         boolean tagMatch = src.getName().equals(filter.getName()) &&
                 src.getNamespaceOptionally().equals(filter.getNamespaceOptionally());
         MatchingResult result = null;
@@ -166,7 +166,7 @@ public class SubtreeFilter {
         return result;
     }
 
-    private static boolean prefixedContentMatches(final XmlElement filter, final XmlElement src) throws NetconfDocumentedException {
+    private static boolean prefixedContentMatches(final XmlElement filter, final XmlElement src) throws DocumentedException {
         final Map.Entry<String, String> prefixToNamespaceOfFilter;
         final Map.Entry<String, String> prefixToNamespaceOfSrc;
         try {
index 303352c9c557f111cabde8866e4376698cb96190..3aa40b55a694dd3ac74d32d3ae5a462652b59e81 100644 (file)
@@ -11,12 +11,12 @@ package org.opendaylight.controller.netconf.impl.mapping.operations;
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import java.util.Collections;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.config.util.xml.XmlElement;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
 import org.opendaylight.controller.netconf.impl.NetconfServerSession;
 import org.opendaylight.controller.netconf.util.mapping.AbstractSingletonNetconfOperation;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
@@ -47,17 +47,17 @@ public class DefaultCloseSession extends AbstractSingletonNetconfOperation imple
      */
     @Override
     protected Element handleWithNoSubsequentOperations(Document document, XmlElement operationElement)
-            throws NetconfDocumentedException {
+            throws DocumentedException {
         try {
             sessionResources.close();
             Preconditions.checkNotNull(session, "Session was not set").delayedClose();
             LOG.info("Session {} closing", session.getSessionId());
         } catch (Exception e) {
-            throw new NetconfDocumentedException("Unable to properly close session "
-                    + getNetconfSessionIdForReporting(), NetconfDocumentedException.ErrorType.application,
-                    NetconfDocumentedException.ErrorTag.operation_failed,
-                    NetconfDocumentedException.ErrorSeverity.error, Collections.singletonMap(
-                        NetconfDocumentedException.ErrorSeverity.error.toString(), e.getMessage()));
+            throw new DocumentedException("Unable to properly close session "
+                    + getNetconfSessionIdForReporting(), DocumentedException.ErrorType.application,
+                    DocumentedException.ErrorTag.operation_failed,
+                    DocumentedException.ErrorSeverity.error, Collections.singletonMap(
+                    DocumentedException.ErrorSeverity.error.toString(), e.getMessage()));
         }
         return XmlUtil.createElement(document, XmlNetconfConstants.OK, Optional.<String>absent());
     }
diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultCommit.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultCommit.java
deleted file mode 100644 (file)
index 13e56d7..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.impl.mapping.operations;
-
-import com.google.common.base.Function;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Collections2;
-import com.google.common.collect.Sets;
-import java.io.InputStream;
-import java.util.Set;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.impl.CommitNotifier;
-import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationRouter;
-import org.opendaylight.controller.netconf.mapping.api.HandlingPriority;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationChainedExecution;
-import org.opendaylight.controller.netconf.util.mapping.AbstractNetconfOperation;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.Capabilities;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-public class DefaultCommit extends AbstractNetconfOperation {
-
-    private static final Logger LOG = LoggerFactory.getLogger(DefaultCommit.class);
-
-    private static final String NOTIFY_ATTR = "notify";
-
-    //TODO make commit notification optional
-    private final CommitNotifier notificationProducer;
-    private final NetconfMonitoringService cap;
-    private final NetconfOperationRouter operationRouter;
-
-    public DefaultCommit(final CommitNotifier notifier, final NetconfMonitoringService cap,
-                         final String netconfSessionIdForReporting, final NetconfOperationRouter netconfOperationRouter) {
-        super(netconfSessionIdForReporting);
-        this.notificationProducer = notifier;
-        this.cap = cap;
-        this.operationRouter = netconfOperationRouter;
-        this.getConfigMessage = loadGetConfigMessage();
-    }
-
-    private final Document getConfigMessage;
-    public static final String GET_CONFIG_CANDIDATE_XML_LOCATION = "/getConfig_candidate.xml";
-
-    private static Document loadGetConfigMessage() {
-        try (InputStream asStream = DefaultCommit.class.getResourceAsStream(GET_CONFIG_CANDIDATE_XML_LOCATION)) {
-            return XmlUtil.readXmlToDocument(asStream);
-        } catch (Exception e) {
-            throw new IllegalStateException("Unable to load getConfig message for notifications from "
-                    + GET_CONFIG_CANDIDATE_XML_LOCATION);
-        }
-    }
-
-    @Override
-    protected String getOperationName() {
-        return XmlNetconfConstants.COMMIT;
-    }
-
-    @Override
-    public Document handle(final Document requestMessage, final NetconfOperationChainedExecution subsequentOperation) throws NetconfDocumentedException {
-        Preconditions.checkArgument(!subsequentOperation.isExecutionTermination(),
-                "Subsequent netconf operation expected by %s", this);
-
-        if (isCommitWithoutNotification(requestMessage)) {
-            LOG.debug("Skipping commit notification");
-        } else {
-            // Send commit notification if commit was not issued by persister
-            removePersisterAttributes(requestMessage);
-            Element cfgSnapshot = getConfigSnapshot(operationRouter);
-            LOG.debug("Config snapshot retrieved successfully {}", cfgSnapshot);
-            notificationProducer.sendCommitNotification("ok", cfgSnapshot, transformCapabilities(cap.getCapabilities()));
-        }
-
-        return subsequentOperation.execute(requestMessage);
-    }
-
-    // FIXME move somewhere to util since this is required also by negotiatiorFactory
-    public static Set<String> transformCapabilities(final Capabilities capabilities) {
-        return Sets.newHashSet(Collections2.transform(capabilities.getCapability(), new Function<Uri, String>() {
-            @Override
-            public String apply(final Uri uri) {
-                return uri.getValue();
-            }
-        }));
-    }
-
-    @Override
-    protected Element handle(final Document document, final XmlElement message, final NetconfOperationChainedExecution subsequentOperation) throws NetconfDocumentedException {
-        throw new UnsupportedOperationException("Never gets called");
-    }
-
-    @Override
-    protected HandlingPriority getHandlingPriority() {
-        return HandlingPriority.HANDLE_WITH_DEFAULT_PRIORITY.increasePriority(1);
-    }
-
-    private static void removePersisterAttributes(final Document message) {
-        message.getDocumentElement().removeAttribute(NOTIFY_ATTR);
-    }
-
-    private static boolean isCommitWithoutNotification(final Document message) {
-        XmlElement xmlElement = null;
-        try {
-            xmlElement = XmlElement.fromDomElementWithExpected(message.getDocumentElement(),
-                    XmlNetconfConstants.RPC_KEY, XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
-        } catch (NetconfDocumentedException e) {
-            LOG.trace("Commit operation is not valid due to ",e);
-            return false;
-        }
-
-        String attr = xmlElement.getAttribute(NOTIFY_ATTR);
-
-        if (attr == null || attr.equals("")){
-            return false;
-        } else if (attr.equals(Boolean.toString(false))) {
-            LOG.debug("Commit operation received with notify=false attribute {}", message);
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    private Element getConfigSnapshot(final NetconfOperationRouter opRouter) throws NetconfDocumentedException {
-        final Document responseDocument = opRouter.onNetconfMessage(
-                getConfigMessage, null);
-
-        XmlElement dataElement;
-        XmlElement xmlElement = XmlElement.fromDomElementWithExpected(responseDocument.getDocumentElement(),
-                XmlNetconfConstants.RPC_REPLY_KEY, XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
-        dataElement = xmlElement.getOnlyChildElement(XmlNetconfConstants.DATA_KEY);
-        return dataElement.getDomElement();
-    }
-
-}
index 5593c22fad1e233b9ee9ce2a1eb88cf3451144e6..1dab7e0b458683d98b03acf277a142dabf1546f5 100644 (file)
@@ -7,21 +7,22 @@
  */
 package org.opendaylight.controller.netconf.impl.mapping.operations;
 
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorSeverity;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorTag;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorType;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorSeverity;
+import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorTag;
+import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorType;
+import org.opendaylight.controller.config.util.xml.XmlElement;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.netconf.api.NetconfMessage;
 import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
 import org.opendaylight.controller.netconf.impl.NetconfServerSession;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperationChainedExecution;
 import org.opendaylight.controller.netconf.util.mapping.AbstractSingletonNetconfOperation;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
+
 public class DefaultStartExi extends AbstractSingletonNetconfOperation implements DefaultNetconfOperation {
     public static final String START_EXI = "start-exi";
 
@@ -34,7 +35,7 @@ public class DefaultStartExi extends AbstractSingletonNetconfOperation implement
 
     @Override
     public Document handle(final Document message,
-                           final NetconfOperationChainedExecution subsequentOperation) throws NetconfDocumentedException {
+                           final NetconfOperationChainedExecution subsequentOperation) throws DocumentedException {
         if (LOG.isDebugEnabled()) {
             LOG.debug("Received start-exi message {} ", XmlUtil.toString(message));
         }
@@ -42,7 +43,7 @@ public class DefaultStartExi extends AbstractSingletonNetconfOperation implement
         try {
             netconfSession.startExiCommunication(new NetconfMessage(message));
         } catch (IllegalArgumentException e) {
-            throw new NetconfDocumentedException("Failed to parse EXI parameters", ErrorType.protocol,
+            throw new DocumentedException("Failed to parse EXI parameters", ErrorType.protocol,
                     ErrorTag.operation_failed, ErrorSeverity.error);
         }
 
@@ -50,7 +51,7 @@ public class DefaultStartExi extends AbstractSingletonNetconfOperation implement
     }
 
     @Override
-    protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement operationElement) throws NetconfDocumentedException {
+    protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement operationElement) throws DocumentedException {
         Element getSchemaResult = document.createElementNS( XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0, XmlNetconfConstants.OK);
         LOG.trace("{} operation successful", START_EXI);
         return getSchemaResult;
index 2b90a6150552e9306f3a137c6fe7056b2e422b3d..8ee671733e56b2c29a1e697f1bc323592820fff2 100644 (file)
@@ -7,12 +7,12 @@
  */
 package org.opendaylight.controller.netconf.impl.mapping.operations;
 
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.config.util.xml.XmlElement;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
 import org.opendaylight.controller.netconf.impl.NetconfServerSession;
 import org.opendaylight.controller.netconf.util.mapping.AbstractSingletonNetconfOperation;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
@@ -31,7 +31,7 @@ public class DefaultStopExi extends AbstractSingletonNetconfOperation implements
     }
 
     @Override
-    protected Element handleWithNoSubsequentOperations(Document document, XmlElement operationElement) throws NetconfDocumentedException {
+    protected Element handleWithNoSubsequentOperations(Document document, XmlElement operationElement) throws DocumentedException {
         LOG.debug("Received stop-exi message {} ", XmlUtil.toString(operationElement));
 
         netconfSession.stopExiCommunication();
index ae68ecc120b5fb502a0c362d023ff81b7f469509..d4a15e0dbde241583f5d3a2676c0821c4b365b50 100644 (file)
@@ -17,19 +17,23 @@ import com.google.common.collect.Sets;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
-import org.opendaylight.controller.netconf.api.Capability;
+import org.opendaylight.controller.config.util.capability.Capability;
 import org.opendaylight.controller.netconf.api.monitoring.CapabilityListener;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperation;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactory;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactoryListener;
 import org.opendaylight.controller.netconf.util.CloseableUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * NetconfOperationService aggregator. Makes a collection of operation services accessible as one.
  */
 public class AggregatedNetconfOperationServiceFactory implements NetconfOperationServiceFactory, NetconfOperationServiceFactoryListener, AutoCloseable {
 
+    private static final Logger LOG = LoggerFactory.getLogger(AggregatedNetconfOperationServiceFactory.class);
+
     private final Set<NetconfOperationServiceFactory> factories = new HashSet<>();
     private final Multimap<NetconfOperationServiceFactory, AutoCloseable> registrations = HashMultimap.create();
     private final Set<CapabilityListener> listeners = Sets.newHashSet();
@@ -52,7 +56,7 @@ public class AggregatedNetconfOperationServiceFactory implements NetconfOperatio
             try {
                 autoCloseable.close();
             } catch (Exception e) {
-                // FIXME Issue warning
+                LOG.warn("Unable to close listener registration", e);
             }
         }
 
index 1e35597d9a6239d8566005b8bf3775b86282b082..8946765aa6b000ea7ed9d60c05a1d5fdc0688925 100644 (file)
@@ -10,20 +10,23 @@ package org.opendaylight.controller.netconf.impl.osgi;
 import io.netty.channel.local.LocalAddress;
 import io.netty.channel.nio.NioEventLoopGroup;
 import io.netty.util.HashedWheelTimer;
-import java.lang.management.ManagementFactory;
 import java.util.Dictionary;
 import java.util.Hashtable;
 import java.util.concurrent.TimeUnit;
 import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService;
-import org.opendaylight.controller.netconf.impl.DefaultCommitNotificationProducer;
 import org.opendaylight.controller.netconf.impl.NetconfServerDispatcherImpl;
 import org.opendaylight.controller.netconf.impl.NetconfServerSessionNegotiatorFactory;
 import org.opendaylight.controller.netconf.impl.SessionIdProvider;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactoryListener;
+import org.opendaylight.controller.netconf.notifications.BaseNotificationPublisherRegistration;
+import org.opendaylight.controller.netconf.notifications.NetconfNotificationCollector;
 import org.opendaylight.controller.netconf.util.osgi.NetconfConfigUtil;
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
 import org.osgi.framework.ServiceRegistration;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -32,38 +35,62 @@ public class NetconfImplActivator implements BundleActivator {
     private static final Logger LOG = LoggerFactory.getLogger(NetconfImplActivator.class);
 
     private NetconfOperationServiceFactoryTracker factoriesTracker;
-    private DefaultCommitNotificationProducer commitNot;
     private NioEventLoopGroup eventLoopGroup;
     private HashedWheelTimer timer;
     private ServiceRegistration<NetconfMonitoringService> regMonitoring;
 
+    private BaseNotificationPublisherRegistration listenerReg;
+
     @Override
     public void start(final BundleContext context)  {
-
-        AggregatedNetconfOperationServiceFactory factoriesListener = new AggregatedNetconfOperationServiceFactory();
-        startOperationServiceFactoryTracker(context, factoriesListener);
-
-        SessionIdProvider idProvider = new SessionIdProvider();
-        timer = new HashedWheelTimer();
-        long connectionTimeoutMillis = NetconfConfigUtil.extractTimeoutMillis(context);
-
-
-        commitNot = new DefaultCommitNotificationProducer(ManagementFactory.getPlatformMBeanServer());
-
-        NetconfMonitoringService monitoringService = startMonitoringService(context, factoriesListener);
-
-        NetconfServerSessionNegotiatorFactory serverNegotiatorFactory = new NetconfServerSessionNegotiatorFactory(
-                timer, factoriesListener, idProvider, connectionTimeoutMillis, commitNot, monitoringService);
-
-        eventLoopGroup = new NioEventLoopGroup();
-
-        NetconfServerDispatcherImpl.ServerChannelInitializer serverChannelInitializer = new NetconfServerDispatcherImpl.ServerChannelInitializer(
-                serverNegotiatorFactory);
-        NetconfServerDispatcherImpl dispatch = new NetconfServerDispatcherImpl(serverChannelInitializer, eventLoopGroup, eventLoopGroup);
-
-        LocalAddress address = NetconfConfigUtil.getNetconfLocalAddress();
-        LOG.trace("Starting local netconf server at {}", address);
-        dispatch.createLocalServer(address);
+        try {
+            AggregatedNetconfOperationServiceFactory factoriesListener = new AggregatedNetconfOperationServiceFactory();
+            startOperationServiceFactoryTracker(context, factoriesListener);
+
+            SessionIdProvider idProvider = new SessionIdProvider();
+            timer = new HashedWheelTimer();
+            long connectionTimeoutMillis = NetconfConfigUtil.extractTimeoutMillis(context);
+
+            final NetconfMonitoringServiceImpl monitoringService = startMonitoringService(context, factoriesListener);
+
+            NetconfServerSessionNegotiatorFactory serverNegotiatorFactory = new NetconfServerSessionNegotiatorFactory(
+                    timer, factoriesListener, idProvider, connectionTimeoutMillis, monitoringService);
+
+            eventLoopGroup = new NioEventLoopGroup();
+
+            NetconfServerDispatcherImpl.ServerChannelInitializer serverChannelInitializer = new NetconfServerDispatcherImpl.ServerChannelInitializer(
+                    serverNegotiatorFactory);
+            NetconfServerDispatcherImpl dispatch = new NetconfServerDispatcherImpl(serverChannelInitializer, eventLoopGroup, eventLoopGroup);
+
+            LocalAddress address = NetconfConfigUtil.getNetconfLocalAddress();
+            LOG.trace("Starting local netconf server at {}", address);
+            dispatch.createLocalServer(address);
+
+            final ServiceTracker<NetconfNotificationCollector, NetconfNotificationCollector> notificationServiceTracker =
+                    new ServiceTracker<>(context, NetconfNotificationCollector.class, new ServiceTrackerCustomizer<NetconfNotificationCollector, NetconfNotificationCollector>() {
+                        @Override
+                        public NetconfNotificationCollector addingService(ServiceReference<NetconfNotificationCollector> reference) {
+                            listenerReg = context.getService(reference).registerBaseNotificationPublisher();
+                            monitoringService.setNotificationPublisher(listenerReg);
+                            return null;
+                        }
+
+                        @Override
+                        public void modifiedService(ServiceReference<NetconfNotificationCollector> reference, NetconfNotificationCollector service) {
+
+                        }
+
+                        @Override
+                        public void removedService(ServiceReference<NetconfNotificationCollector> reference, NetconfNotificationCollector service) {
+                            listenerReg.close();
+                            listenerReg = null;
+                            monitoringService.setNotificationPublisher(listenerReg);
+                        }
+                    });
+            notificationServiceTracker.open();
+        } catch (Exception e) {
+            LOG.warn("Unable to start NetconfImplActivator", e);
+        }
     }
 
     private void startOperationServiceFactoryTracker(BundleContext context, NetconfOperationServiceFactoryListener factoriesListener) {
@@ -83,7 +110,6 @@ public class NetconfImplActivator implements BundleActivator {
     public void stop(final BundleContext context) {
         LOG.info("Shutting down netconf because YangStoreService service was removed");
 
-        commitNot.close();
         eventLoopGroup.shutdownGracefully(0, 1, TimeUnit.SECONDS);
         timer.stop();
 
index b02137b748c71584841df04817a9f8bb552147e2..2b0d35bc9d96320070080a0914234fc6f2852d27 100644 (file)
@@ -19,15 +19,19 @@ import com.google.common.collect.Sets;
 import io.netty.util.internal.ConcurrentSet;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import javax.annotation.Nonnull;
-import org.opendaylight.controller.netconf.api.Capability;
+import org.opendaylight.controller.config.util.capability.BasicCapability;
+import org.opendaylight.controller.config.util.capability.Capability;
 import org.opendaylight.controller.netconf.api.monitoring.NetconfManagementSession;
 import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactory;
+import org.opendaylight.controller.netconf.notifications.BaseNotificationPublisherRegistration;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
 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.NetconfStateBuilder;
@@ -42,6 +46,10 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.mon
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.schemas.SchemaBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.schemas.SchemaKey;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.sessions.Session;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfCapabilityChange;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfCapabilityChangeBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.changed.by.parms.ChangedByBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.changed.by.parms.changed.by.server.or.user.ServerBuilder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -68,6 +76,7 @@ public class NetconfMonitoringServiceImpl implements NetconfMonitoringService, A
     private final Map<Uri, Capability> capabilities = new ConcurrentHashMap<>();
 
     private final Set<MonitoringListener> listeners = Sets.newHashSet();
+    private volatile BaseNotificationPublisherRegistration notificationPublisher;
 
     public NetconfMonitoringServiceImpl(final NetconfOperationServiceFactory netconfOperationProvider) {
         this.netconfOperationProvider = netconfOperationProvider;
@@ -222,11 +231,48 @@ public class NetconfMonitoringServiceImpl implements NetconfMonitoringService, A
         return b.build();
     }
 
+    public static Set<Capability> setupCapabilities(final Set<Capability> caps) {
+        Set<Capability> capabilities = new HashSet<>(caps);
+        capabilities.add(new BasicCapability("urn:ietf:params:netconf:capability:candidate:1.0"));
+        // TODO rollback on error not supported EditConfigXmlParser:100
+        // [RFC6241] 8.5.  Rollback-on-Error Capability
+        // capabilities.add(new BasicCapability("urn:ietf:params:netconf:capability:rollback-on-error:1.0"));
+        return capabilities;
+    }
+
     @Override
-    public synchronized void onCapabilitiesAdded(final Set<Capability> addedCaps) {
-        // FIXME howto check for duplicates
-        this.capabilities.putAll(Maps.uniqueIndex(addedCaps, CAPABILITY_TO_URI));
+    public synchronized void close() throws Exception {
+        listeners.clear();
+        sessions.clear();
+        capabilities.clear();
+    }
+
+    @Override
+    public void onCapabilitiesChanged(Set<Capability> added, Set<Capability> removed) {
+        onCapabilitiesAdded(added);
+        onCapabilitiesRemoved(removed);
         notifyListeners();
+
+        // publish notification to notification collector about changed capabilities
+        if (notificationPublisher != null) {
+            notificationPublisher.onCapabilityChanged(computeDiff(added, removed));
+        }
+    }
+
+    static NetconfCapabilityChange computeDiff(final Set<Capability> removed, final Set<Capability> added) {
+        final NetconfCapabilityChangeBuilder netconfCapabilityChangeBuilder = new NetconfCapabilityChangeBuilder();
+        netconfCapabilityChangeBuilder.setChangedBy(new ChangedByBuilder().setServerOrUser(new ServerBuilder().setServer(true).build()).build());
+        netconfCapabilityChangeBuilder.setDeletedCapability(Lists.newArrayList(Collections2.transform(removed, CAPABILITY_TO_URI)));
+        netconfCapabilityChangeBuilder.setAddedCapability(Lists.newArrayList(Collections2.transform(added, CAPABILITY_TO_URI)));
+        // TODO modified should be computed ... but why ?
+        netconfCapabilityChangeBuilder.setModifiedCapability(Collections.<Uri>emptyList());
+        return netconfCapabilityChangeBuilder.build();
+    }
+
+
+    private synchronized void onCapabilitiesAdded(final Set<Capability> addedCaps) {
+        // FIXME howto check for duplicates
+        this.capabilities.putAll(Maps.uniqueIndex(setupCapabilities(addedCaps), CAPABILITY_TO_URI));
     }
 
     private void notifyListeners() {
@@ -235,18 +281,13 @@ public class NetconfMonitoringServiceImpl implements NetconfMonitoringService, A
         }
     }
 
-    @Override
-    public synchronized void onCapabilitiesRemoved(final Set<Capability> addedCaps) {
+    private synchronized void onCapabilitiesRemoved(final Set<Capability> addedCaps) {
         for (final Capability addedCap : addedCaps) {
-            capabilities.remove(addedCap.getCapabilityUri());
+            capabilities.remove(CAPABILITY_TO_URI.apply(addedCap));
         }
-        notifyListeners();
     }
 
-    @Override
-    public synchronized void close() throws Exception {
-        listeners.clear();
-        sessions.clear();
-        capabilities.clear();
+    public void setNotificationPublisher(final BaseNotificationPublisherRegistration notificationPublisher) {
+        this.notificationPublisher = notificationPublisher;
     }
 }
index 16cca1fee793c2f6996a5fa93c66e7a0fcaa513b..ab9a3ab1c49f83871f398ad110a67b7ca09e1cc7 100644 (file)
@@ -8,14 +8,14 @@
 
 package org.opendaylight.controller.netconf.impl.osgi;
 
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
 import org.opendaylight.controller.netconf.impl.NetconfServerSession;
 import org.w3c.dom.Document;
 
 public interface NetconfOperationRouter extends AutoCloseable {
 
     Document onNetconfMessage(Document message, NetconfServerSession session)
-            throws NetconfDocumentedException;
+            throws DocumentedException;
 
 
 }
index 9d58bd911c828bfcba3b185b3db20dc9c0d87985..56acf0f6487e9e33abcaaac18c522afb0c6cf548 100644 (file)
@@ -16,12 +16,11 @@ import java.util.HashSet;
 import java.util.NavigableMap;
 import java.util.Set;
 import java.util.TreeMap;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService;
-import org.opendaylight.controller.netconf.impl.CommitNotifier;
 import org.opendaylight.controller.netconf.impl.NetconfServerSession;
 import org.opendaylight.controller.netconf.impl.mapping.operations.DefaultCloseSession;
-import org.opendaylight.controller.netconf.impl.mapping.operations.DefaultCommit;
 import org.opendaylight.controller.netconf.impl.mapping.operations.DefaultNetconfOperation;
 import org.opendaylight.controller.netconf.impl.mapping.operations.DefaultStartExi;
 import org.opendaylight.controller.netconf.impl.mapping.operations.DefaultStopExi;
@@ -30,7 +29,6 @@ import org.opendaylight.controller.netconf.mapping.api.NetconfOperation;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperationChainedExecution;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService;
 import org.opendaylight.controller.netconf.mapping.api.SessionAwareNetconfOperation;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
@@ -42,14 +40,13 @@ public class NetconfOperationRouterImpl implements NetconfOperationRouter {
     private final Collection<NetconfOperation> allNetconfOperations;
 
     public NetconfOperationRouterImpl(final NetconfOperationService netconfOperationServiceSnapshot,
-                                      final CommitNotifier commitNotifier, final NetconfMonitoringService netconfMonitoringService, final String sessionId) {
+                                      final NetconfMonitoringService netconfMonitoringService, final String sessionId) {
         this.netconfOperationServiceSnapshot = Preconditions.checkNotNull(netconfOperationServiceSnapshot);
 
         final Set<NetconfOperation> ops = new HashSet<>();
         ops.add(new DefaultCloseSession(sessionId, this));
         ops.add(new DefaultStartExi(sessionId));
         ops.add(new DefaultStopExi(sessionId));
-        ops.add(new DefaultCommit(commitNotifier, netconfMonitoringService, sessionId, this));
 
         ops.addAll(netconfOperationServiceSnapshot.getNetconfOperations());
 
@@ -57,7 +54,7 @@ public class NetconfOperationRouterImpl implements NetconfOperationRouter {
     }
 
     @Override
-    public Document onNetconfMessage(final Document message, final NetconfServerSession session) throws NetconfDocumentedException {
+    public Document onNetconfMessage(final Document message, final NetconfServerSession session) throws DocumentedException {
         Preconditions.checkNotNull(allNetconfOperations, "Operation router was not initialized properly");
 
         final NetconfOperationExecution netconfOperationExecution;
@@ -67,17 +64,17 @@ public class NetconfOperationRouterImpl implements NetconfOperationRouter {
             final String messageAsString = XmlUtil.toString(message);
             LOG.warn("Unable to handle rpc {} on session {}", messageAsString, session, e);
 
-            final NetconfDocumentedException.ErrorTag tag;
+            final DocumentedException.ErrorTag tag;
             if (e instanceof IllegalArgumentException) {
-                tag = NetconfDocumentedException.ErrorTag.operation_not_supported;
+                tag = DocumentedException.ErrorTag.operation_not_supported;
             } else {
-                tag = NetconfDocumentedException.ErrorTag.operation_failed;
+                tag = DocumentedException.ErrorTag.operation_failed;
             }
 
-            throw new NetconfDocumentedException(
+            throw new DocumentedException(
                 String.format("Unable to handle rpc %s on session %s", messageAsString, session),
-                e, NetconfDocumentedException.ErrorType.application,
-                tag, NetconfDocumentedException.ErrorSeverity.error,
+                e, DocumentedException.ErrorType.application,
+                tag, DocumentedException.ErrorSeverity.error,
                 Collections.singletonMap(tag.toString(), e.getMessage()));
         } catch (RuntimeException e) {
             throw handleUnexpectedEx("Unexpected exception during netconf operation sort", e);
@@ -95,18 +92,18 @@ public class NetconfOperationRouterImpl implements NetconfOperationRouter {
         netconfOperationServiceSnapshot.close();
     }
 
-    private static NetconfDocumentedException handleUnexpectedEx(final String s, final Exception e) throws NetconfDocumentedException {
+    private static DocumentedException handleUnexpectedEx(final String s, final Exception e) throws DocumentedException {
         LOG.error("{}", s, e);
-        return new NetconfDocumentedException("Unexpected error",
-                NetconfDocumentedException.ErrorType.application,
-                NetconfDocumentedException.ErrorTag.operation_failed,
-                NetconfDocumentedException.ErrorSeverity.error,
-                Collections.singletonMap(NetconfDocumentedException.ErrorSeverity.error.toString(), e.toString()));
+        return new DocumentedException("Unexpected error",
+                DocumentedException.ErrorType.application,
+                DocumentedException.ErrorTag.operation_failed,
+                DocumentedException.ErrorSeverity.error,
+                Collections.singletonMap(DocumentedException.ErrorSeverity.error.toString(), e.toString()));
     }
 
     private Document executeOperationWithHighestPriority(final Document message,
             final NetconfOperationExecution netconfOperationExecution)
-            throws NetconfDocumentedException {
+            throws DocumentedException {
         if (LOG.isDebugEnabled()) {
             LOG.debug("Forwarding netconf message {} to {}", XmlUtil.toString(message), netconfOperationExecution.netconfOperation);
         }
@@ -115,7 +112,7 @@ public class NetconfOperationRouterImpl implements NetconfOperationRouter {
     }
 
     private NetconfOperationExecution getNetconfOperationWithHighestPriority(
-            final Document message, final NetconfServerSession session) throws NetconfDocumentedException {
+            final Document message, final NetconfServerSession session) throws DocumentedException {
 
         NavigableMap<HandlingPriority, NetconfOperation> sortedByPriority = getSortedNetconfOperationsWithCanHandle(
                 message, session);
@@ -129,7 +126,7 @@ public class NetconfOperationRouterImpl implements NetconfOperationRouter {
     }
 
     private TreeMap<HandlingPriority, NetconfOperation> getSortedNetconfOperationsWithCanHandle(final Document message,
-            final NetconfServerSession session) throws NetconfDocumentedException {
+            final NetconfServerSession session) throws DocumentedException {
         TreeMap<HandlingPriority, NetconfOperation> sortedPriority = Maps.newTreeMap();
 
         for (NetconfOperation netconfOperation : allNetconfOperations) {
@@ -158,11 +155,11 @@ public class NetconfOperationRouterImpl implements NetconfOperationRouter {
         }
 
         @Override
-        public Document execute(final Document requestMessage) throws NetconfDocumentedException {
-            throw new NetconfDocumentedException("This execution represents the termination point in operation execution and cannot be executed itself",
-                    NetconfDocumentedException.ErrorType.application,
-                    NetconfDocumentedException.ErrorTag.operation_failed,
-                    NetconfDocumentedException.ErrorSeverity.error);
+        public Document execute(final Document requestMessage) throws DocumentedException {
+            throw new DocumentedException("This execution represents the termination point in operation execution and cannot be executed itself",
+                    DocumentedException.ErrorType.application,
+                    DocumentedException.ErrorTag.operation_failed,
+                    DocumentedException.ErrorSeverity.error);
         }
     };
 
@@ -181,7 +178,7 @@ public class NetconfOperationRouterImpl implements NetconfOperationRouter {
         }
 
         @Override
-        public Document execute(final Document message) throws NetconfDocumentedException {
+        public Document execute(final Document message) throws DocumentedException {
             return netconfOperation.handle(message, subsequentExecution);
         }
 
index e336914981222e5572a77a4f2b09a05fea82dc50..15205e4bed75e3440420c404dc90d3ead0ed5400 100644 (file)
@@ -12,7 +12,7 @@ import com.google.common.collect.Maps;
 import io.netty.channel.ChannelHandler;
 import io.netty.channel.ChannelHandlerContext;
 import java.util.Map;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
 import org.opendaylight.controller.netconf.util.messages.SendErrorExceptionUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -41,9 +41,9 @@ public final class DeserializerExceptionHandler implements ChannelHandler {
 
         Map<String, String> info = Maps.newHashMap();
         info.put("cause", cause.getMessage());
-        NetconfDocumentedException ex = new NetconfDocumentedException(cause.getMessage(),
-                NetconfDocumentedException.ErrorType.rpc, NetconfDocumentedException.ErrorTag.malformed_message,
-                NetconfDocumentedException.ErrorSeverity.error, info);
+        DocumentedException ex = new DocumentedException(cause.getMessage(),
+                DocumentedException.ErrorType.rpc, DocumentedException.ErrorTag.malformed_message,
+                DocumentedException.ErrorSeverity.error, info);
 
         SendErrorExceptionUtil.sendErrorMessage(ctx.channel(), ex);
     }
index f20bbda75e4ac795d037f29d43be7b01b0dabc06..b8b544b90d25e71395d6aee1c6489210a604d2f1 100644 (file)
@@ -16,6 +16,7 @@ import static org.mockito.Matchers.anySetOf;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
+
 import com.google.common.base.Preconditions;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
@@ -28,7 +29,6 @@ import io.netty.util.concurrent.GlobalEventExecutor;
 import java.io.DataOutputStream;
 import java.io.InputStream;
 import java.io.InputStreamReader;
-import java.lang.management.ManagementFactory;
 import java.net.InetSocketAddress;
 import java.net.Socket;
 import java.util.Arrays;
@@ -49,8 +49,9 @@ import org.junit.BeforeClass;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
-import org.opendaylight.controller.netconf.api.Capability;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.config.util.capability.Capability;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.netconf.api.NetconfMessage;
 import org.opendaylight.controller.netconf.api.monitoring.CapabilityListener;
 import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService;
@@ -71,7 +72,6 @@ import org.opendaylight.controller.netconf.nettyutil.handler.exi.NetconfStartExi
 import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader;
 import org.opendaylight.controller.netconf.util.messages.NetconfMessageUtil;
 import org.opendaylight.controller.netconf.util.test.XmlFileLoader;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.opendaylight.protocol.framework.NeverReconnectStrategy;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.CapabilitiesBuilder;
@@ -114,8 +114,6 @@ public class ConcurrentClientsTest {
     private EventLoopGroup nettyGroup;
     private NetconfClientDispatcher netconfClientDispatcher;
 
-    private DefaultCommitNotificationProducer commitNot;
-
     HashedWheelTimer hashedWheelTimer;
     private TestingNetconfOperation testingNetconfOperation;
 
@@ -129,8 +127,7 @@ public class ConcurrentClientsTest {
 
             }
         }).when(monitoring).registerListener(any(NetconfMonitoringService.MonitoringListener.class));
-        doNothing().when(monitoring).onCapabilitiesAdded(anySetOf(Capability.class));
-        doNothing().when(monitoring).onCapabilitiesRemoved(anySetOf(Capability.class));
+        doNothing().when(monitoring).onCapabilitiesChanged(anySetOf(Capability.class), anySetOf(Capability.class));
         doReturn(new CapabilitiesBuilder().setCapability(Collections.<Uri>emptyList()).build()).when(monitoring).getCapabilities();
         return monitoring;
     }
@@ -164,9 +161,7 @@ public class ConcurrentClientsTest {
         SessionIdProvider idProvider = new SessionIdProvider();
 
         NetconfServerSessionNegotiatorFactory serverNegotiatorFactory = new NetconfServerSessionNegotiatorFactory(
-                hashedWheelTimer, factoriesListener, idProvider, 5000, commitNot, createMockedMonitoringService(), serverCaps);
-
-        commitNot = new DefaultCommitNotificationProducer(ManagementFactory.getPlatformMBeanServer());
+                hashedWheelTimer, factoriesListener, idProvider, 5000, createMockedMonitoringService(), serverCaps);
 
         NetconfServerDispatcherImpl.ServerChannelInitializer serverChannelInitializer = new NetconfServerDispatcherImpl.ServerChannelInitializer(serverNegotiatorFactory);
         final NetconfServerDispatcherImpl dispatch = new NetconfServerDispatcherImpl(serverChannelInitializer, nettyGroup, nettyGroup);
@@ -177,7 +172,6 @@ public class ConcurrentClientsTest {
 
     @After
     public void tearDown(){
-        commitNot.close();
         hashedWheelTimer.stop();
         try {
             nettyGroup.shutdownGracefully().get();
@@ -247,7 +241,7 @@ public class ConcurrentClientsTest {
         }
 
         @Override
-        public Document handle(Document requestMessage, NetconfOperationChainedExecution subsequentOperation) throws NetconfDocumentedException {
+        public Document handle(Document requestMessage, NetconfOperationChainedExecution subsequentOperation) throws DocumentedException {
             try {
                 LOG.info("Handling netconf message from test {}", XmlUtil.toString(requestMessage));
                 counter.getAndIncrement();
index 4fd04e29ef178148ced11c1e0fdd2e252703fd4a..d7d679bcafc97db9d241fd7575b4e030b1940314 100644 (file)
@@ -12,7 +12,6 @@ import io.netty.channel.ChannelFuture;
 import io.netty.channel.EventLoopGroup;
 import io.netty.channel.nio.NioEventLoopGroup;
 import io.netty.util.HashedWheelTimer;
-import java.lang.management.ManagementFactory;
 import java.net.InetSocketAddress;
 import org.junit.After;
 import org.junit.Before;
@@ -23,7 +22,6 @@ public class NetconfDispatcherImplTest {
 
     private EventLoopGroup nettyGroup;
     private NetconfServerDispatcherImpl dispatch;
-    private DefaultCommitNotificationProducer commitNot;
     private HashedWheelTimer hashedWheelTimer;
 
 
@@ -31,14 +29,12 @@ public class NetconfDispatcherImplTest {
     public void setUp() throws Exception {
         nettyGroup = new NioEventLoopGroup();
 
-        commitNot = new DefaultCommitNotificationProducer(
-                ManagementFactory.getPlatformMBeanServer());
         AggregatedNetconfOperationServiceFactory factoriesListener = new AggregatedNetconfOperationServiceFactory();
 
         SessionIdProvider idProvider = new SessionIdProvider();
         hashedWheelTimer = new HashedWheelTimer();
         NetconfServerSessionNegotiatorFactory serverNegotiatorFactory = new NetconfServerSessionNegotiatorFactory(
-                hashedWheelTimer, factoriesListener, idProvider, 5000, commitNot, ConcurrentClientsTest.createMockedMonitoringService());
+                hashedWheelTimer, factoriesListener, idProvider, 5000, ConcurrentClientsTest.createMockedMonitoringService());
 
         NetconfServerDispatcherImpl.ServerChannelInitializer serverChannelInitializer = new NetconfServerDispatcherImpl.ServerChannelInitializer(serverNegotiatorFactory);
 
@@ -49,7 +45,6 @@ public class NetconfDispatcherImplTest {
     @After
     public void tearDown() throws Exception {
         hashedWheelTimer.stop();
-        commitNot.close();
         nettyGroup.shutdownGracefully();
     }
 
index b925295e74a8ec86e8b235a48f691c2222d82aa8..bc04b3320ec1bdbead036fa48f9a4e4bb36b7fe9 100644 (file)
@@ -21,7 +21,7 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
 import org.junit.runners.Parameterized.Parameters;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
index 9afa76148e31967abd9dd041775c921b4f2ad742..cacee6c986208c98894ecb23457b63c9fc28db2f 100644 (file)
@@ -16,20 +16,22 @@ import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
+
 import io.netty.channel.Channel;
 import io.netty.channel.ChannelFuture;
 import io.netty.util.concurrent.GenericFutureListener;
 import org.junit.Test;
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.config.util.xml.XmlElement;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
 import org.opendaylight.controller.netconf.api.NetconfMessage;
 import org.opendaylight.controller.netconf.api.NetconfTerminationReason;
 import org.opendaylight.controller.netconf.impl.NetconfServerSession;
 import org.opendaylight.controller.netconf.impl.NetconfServerSessionListener;
 import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.w3c.dom.Document;
 
 public class DefaultCloseSessionTest {
@@ -70,7 +72,7 @@ public class DefaultCloseSessionTest {
         verify(listener).onSessionTerminated(any(NetconfServerSession.class), any(NetconfTerminationReason.class));
     }
 
-    @Test(expected = NetconfDocumentedException.class)
+    @Test(expected = DocumentedException.class)
     public void testDefaultCloseSession2() throws Exception {
         AutoCloseable res = mock(AutoCloseable.class);
         doThrow(NetconfDocumentedException.class).when(res).close();
diff --git a/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultCommitTest.java b/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultCommitTest.java
deleted file mode 100644 (file)
index 0c74065..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.impl.mapping.operations;
-
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.anySetOf;
-import static org.mockito.Mockito.anyString;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import java.util.Collections;
-import org.junit.Before;
-import org.junit.Test;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService;
-import org.opendaylight.controller.netconf.impl.DefaultCommitNotificationProducer;
-import org.opendaylight.controller.netconf.impl.NetconfServerSession;
-import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationRouter;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationChainedExecution;
-import org.opendaylight.controller.netconf.util.test.XmlFileLoader;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.CapabilitiesBuilder;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-public class DefaultCommitTest {
-
-    private NetconfOperationChainedExecution operation;
-    private Document requestMessage;
-    private NetconfOperationRouter router;
-    private DefaultCommitNotificationProducer notifier;
-    private NetconfMonitoringService cap;
-    private DefaultCommit commit;
-
-    @Before
-    public void setUp() throws Exception {
-        operation = mock(NetconfOperationChainedExecution.class);
-        doReturn(XmlUtil.newDocument()).when(operation).execute(any(Document.class));
-        router = mock(NetconfOperationRouter.class);
-        doReturn(false).when(operation).isExecutionTermination();
-        notifier = mock(DefaultCommitNotificationProducer.class);
-        doNothing().when(notifier).sendCommitNotification(anyString(), any(Element.class), anySetOf(String.class));
-        cap = mock(NetconfMonitoringService.class);
-        doReturn(new CapabilitiesBuilder().setCapability(Collections.<Uri>emptyList()).build()).when(cap).getCapabilities();
-        Document rpcData = XmlFileLoader.xmlFileToDocument("netconfMessages/editConfig_expectedResult.xml");
-        doReturn(rpcData).when(router).onNetconfMessage(any(Document.class), any(NetconfServerSession.class));
-        commit = new DefaultCommit(notifier, cap, "", router);
-    }
-
-    @Test
-    public void testHandleWithNotification() throws Exception {
-        requestMessage = XmlFileLoader.xmlFileToDocument("netconfMessages/commit.xml");
-        commit.handle(requestMessage, operation);
-        verify(operation, times(1)).execute(requestMessage);
-        verify(notifier, times(1)).sendCommitNotification(anyString(), any(Element.class), anySetOf(String.class));
-    }
-
-    @Test
-    public void testHandleWithoutNotification() throws Exception {
-        requestMessage = XmlFileLoader.xmlFileToDocument("netconfMessages/commit.xml");
-        Element elem = requestMessage.getDocumentElement();
-        elem.setAttribute("notify", "false");
-        commit.handle(requestMessage, operation);
-        verify(operation, times(1)).execute(requestMessage);
-        verify(notifier, never()).sendCommitNotification(anyString(), any(Element.class), anySetOf(String.class));
-    }
-
-    @Test(expected = NetconfDocumentedException.class)
-    public void testHandle() throws Exception {
-        Document rpcData = XmlFileLoader.xmlFileToDocument("netconfMessages/get.xml");
-        doReturn(rpcData).when(router).onNetconfMessage(any(Document.class), any(NetconfServerSession.class));
-        requestMessage = XmlFileLoader.xmlFileToDocument("netconfMessages/commit.xml");
-        commit.handle(requestMessage, operation);
-    }
-}
index aaaf5991d425d762ab1afa8303ae69d86c651c36..466ec97f18f07e4f5d361c9db9047ba55e19170d 100644 (file)
@@ -20,9 +20,9 @@ import io.netty.channel.Channel;
 import io.netty.channel.ChannelHandler;
 import io.netty.channel.ChannelPipeline;
 import org.junit.Test;
+import org.opendaylight.controller.config.util.xml.XmlElement;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.netconf.impl.NetconfServerSession;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.w3c.dom.Document;
 
 public class DefaultStopExiTest {
index 4f722f4db44b058f49a9d774de02a9390b8710c5..7022cd13bb326a5e968159b8812b2936b75c3f67 100644 (file)
       <groupId>org.opendaylight.yangtools</groupId>
       <artifactId>object-cache-guava</artifactId>
     </dependency>
-    <dependency>
-      <groupId>org.opendaylight.yangtools</groupId>
-      <artifactId>mockito-configuration</artifactId>
-    </dependency>
 
     <dependency>
       <groupId>${project.groupId}</groupId>
index 1e31782bb22c87fe1c151e49fa22be9bd0344b60..b9d16bf34deaec6a6846fa38ee9c4b1cd4064021 100644 (file)
@@ -9,11 +9,7 @@ package org.opendaylight.controller.netconf.it;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anySetOf;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.mock;
+
 import com.google.common.io.ByteStreams;
 import io.netty.channel.Channel;
 import io.netty.channel.ChannelFuture;
@@ -36,6 +32,9 @@ import java.util.List;
 import java.util.concurrent.TimeUnit;
 import org.junit.After;
 import org.junit.Before;
+import org.opendaylight.controller.config.facade.xml.ConfigSubsystemFacadeFactory;
+import org.opendaylight.controller.config.facade.xml.osgi.EnumResolver;
+import org.opendaylight.controller.config.facade.xml.osgi.YangStoreService;
 import org.opendaylight.controller.config.manager.impl.AbstractConfigTest;
 import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
 import org.opendaylight.controller.config.spi.ModuleFactory;
@@ -50,10 +49,7 @@ import org.opendaylight.controller.netconf.client.NetconfClientDispatcherImpl;
 import org.opendaylight.controller.netconf.client.SimpleNetconfClientSessionListener;
 import org.opendaylight.controller.netconf.client.conf.NetconfClientConfiguration;
 import org.opendaylight.controller.netconf.client.conf.NetconfClientConfigurationBuilder;
-import org.opendaylight.controller.netconf.confignetconfconnector.osgi.EnumResolver;
 import org.opendaylight.controller.netconf.confignetconfconnector.osgi.NetconfOperationServiceFactoryImpl;
-import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreService;
-import org.opendaylight.controller.netconf.impl.DefaultCommitNotificationProducer;
 import org.opendaylight.controller.netconf.impl.NetconfServerDispatcherImpl;
 import org.opendaylight.controller.netconf.impl.NetconfServerSessionNegotiatorFactory;
 import org.opendaylight.controller.netconf.impl.SessionIdProvider;
@@ -62,15 +58,13 @@ import org.opendaylight.controller.netconf.impl.osgi.NetconfMonitoringServiceImp
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactory;
 import org.opendaylight.controller.netconf.monitoring.osgi.NetconfMonitoringActivator;
 import org.opendaylight.controller.netconf.monitoring.osgi.NetconfMonitoringOperationService;
-import org.opendaylight.controller.netconf.notifications.BaseNetconfNotificationListener;
 import org.opendaylight.controller.netconf.util.test.XmlFileLoader;
 import org.opendaylight.protocol.framework.NeverReconnectStrategy;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfCapabilityChange;
+import org.opendaylight.yangtools.sal.binding.generator.util.BindingRuntimeContext;
 import org.opendaylight.yangtools.yang.binding.BindingMapping;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider;
 import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
-import org.w3c.dom.Element;
 
 public abstract class AbstractNetconfConfigTest extends AbstractConfigTest {
 
@@ -84,6 +78,7 @@ public abstract class AbstractNetconfConfigTest extends AbstractConfigTest {
                                         new IdentityTestModuleFactory(),
                                         new MultipleDependenciesModuleFactory() };
 
+    protected ConfigSubsystemFacadeFactory configSubsystemFacadeFactory;
     private EventLoopGroup nettyThreadgroup;
     private HashedWheelTimer hashedWheelTimer;
 
@@ -109,7 +104,8 @@ public abstract class AbstractNetconfConfigTest extends AbstractConfigTest {
 
         final AggregatedNetconfOperationServiceFactory factoriesListener = new AggregatedNetconfOperationServiceFactory();
         final NetconfMonitoringService netconfMonitoringService = getNetconfMonitoringService(factoriesListener);
-        factoriesListener.onAddNetconfOperationServiceFactory(new NetconfOperationServiceFactoryImpl(getYangStore()));
+        configSubsystemFacadeFactory = new ConfigSubsystemFacadeFactory(configRegistryClient, configRegistryClient, getYangStore());
+        factoriesListener.onAddNetconfOperationServiceFactory(new NetconfOperationServiceFactoryImpl(configSubsystemFacadeFactory));
         factoriesListener.onAddNetconfOperationServiceFactory(new NetconfMonitoringActivator.NetconfMonitoringOperationServiceFactory(new NetconfMonitoringOperationService(netconfMonitoringService)));
 
         for (final NetconfOperationServiceFactory netconfOperationServiceFactory : getAdditionalServiceFactories(factoriesListener)) {
@@ -139,7 +135,7 @@ public abstract class AbstractNetconfConfigTest extends AbstractConfigTest {
     }
 
     private Channel startNetconfTcpServer(final AggregatedNetconfOperationServiceFactory listener, final NetconfMonitoringService monitoring) throws Exception {
-        final NetconfServerDispatcherImpl dispatch = createDispatcher(listener, monitoring, getNotificationProducer());
+        final NetconfServerDispatcherImpl dispatch = createDispatcher(listener, monitoring);
 
         final ChannelFuture s;
         if(getTcpServerAddress() instanceof LocalAddress) {
@@ -151,13 +147,6 @@ public abstract class AbstractNetconfConfigTest extends AbstractConfigTest {
         return s.channel();
     }
 
-    protected DefaultCommitNotificationProducer getNotificationProducer() {
-        final DefaultCommitNotificationProducer notificationProducer = mock(DefaultCommitNotificationProducer.class);
-        doNothing().when(notificationProducer).close();
-        doNothing().when(notificationProducer).sendCommitNotification(anyString(), any(Element.class), anySetOf(String.class));
-        return notificationProducer;
-    }
-
     protected Iterable<NetconfOperationServiceFactory> getAdditionalServiceFactories(final AggregatedNetconfOperationServiceFactory factoriesListener) throws Exception {
         return Collections.emptySet();
     }
@@ -174,7 +163,7 @@ public abstract class AbstractNetconfConfigTest extends AbstractConfigTest {
 
     private HardcodedYangStoreService getYangStore() throws IOException {
         final Collection<InputStream> yangDependencies = getBasicYangs();
-        return new HardcodedYangStoreService(yangDependencies);
+        return new HardcodedYangStoreService(yangDependencies, getBindingRuntimeContext());
     }
 
     static Collection<InputStream> getBasicYangs() throws IOException {
@@ -203,12 +192,11 @@ public abstract class AbstractNetconfConfigTest extends AbstractConfigTest {
     }
 
     protected NetconfServerDispatcherImpl createDispatcher(
-            final AggregatedNetconfOperationServiceFactory factoriesListener, final NetconfMonitoringService sessionMonitoringService,
-            final DefaultCommitNotificationProducer commitNotifier) {
+            final AggregatedNetconfOperationServiceFactory factoriesListener, final NetconfMonitoringService sessionMonitoringService) {
         final SessionIdProvider idProvider = new SessionIdProvider();
 
         final NetconfServerSessionNegotiatorFactory serverNegotiatorFactory = new NetconfServerSessionNegotiatorFactory(
-                hashedWheelTimer, factoriesListener, idProvider, SERVER_CONNECTION_TIMEOUT_MILLIS, commitNotifier, sessionMonitoringService);
+                hashedWheelTimer, factoriesListener, idProvider, SERVER_CONNECTION_TIMEOUT_MILLIS, sessionMonitoringService);
 
         final NetconfServerDispatcherImpl.ServerChannelInitializer serverChannelInitializer = new NetconfServerDispatcherImpl.ServerChannelInitializer(
                 serverNegotiatorFactory);
@@ -243,18 +231,15 @@ public abstract class AbstractNetconfConfigTest extends AbstractConfigTest {
     }
 
     public static final class HardcodedYangStoreService extends YangStoreService {
-        public HardcodedYangStoreService(final Collection<? extends InputStream> inputStreams) throws IOException {
+        public HardcodedYangStoreService(final Collection<? extends InputStream> inputStreams, final BindingRuntimeContext bindingRuntimeContext) throws IOException {
             super(new SchemaContextProvider() {
                 @Override
                 public SchemaContext getSchemaContext() {
                     return getSchema(inputStreams);
                 }
-            }, new BaseNetconfNotificationListener() {
-                @Override
-                public void onCapabilityChanged(final NetconfCapabilityChange capabilityChange) {
-                    // NOOP
-                }
             });
+
+            refresh(bindingRuntimeContext);
         }
 
         private static SchemaContext getSchema(final Collection<? extends InputStream> inputStreams) {
index c421a46fdf1662405b18390e81df1c6945a660fe..ba435e8a366d16d3a776b8b2f502b7c9e6aa22d2 100644 (file)
@@ -9,15 +9,17 @@ package org.opendaylight.controller.netconf.it;
 
 import static org.junit.Assert.assertEquals;
 import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
 import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
+import static org.opendaylight.controller.config.util.xml.XmlUtil.readXmlToDocument;
 import static org.opendaylight.controller.netconf.util.test.XmlUnitUtil.assertContainsElementWithName;
 import static org.opendaylight.controller.netconf.util.test.XmlUnitUtil.assertElementsCount;
-import static org.opendaylight.controller.netconf.util.xml.XmlUtil.readXmlToDocument;
 
+import com.google.common.collect.HashBiMap;
 import com.google.common.collect.Lists;
 import java.io.IOException;
-import java.lang.management.ManagementFactory;
 import java.net.InetSocketAddress;
 import java.net.SocketAddress;
 import java.util.List;
@@ -27,16 +29,18 @@ import javax.management.NotificationListener;
 import org.junit.Test;
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
+import org.opendaylight.controller.config.api.jmx.notifications.CommitJMXNotification;
+import org.opendaylight.controller.config.api.jmx.notifications.ConfigJMXNotification;
 import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
 import org.opendaylight.controller.config.persist.api.Persister;
+import org.opendaylight.controller.config.persist.impl.ConfigPersisterNotificationHandler;
 import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.api.jmx.CommitJMXNotification;
 import org.opendaylight.controller.netconf.client.TestingNetconfClient;
-import org.opendaylight.controller.netconf.impl.DefaultCommitNotificationProducer;
-import org.opendaylight.controller.netconf.persist.impl.ConfigPersisterNotificationHandler;
 import org.opendaylight.controller.netconf.util.test.XmlFileLoader;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.test.types.rev131127.TestIdentity1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.test.types.rev131127.TestIdentity2;
+import org.opendaylight.yangtools.sal.binding.generator.util.BindingRuntimeContext;
 import org.w3c.dom.Document;
-import org.w3c.dom.Element;
 import org.xml.sax.SAXException;
 
 public class NetconfConfigPersisterITTest extends AbstractNetconfConfigTest {
@@ -44,17 +48,11 @@ public class NetconfConfigPersisterITTest extends AbstractNetconfConfigTest {
     public static final int PORT = 12026;
     private static final InetSocketAddress TCP_ADDRESS = new InetSocketAddress(LOOPBACK_ADDRESS, PORT);
 
-
     @Override
     protected SocketAddress getTcpServerAddress() {
         return TCP_ADDRESS;
     }
 
-    @Override
-    protected DefaultCommitNotificationProducer getNotificationProducer() {
-        return new DefaultCommitNotificationProducer(ManagementFactory.getPlatformMBeanServer());
-    }
-
     @Test
     public void testNetconfCommitNotifications() throws Exception {
         final VerifyingNotificationListener notificationVerifier = createCommitNotificationListener();
@@ -62,31 +60,39 @@ public class NetconfConfigPersisterITTest extends AbstractNetconfConfigTest {
 
         try (TestingNetconfClient persisterClient = new TestingNetconfClient("persister", getClientDispatcher(), getClientConfiguration(TCP_ADDRESS, 4000))) {
             try (ConfigPersisterNotificationHandler configPersisterNotificationHandler = new ConfigPersisterNotificationHandler(
-                    platformMBeanServer, mockedAggregator)) {
+                    platformMBeanServer, mockedAggregator, configSubsystemFacadeFactory)) {
 
                 try (TestingNetconfClient netconfClient = new TestingNetconfClient("client", getClientDispatcher(), getClientConfiguration(TCP_ADDRESS, 4000))) {
-                    NetconfMessage response = netconfClient.sendMessage(loadGetConfigMessage());
-                    assertContainsElementWithName(response.getDocument(), "modules");
-                    assertContainsElementWithName(response.getDocument(), "services");
-                    response = netconfClient.sendMessage(loadCommitMessage());
-                    assertContainsElementWithName(response.getDocument(), "ok");
-
-                    response = netconfClient.sendMessage(loadEditConfigMessage());
+                    NetconfMessage response = netconfClient.sendMessage(loadEditConfigMessage());
                     assertContainsElementWithName(response.getDocument(), "ok");
                     response = netconfClient.sendMessage(loadCommitMessage());
                     assertContainsElementWithName(response.getDocument(), "ok");
+
+                    response = netconfClient.sendMessage(loadGetConfigMessage());
+                    assertContainsElementWithName(response.getDocument(), "modules");
+                    assertContainsElementWithName(response.getDocument(), "services");
                 }
             }
         }
 
-        notificationVerifier.assertNotificationCount(2);
-        notificationVerifier.assertNotificationContent(0, 0, 0, 8);
-        notificationVerifier.assertNotificationContent(1, 4, 3, 8);
+        notificationVerifier.assertNotificationCount(1);
 
-        mockedAggregator.assertSnapshotCount(2);
+        mockedAggregator.assertSnapshotCount(1);
         // Capabilities are stripped for persister
-        mockedAggregator.assertSnapshotContent(0, 0, 0, 1);
-        mockedAggregator.assertSnapshotContent(1, 4, 3, 3);
+        mockedAggregator.assertSnapshotContent(0, 4, 3, 3);
+    }
+
+    @Override
+    protected BindingRuntimeContext getBindingRuntimeContext() {
+        final BindingRuntimeContext ret = super.getBindingRuntimeContext();
+        doReturn(TestIdentity1.class).when(ret).getIdentityClass(TestIdentity1.QNAME);
+        doReturn(TestIdentity2.class).when(ret).getIdentityClass(TestIdentity2.QNAME);
+        final HashBiMap<String, String> toBeReturned = HashBiMap.create();
+        toBeReturned.put("two", "Two");
+        toBeReturned.put("one", "One");
+        toBeReturned.put("version1", "Version1");
+        doReturn(toBeReturned).when(ret).getEnumMapping(anyString());
+        return ret;
     }
 
     private VerifyingPersister mockAggregator() throws IOException {
@@ -95,7 +101,7 @@ public class NetconfConfigPersisterITTest extends AbstractNetconfConfigTest {
 
     private VerifyingNotificationListener createCommitNotificationListener() throws InstanceNotFoundException {
         final VerifyingNotificationListener listener = new VerifyingNotificationListener();
-        platformMBeanServer.addNotificationListener(DefaultCommitNotificationProducer.OBJECT_NAME, listener, null, null);
+        platformMBeanServer.addNotificationListener(ConfigJMXNotification.OBJECT_NAME, listener, null, null);
         return listener;
     }
 
@@ -123,16 +129,9 @@ public class NetconfConfigPersisterITTest extends AbstractNetconfConfigTest {
             assertEquals(size, notifications.size());
         }
 
-        void assertNotificationContent(final int notificationIndex, final int expectedModulesSize, final int expectedServicesSize, final int expectedCapsSize) {
+        void assertNotificationContent(final int notificationIndex) {
             final Notification notification = notifications.get(notificationIndex);
             assertEquals(CommitJMXNotification.class, notification.getClass());
-            final int capsSize = ((CommitJMXNotification) notification).getCapabilities().size();
-            assertEquals("Expected capabilities count", expectedCapsSize, capsSize);
-            final Element configSnapshot = ((CommitJMXNotification) notification).getConfigSnapshot();
-            final int modulesSize = configSnapshot.getElementsByTagName("module").getLength();
-            assertEquals("Expected modules count", expectedModulesSize, modulesSize);
-            final int servicesSize = configSnapshot.getElementsByTagName("instance").getLength();
-            assertEquals("Expected services count", expectedServicesSize, servicesSize);
         }
     }
 
@@ -164,7 +163,7 @@ public class NetconfConfigPersisterITTest extends AbstractNetconfConfigTest {
                 throws SAXException, IOException {
             final ConfigSnapshotHolder snapshot = snapshots.get(notificationIndex);
             final int capsSize = snapshot.getCapabilities().size();
-            assertEquals("Expected capabilities count", expectedCapsSize, capsSize);
+            assertEquals("Expected capabilities count should be " + expectedCapsSize + " but was " + snapshot.getCapabilities(), expectedCapsSize, capsSize);
             final Document configSnapshot = readXmlToDocument(snapshot.getConfigSnapshot());
             assertElementsCount(configSnapshot, "module", expectedModulesSize);
             assertElementsCount(configSnapshot, "instance", expectedServicesSize);
index e745b393fbcb271868e0f9e2c68366a6b44f38c1..79733cc6f5dfd31029eb23cd846f7a4b50bceb8e 100644 (file)
@@ -27,14 +27,14 @@ import java.util.Collections;
 import java.util.List;
 import java.util.Set;
 import org.junit.Test;
-import org.opendaylight.controller.netconf.api.Capability;
+import org.opendaylight.controller.config.util.capability.Capability;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.netconf.api.NetconfMessage;
 import org.opendaylight.controller.netconf.api.monitoring.CapabilityListener;
 import org.opendaylight.controller.netconf.client.TestingNetconfClient;
 import org.opendaylight.controller.netconf.impl.osgi.AggregatedNetconfOperationServiceFactory;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService;
 import org.opendaylight.controller.netconf.util.test.XmlFileLoader;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.w3c.dom.Document;
 
 public class NetconfITMonitoringTest extends AbstractNetconfConfigTest {
@@ -62,7 +62,6 @@ public class NetconfITMonitoringTest extends AbstractNetconfConfigTest {
         }
     }
 
-
     @Test(timeout = 13 * 10000)
     public void testClientHelloWithAuth() throws Exception {
         String fileName = "netconfMessages/client_hello_with_auth.xml";
index f15c41a4540484bb66617d4d4aa96c433917e08e..91dbd4117df22a6a8cf087678f7296f75d3d0e73 100644 (file)
@@ -41,6 +41,7 @@ import org.apache.sshd.server.session.ServerSession;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.netconf.api.NetconfMessage;
 import org.opendaylight.controller.netconf.auth.AuthProvider;
 import org.opendaylight.controller.netconf.client.NetconfClientDispatcher;
@@ -56,7 +57,6 @@ import org.opendaylight.controller.netconf.ssh.SshProxyServer;
 import org.opendaylight.controller.netconf.ssh.SshProxyServerConfigurationBuilder;
 import org.opendaylight.controller.netconf.util.messages.NetconfMessageUtil;
 import org.opendaylight.controller.netconf.util.osgi.NetconfConfigUtil;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.opendaylight.controller.sal.connect.api.RemoteDevice;
 import org.opendaylight.controller.sal.connect.netconf.listener.NetconfDeviceCommunicator;
 import org.opendaylight.controller.sal.connect.netconf.listener.NetconfSessionPreferences;
index 70d7acf159052ac3c15c7d58f108e18c84f6942a..866fe1ac61b3e52fb321523c640b57be02d0dafe 100644 (file)
@@ -32,18 +32,18 @@ import org.junit.Before;
 import org.junit.Test;
 import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
 import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.config.util.xml.XmlElement;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.config.yang.test.impl.DepTestImplModuleFactory;
 import org.opendaylight.controller.config.yang.test.impl.MultipleDependenciesModuleFactory;
 import org.opendaylight.controller.config.yang.test.impl.MultipleDependenciesModuleMXBean;
 import org.opendaylight.controller.config.yang.test.impl.NetconfTestImplModuleFactory;
 import org.opendaylight.controller.config.yang.test.impl.NetconfTestImplModuleMXBean;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
 import org.opendaylight.controller.netconf.api.NetconfMessage;
 import org.opendaylight.controller.netconf.client.NetconfClientDispatcher;
 import org.opendaylight.controller.netconf.client.TestingNetconfClient;
 import org.opendaylight.controller.netconf.util.test.XmlFileLoader;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.test.types.rev131127.TestIdentity1;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.test.types.rev131127.TestIdentity2;
 import org.opendaylight.yangtools.sal.binding.generator.util.BindingRuntimeContext;
@@ -214,17 +214,17 @@ public class NetconfITTest extends AbstractNetconfConfigTest {
         }
     }
 
-    private void assertIsOK(final Document rpcReply) throws NetconfDocumentedException {
+    private void assertIsOK(final Document rpcReply) throws DocumentedException {
         assertEquals("rpc-reply", rpcReply.getDocumentElement().getLocalName());
         assertEquals("ok", XmlElement.fromDomDocument(rpcReply).getOnlyChildElement().getName());
     }
 
-    private Document assertGetConfigWorks(final TestingNetconfClient netconfClient) throws InterruptedException, ExecutionException, TimeoutException, NetconfDocumentedException {
+    private Document assertGetConfigWorks(final TestingNetconfClient netconfClient) throws InterruptedException, ExecutionException, TimeoutException, DocumentedException {
         return assertGetConfigWorks(netconfClient, getGetConfig());
     }
 
     private Document assertGetConfigWorks(final TestingNetconfClient netconfClient, final NetconfMessage getConfigMessage)
-            throws InterruptedException, ExecutionException, TimeoutException, NetconfDocumentedException {
+            throws InterruptedException, ExecutionException, TimeoutException, DocumentedException {
         final NetconfMessage rpcReply = netconfClient.sendMessage(getConfigMessage);
         assertNotNull(rpcReply);
         assertEquals("data", XmlElement.fromDomDocument(rpcReply.getDocument()).getOnlyChildElement().getName());
diff --git a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/SSLUtil.java b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/SSLUtil.java
deleted file mode 100644 (file)
index 56015b9..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.it;
-
-import com.google.common.base.Preconditions;
-import java.io.IOException;
-import java.io.InputStream;
-import java.security.KeyManagementException;
-import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.UnrecoverableKeyException;
-import java.security.cert.CertificateException;
-import javax.net.ssl.KeyManagerFactory;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.TrustManagerFactory;
-
-public final class SSLUtil {
-
-    private SSLUtil() {}
-
-    public static SSLContext initializeSecureContext(final String pass, final InputStream ksKeysFile, final InputStream ksTrustFile,
-                                                     final String algorithm) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException,
-            UnrecoverableKeyException, KeyManagementException {
-
-        Preconditions.checkNotNull(ksTrustFile, "ksTrustFile cannot be null");
-        Preconditions.checkNotNull(ksKeysFile, "ksKeysFile cannot be null");
-
-        final char[] passphrase = pass.toCharArray();
-
-        // First initialize the key and trust material.
-        final KeyStore ksKeys = KeyStore.getInstance("JKS");
-        ksKeys.load(ksKeysFile, passphrase);
-        final KeyStore ksTrust = KeyStore.getInstance("JKS");
-        ksTrust.load(ksTrustFile, passphrase);
-
-        // KeyManager's decide which key material to use.
-        final KeyManagerFactory kmf = KeyManagerFactory.getInstance(algorithm);
-        kmf.init(ksKeys, passphrase);
-
-        // TrustManager's decide whether to allow connections.
-        final TrustManagerFactory tmf = TrustManagerFactory.getInstance(algorithm);
-        tmf.init(ksTrust);
-
-        final SSLContext sslContext = SSLContext.getInstance("TLS");
-
-        // Create/initialize the SSLContext with key material
-        sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
-        return sslContext;
-    }
-
-}
index ab8635b62df3d7a031d739ec2fa27d39043640fc..85d38bced2305047a6e2399b24d2aaee3241cd23 100644 (file)
       <groupId>${project.groupId}</groupId>
       <artifactId>netconf-api</artifactId>
     </dependency>
+      <dependency>
+          <groupId>org.opendaylight.controller</groupId>
+          <artifactId>config-manager-facade-xml</artifactId>
+          <version>0.4.0-SNAPSHOT</version>
+      </dependency>
 
     <dependency>
       <groupId>com.google.guava</groupId>
         <plugin>
             <groupId>org.opendaylight.yangtools</groupId>
             <artifactId>yang-maven-plugin</artifactId>
-            <executions>
-                <execution>
-                    <id>config</id>
-                    <goals>
-                        <goal>generate-sources</goal>
-                    </goals>
-                    <configuration>
-                        <codeGenerators>
-                            <generator>
-                                <codeGeneratorClass>org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator</codeGeneratorClass>
-                                <outputBaseDir>${jmxGeneratorPath}</outputBaseDir>
-                                <additionalConfiguration>
-                                    <namespaceToPackage1>urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang</namespaceToPackage1>
-                                </additionalConfiguration>
-                            </generator>
-                            <generator>
-                                <codeGeneratorClass>org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl</codeGeneratorClass>
-                                <outputBaseDir>${salGeneratorPath}</outputBaseDir>
-                            </generator>
-                        </codeGenerators>
-                        <inspectDependencies>true</inspectDependencies>
-                    </configuration>
-                </execution>
-            </executions>
-            <dependencies>
-                <dependency>
-                    <groupId>org.opendaylight.controller</groupId>
-                    <artifactId>yang-jmx-generator-plugin</artifactId>
-                    <version>${config.version}</version>
-                </dependency>
-            </dependencies>
         </plugin>
     </plugins>
   </build>
index c7298cbf1e4ae42e91976868cc93851c77bf8f7b..00b3124e7f19076b96ddadae22c0599228c75783 100644 (file)
@@ -8,7 +8,7 @@
 
 package org.opendaylight.controller.netconf.mapping.api;
 
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
 import org.w3c.dom.Document;
 
 /**
@@ -33,7 +33,7 @@ public interface NetconfOperation {
      * @param requestMessage
      * @return
      */
-    HandlingPriority canHandle(Document message) throws NetconfDocumentedException;
+    HandlingPriority canHandle(Document message) throws DocumentedException;
 
     /**
      * Execute current netconf operation and trigger execution of subsequent
@@ -46,8 +46,8 @@ public interface NetconfOperation {
      * @param subsequentOperation
      *            execution of subsequent netconf operation
      * @return
-     * @throws NetconfDocumentedException
+     * @throws DocumentedException
      */
     Document handle(Document requestMessage, NetconfOperationChainedExecution subsequentOperation)
-            throws NetconfDocumentedException;
+            throws DocumentedException;
 }
index 4013d623bd4c1dc1e891cd230fcb1b260c0f1ad6..e474422cec317f8dfc390912e1f0ff10843d0b91 100644 (file)
@@ -7,7 +7,7 @@
  */
 package org.opendaylight.controller.netconf.mapping.api;
 
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
 import org.w3c.dom.Document;
 
 /**
@@ -26,7 +26,7 @@ public interface NetconfOperationChainedExecution {
     /**
      * Do not execute if this is termination point
      */
-    Document execute(Document requestMessage) throws NetconfDocumentedException;
+    Document execute(Document requestMessage) throws DocumentedException;
 
     public static final NetconfOperationChainedExecution EXECUTION_TERMINATION_POINT = new NetconfOperationChainedExecution() {
         @Override
@@ -35,7 +35,7 @@ public interface NetconfOperationChainedExecution {
         }
 
         @Override
-        public Document execute(Document requestMessage) throws NetconfDocumentedException {
+        public Document execute(Document requestMessage) throws DocumentedException {
             throw new IllegalStateException("This execution represents the termination point in operation execution and cannot be executed itself");
         }
     };
index 8caa177bfa525dd87ce38a1e914d1920dc1dc1be..c7378178283f92a11c10397dc0e7582d2a99b2a3 100644 (file)
@@ -9,7 +9,7 @@
 package org.opendaylight.controller.netconf.mapping.api;
 
 import java.util.Set;
-import org.opendaylight.controller.netconf.api.Capability;
+import org.opendaylight.controller.config.util.capability.Capability;
 import org.opendaylight.controller.netconf.api.monitoring.CapabilityListener;
 
 /**
@@ -16,24 +16,28 @@ import org.junit.Test;
 
 public class HandlingPriorityTest {
 
-    @Test
-    public void testHandlingPriority() throws Exception {
-
-
-        assertTrue(HandlingPriority.HANDLE_WITH_DEFAULT_PRIORITY.compareTo(HandlingPriority.HANDLE_WITH_DEFAULT_PRIORITY) == 0);
+    @Test public void testHandlingPriority() throws Exception {
+        assertTrue(
+            HandlingPriority.HANDLE_WITH_DEFAULT_PRIORITY.compareTo(HandlingPriority.HANDLE_WITH_DEFAULT_PRIORITY)
+                == 0);
         assertTrue(HandlingPriority.CANNOT_HANDLE.compareTo(HandlingPriority.HANDLE_WITH_DEFAULT_PRIORITY) == -1);
         assertTrue(HandlingPriority.HANDLE_WITH_DEFAULT_PRIORITY.compareTo(HandlingPriority.CANNOT_HANDLE) == 1);
 
-        assertTrue(HandlingPriority.HANDLE_WITH_DEFAULT_PRIORITY.compareTo(HandlingPriority.HANDLE_WITH_MAX_PRIORITY) == -1);
-        assertTrue(HandlingPriority.HANDLE_WITH_MAX_PRIORITY.compareTo(HandlingPriority.HANDLE_WITH_DEFAULT_PRIORITY) == 1);
-        assertTrue(HandlingPriority.getHandlingPriority(Integer.MIN_VALUE).compareTo(HandlingPriority.HANDLE_WITH_DEFAULT_PRIORITY) == 0);
+        assertTrue(
+            HandlingPriority.HANDLE_WITH_DEFAULT_PRIORITY.compareTo(HandlingPriority.HANDLE_WITH_MAX_PRIORITY) == -1);
+        assertTrue(
+            HandlingPriority.HANDLE_WITH_MAX_PRIORITY.compareTo(HandlingPriority.HANDLE_WITH_DEFAULT_PRIORITY) == 1);
+        assertTrue(HandlingPriority.getHandlingPriority(Integer.MIN_VALUE)
+            .compareTo(HandlingPriority.HANDLE_WITH_DEFAULT_PRIORITY) == 0);
 
         HandlingPriority prio = HandlingPriority.getHandlingPriority(10);
         assertTrue(prio.increasePriority(1).compareTo(HandlingPriority.getHandlingPriority(11)) == 0);
 
         assertFalse(HandlingPriority.CANNOT_HANDLE.getPriority().isPresent());
         assertFalse(HandlingPriority.HANDLE_WITH_MAX_PRIORITY.equals(new Object()));
-        assertEquals(HandlingPriority.HANDLE_WITH_MAX_PRIORITY, HandlingPriority.getHandlingPriority(Integer.MAX_VALUE));
-        assertEquals(HandlingPriority.HANDLE_WITH_MAX_PRIORITY.hashCode(), HandlingPriority.getHandlingPriority(Integer.MAX_VALUE).hashCode());
+        assertEquals(HandlingPriority.HANDLE_WITH_MAX_PRIORITY,
+            HandlingPriority.getHandlingPriority(Integer.MAX_VALUE));
+        assertEquals(HandlingPriority.HANDLE_WITH_MAX_PRIORITY.hashCode(),
+            HandlingPriority.getHandlingPriority(Integer.MAX_VALUE).hashCode());
     }
 }
index 6ab3cd4b6e638999ed9fa1787b8b3b8652e09422..baea3a5e09f816fdecb76720ac65816fde4b6fbb 100644 (file)
@@ -8,7 +8,9 @@
 package org.opendaylight.controller.netconf.monitoring;
 
 import java.util.Collections;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.config.util.xml.XmlElement;
+import org.opendaylight.controller.config.util.xml.XmlMappingConstants;
 import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService;
 import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
 import org.opendaylight.controller.netconf.mapping.api.HandlingPriority;
@@ -16,7 +18,6 @@ import org.opendaylight.controller.netconf.mapping.api.NetconfOperationChainedEx
 import org.opendaylight.controller.netconf.monitoring.xml.JaxBSerializer;
 import org.opendaylight.controller.netconf.monitoring.xml.model.NetconfState;
 import org.opendaylight.controller.netconf.util.mapping.AbstractNetconfOperation;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
@@ -33,9 +34,9 @@ public class Get extends AbstractNetconfOperation {
     }
 
     private Element getPlaceholder(final Document innerResult)
-            throws NetconfDocumentedException {
+            throws DocumentedException {
         final XmlElement rootElement = XmlElement.fromDomElementWithExpected(
-                innerResult.getDocumentElement(), XmlNetconfConstants.RPC_REPLY_KEY, XmlNetconfConstants.RFC4741_TARGET_NAMESPACE);
+                innerResult.getDocumentElement(), XmlMappingConstants.RPC_REPLY_KEY, XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
         return rootElement.getOnlyChildElement(XmlNetconfConstants.DATA_KEY).getDomElement();
     }
 
@@ -51,12 +52,12 @@ public class Get extends AbstractNetconfOperation {
 
     @Override
     public Document handle(final Document requestMessage, final NetconfOperationChainedExecution subsequentOperation)
-            throws NetconfDocumentedException {
+            throws DocumentedException {
         if (subsequentOperation.isExecutionTermination()){
-            throw new NetconfDocumentedException(String.format("Subsequent netconf operation expected by %s", this),
-                    NetconfDocumentedException.ErrorType.application,
-                    NetconfDocumentedException.ErrorTag.operation_failed,
-                    NetconfDocumentedException.ErrorSeverity.error);
+            throw new DocumentedException(String.format("Subsequent netconf operation expected by %s", this),
+                    DocumentedException.ErrorType.application,
+                    DocumentedException.ErrorTag.operation_failed,
+                    DocumentedException.ErrorSeverity.error);
         }
 
         try {
@@ -74,16 +75,16 @@ public class Get extends AbstractNetconfOperation {
             final String errorMessage = "Get operation for netconf-state subtree failed";
             LOG.warn(errorMessage, e);
 
-            throw new NetconfDocumentedException(errorMessage, NetconfDocumentedException.ErrorType.application,
-                    NetconfDocumentedException.ErrorTag.operation_failed,
-                    NetconfDocumentedException.ErrorSeverity.error,
-                    Collections.singletonMap(NetconfDocumentedException.ErrorSeverity.error.toString(), e.getMessage()));
+            throw new DocumentedException(errorMessage, DocumentedException.ErrorType.application,
+                    DocumentedException.ErrorTag.operation_failed,
+                    DocumentedException.ErrorSeverity.error,
+                    Collections.singletonMap(DocumentedException.ErrorSeverity.error.toString(), e.getMessage()));
         }
     }
 
     @Override
     protected Element handle(final Document document, final XmlElement message, final NetconfOperationChainedExecution subsequentOperation)
-            throws NetconfDocumentedException {
+            throws DocumentedException {
         throw new UnsupportedOperationException("Never gets called");
     }
 }
index 961c9f57c2e9bc71463a472fde46cfd5f77ec166..e2351060193589222d85653045f762720ddb74fd 100644 (file)
@@ -11,13 +11,12 @@ package org.opendaylight.controller.netconf.monitoring;
 import com.google.common.base.Optional;
 import com.google.common.collect.Maps;
 import java.util.Map;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.config.util.xml.XmlElement;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService;
 import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.util.exception.MissingNameSpaceException;
 import org.opendaylight.controller.netconf.util.mapping.AbstractSingletonNetconfOperation;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
@@ -47,7 +46,7 @@ public class GetSchema extends AbstractSingletonNetconfOperation {
     }
 
     @Override
-    protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement xml) throws NetconfDocumentedException {
+    protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement xml) throws DocumentedException {
         final GetSchemaEntry entry;
 
         entry = new GetSchemaEntry(xml);
@@ -58,10 +57,10 @@ public class GetSchema extends AbstractSingletonNetconfOperation {
         } catch (final IllegalStateException e) {
             final Map<String, String> errorInfo = Maps.newHashMap();
             errorInfo.put(entry.identifier, e.getMessage());
-            LOG.warn("Rpc error: {}", NetconfDocumentedException.ErrorTag.operation_failed, e);
-            throw new NetconfDocumentedException(e.getMessage(), NetconfDocumentedException.ErrorType.application,
-                    NetconfDocumentedException.ErrorTag.operation_failed,
-                    NetconfDocumentedException.ErrorSeverity.error, errorInfo);
+            LOG.warn("Rpc error: {}", DocumentedException.ErrorTag.operation_failed, e);
+            throw new DocumentedException(e.getMessage(), DocumentedException.ErrorType.application,
+                    DocumentedException.ErrorTag.operation_failed,
+                    DocumentedException.ErrorSeverity.error, errorInfo);
         }
 
         final Element getSchemaResult;
@@ -76,16 +75,16 @@ public class GetSchema extends AbstractSingletonNetconfOperation {
         private final String identifier;
         private final Optional<String> version;
 
-        GetSchemaEntry(final XmlElement getSchemaElement) throws NetconfDocumentedException {
+        GetSchemaEntry(final XmlElement getSchemaElement) throws DocumentedException {
             getSchemaElement.checkName(GET_SCHEMA);
             getSchemaElement.checkNamespace(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_YANG_IETF_NETCONF_MONITORING);
 
             XmlElement identifierElement = null;
             try {
                 identifierElement = getSchemaElement.getOnlyChildElementWithSameNamespace(IDENTIFIER);
-            } catch (final MissingNameSpaceException e) {
+            } catch (final DocumentedException e) {
                 LOG.trace("Can't get identifier element as only child element with same namespace due to ",e);
-                throw NetconfDocumentedException.wrap(e);
+                throw DocumentedException.wrap(e);
             }
             identifier = identifierElement.getTextContent();
             final Optional<XmlElement> versionElement = getSchemaElement
index 4e9ecae3f223e0a4bb97203e6a56f1a2dfad0d2e..1a0941085f92d892163a0926f4c85e4835b03084 100644 (file)
@@ -10,7 +10,7 @@ package org.opendaylight.controller.netconf.monitoring.osgi;
 
 import java.util.Collections;
 import java.util.Set;
-import org.opendaylight.controller.netconf.api.Capability;
+import org.opendaylight.controller.config.util.capability.Capability;
 import org.opendaylight.controller.netconf.api.monitoring.CapabilityListener;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactory;
index 7b590b59e972207677c64205b96db87b9349a225..dd25aff33fe57f372c293e382e0b8703f7d86b78 100644 (file)
@@ -18,10 +18,10 @@ import static org.mockito.Mockito.mock;
 import com.google.common.base.Optional;
 import org.junit.Before;
 import org.junit.Test;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.config.util.xml.XmlElement;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.w3c.dom.Document;
 
 public class GetSchemaTest {
@@ -44,7 +44,7 @@ public class GetSchemaTest {
                 "    </get-schema>";
     }
 
-    @Test(expected = NetconfDocumentedException.class)
+    @Test(expected = DocumentedException.class)
     public void testDefaultGetSchema() throws Exception {
         GetSchema schema = new GetSchema(cap);
         doThrow(IllegalStateException.class).when(cap).getSchemaForCapability(anyString(), any(Optional.class));
index 5a744fda14f2f1bc5cac2e2a7aec57bde9817d04..86c9cc62e942ebf5108b2e019517d55b04a2c1ce 100644 (file)
@@ -14,17 +14,18 @@ import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.doThrow;
+
 import java.util.Collections;
 import org.hamcrest.CoreMatchers;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService;
 import org.opendaylight.controller.netconf.mapping.api.HandlingPriority;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperationChainedExecution;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.SchemasBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.SessionsBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.schemas.Schema;
@@ -62,8 +63,8 @@ public class GetTest {
     public void testHandleNoSubsequent() throws Exception {
         try {
             get.handle(null, NetconfOperationChainedExecution.EXECUTION_TERMINATION_POINT);
-        } catch (final NetconfDocumentedException e) {
-            assertNetconfDocumentedEx(e, NetconfDocumentedException.ErrorSeverity.error, NetconfDocumentedException.ErrorTag.operation_failed, NetconfDocumentedException.ErrorType.application);
+        } catch (final DocumentedException e) {
+            assertNetconfDocumentedEx(e, DocumentedException.ErrorSeverity.error, DocumentedException.ErrorTag.operation_failed, DocumentedException.ErrorType.application);
             return;
         }
 
@@ -75,8 +76,8 @@ public class GetTest {
         doReturn(incorrectSubsequentResult).when(subsequentOperation).execute(request);
         try {
             get.handle(request, subsequentOperation);
-        } catch (final NetconfDocumentedException e) {
-            assertNetconfDocumentedEx(e, NetconfDocumentedException.ErrorSeverity.error, NetconfDocumentedException.ErrorTag.invalid_value, NetconfDocumentedException.ErrorType.application);
+        } catch (final DocumentedException e) {
+            assertNetconfDocumentedEx(e, DocumentedException.ErrorSeverity.error, DocumentedException.ErrorTag.invalid_value, DocumentedException.ErrorType.application);
             return;
         }
 
@@ -88,8 +89,8 @@ public class GetTest {
         doThrow(RuntimeException.class).when(subsequentOperation).execute(request);
         try {
             get.handle(request, subsequentOperation);
-        } catch (final NetconfDocumentedException e) {
-            assertNetconfDocumentedEx(e, NetconfDocumentedException.ErrorSeverity.error, NetconfDocumentedException.ErrorTag.operation_failed, NetconfDocumentedException.ErrorType.application);
+        } catch (final DocumentedException e) {
+            assertNetconfDocumentedEx(e, DocumentedException.ErrorSeverity.error, DocumentedException.ErrorTag.operation_failed, DocumentedException.ErrorType.application);
             assertEquals(1, e.getErrorInfo().size());
             return;
         }
@@ -113,7 +114,7 @@ public class GetTest {
 
     }
 
-    private void assertNetconfDocumentedEx(final NetconfDocumentedException e, final NetconfDocumentedException.ErrorSeverity severity, final NetconfDocumentedException.ErrorTag errorTag, final NetconfDocumentedException.ErrorType type) {
+    private void assertNetconfDocumentedEx(final DocumentedException e, final DocumentedException.ErrorSeverity severity, final DocumentedException.ErrorTag errorTag, final DocumentedException.ErrorType type) {
         assertEquals(severity, e.getErrorSeverity());
         assertEquals(errorTag, e.getErrorTag());
         assertEquals(type, e.getErrorType());
index 50a355c227b30dd31713026501b2f63d6da9b6bc..e19febf1a7d4a89a757d26dee7ecfc5ea60036ec 100644 (file)
@@ -17,11 +17,11 @@ import com.google.common.collect.Lists;
 import java.util.Set;
 import org.hamcrest.CoreMatchers;
 import org.junit.Test;
-import org.opendaylight.controller.netconf.api.Capability;
+import org.opendaylight.controller.config.util.capability.Capability;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.netconf.api.monitoring.NetconfManagementSession;
 import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService;
 import org.opendaylight.controller.netconf.monitoring.xml.model.NetconfState;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.DomainName;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Host;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
@@ -49,22 +49,17 @@ public class JaxBSerializerTest {
         final NetconfMonitoringService service = new NetconfMonitoringService() {
 
             @Override
-            public void onSessionUp(final NetconfManagementSession session) {
-
-            }
-
-            @Override
-            public void onSessionDown(final NetconfManagementSession session) {
+            public void onCapabilitiesChanged(Set<Capability> added, Set<Capability> removed) {
 
             }
 
             @Override
-            public void onCapabilitiesAdded(final Set<Capability> addedCaps) {
+            public void onSessionUp(final NetconfManagementSession session) {
 
             }
 
             @Override
-            public void onCapabilitiesRemoved(final Set<Capability> addedCaps) {
+            public void onSessionDown(final NetconfManagementSession session) {
 
             }
 
index c979a1aa047c11cbaaa2c7a8efeee12c26554af7..2ec59270db49c62184f49e91737122c2cad1cef6 100644 (file)
       <groupId>openexi</groupId>
       <artifactId>nagasena-rta</artifactId>
     </dependency>
-    <dependency>
-      <groupId>org.osgi</groupId>
-      <artifactId>org.osgi.core</artifactId>
-    </dependency>
     <dependency>
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-api</artifactId>
         <artifactId>maven-bundle-plugin</artifactId>
         <configuration>
           <instructions>
-            <Export-Package>org.opendaylight.controller.netconf.nettyutil,
-              org.opendaylight.controller.netconf.nettyutil.handler,
-              org.opendaylight.controller.netconf.nettyutil.handler.exi,
-              org.opendaylight.controller.netconf.nettyutil.handler.ssh,
-              org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication,
-              org.opendaylight.controller.netconf.nettyutil.handler.ssh.client</Export-Package>
+            <Export-Package>org.opendaylight.controller.netconf.nettyutil.*</Export-Package>
           </instructions>
         </configuration>
       </plugin>
index a59b1a0d76bcdb01095e7c25e76377cd83ad019a..a4ad1a4e82b1918aeef73a4f60901446e12f4538 100644 (file)
@@ -13,6 +13,7 @@ import io.netty.channel.ChannelHandler;
 import io.netty.handler.codec.ByteToMessageDecoder;
 import io.netty.handler.codec.MessageToByteEncoder;
 import java.io.IOException;
+import org.opendaylight.controller.config.util.xml.XmlElement;
 import org.opendaylight.controller.netconf.api.NetconfExiSession;
 import org.opendaylight.controller.netconf.api.NetconfMessage;
 import org.opendaylight.controller.netconf.api.NetconfSession;
@@ -22,7 +23,6 @@ import org.opendaylight.controller.netconf.nettyutil.handler.NetconfEXICodec;
 import org.opendaylight.controller.netconf.nettyutil.handler.NetconfEXIToMessageDecoder;
 import org.opendaylight.controller.netconf.nettyutil.handler.NetconfMessageToEXIEncoder;
 import org.opendaylight.controller.netconf.nettyutil.handler.exi.EXIParameters;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
 import org.opendaylight.protocol.framework.AbstractProtocolSession;
 import org.openexi.proc.common.EXIOptionsException;
 import org.openexi.sax.TransmogrifierException;
index 10f699f8d52d07957908925dac791e119b1b1a52..69af52d61e0e8eb3b8617b07b8006a6cf0fd9ff3 100644 (file)
@@ -21,11 +21,11 @@ import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.util.Arrays;
 import java.util.List;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
 import org.opendaylight.controller.netconf.api.NetconfMessage;
 import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessage;
 import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
index 5ae9bb4b1ca8dab36a29ef9925ed1e74ea3ec889..07fb789a08a5c1d6170df05c6e0bbf6b339a3e6e 100644 (file)
@@ -15,8 +15,8 @@ import io.netty.channel.ChannelHandlerContext;
 import io.netty.handler.codec.ByteToMessageDecoder;
 import java.io.IOException;
 import java.util.List;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.xml.sax.SAXException;
index 859006877486292258f77409dbbdb3e48d826903..cb07635a1abb958b233c8a474b8d3bb453258241 100644 (file)
@@ -8,7 +8,7 @@
 package org.opendaylight.controller.netconf.nettyutil.handler.exi;
 
 import com.google.common.base.Preconditions;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
+import org.opendaylight.controller.config.util.xml.XmlElement;
 import org.openexi.proc.common.AlignmentType;
 import org.openexi.proc.common.EXIOptions;
 import org.openexi.proc.common.EXIOptionsException;
index 1d301d3d35cc05f63d83c5643d400f3f643e02d7..4cc0461f9ebe478d3063e0e397f7da34b3316a4d 100644 (file)
@@ -10,9 +10,9 @@ package org.opendaylight.controller.netconf.nettyutil.handler.exi;
 
 import com.google.common.collect.Lists;
 import java.util.List;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.netconf.api.NetconfMessage;
 import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.openexi.proc.common.EXIOptions;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
index 5c5b5a21c3f232705b96d93961f11087e8c781e5..34f8619a6925bce016e82a81dfbcd35a36935e27 100644 (file)
@@ -10,6 +10,7 @@ package org.opendaylight.controller.netconf.nettyutil.handler;
 
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
+
 import com.google.common.collect.Lists;
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
@@ -21,8 +22,8 @@ import java.util.List;
 import org.custommonkey.xmlunit.XMLUnit;
 import org.junit.Before;
 import org.junit.Test;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.openexi.proc.common.EXIOptions;
 import org.openexi.proc.common.EXIOptionsException;
 import org.openexi.sax.Transmogrifier;
index 00d95df423f142943a1ebb3ef609b2d7ea108835..375448ee66c4b97af2f21123815226e582047c9c 100644 (file)
@@ -19,10 +19,10 @@ 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.netconf.api.NetconfMessage;
 import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessage;
 import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 
 public class NetconfHelloMessageToXMLEncoderTest {
 
index ac6370685a06f600da72a5e0e362a7010c1d1bd3..43f31e69d702341cc26d0962fef0663e8f761247 100644 (file)
@@ -20,8 +20,8 @@ import io.netty.buffer.Unpooled;
 import java.util.List;
 import org.hamcrest.CoreMatchers;
 import org.junit.Test;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessage;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 
 public class NetconfXMLToHelloMessageDecoderTest {
 
index 70186f39a45b71fcb0c2e472c71862c97ce174c8..5d1f009b301031e4ea1eee7748319341032f1d87 100644 (file)
@@ -14,8 +14,8 @@ import java.util.Arrays;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
+import org.opendaylight.controller.config.util.xml.XmlElement;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.openexi.proc.common.AlignmentType;
 import org.openexi.proc.common.EXIOptions;
 
index 3023a2d30e8e9942b12c4d4e91cd6da4c7e8690c..009093ccba7470654f645de5c7ab42c05b795af5 100644 (file)
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>netconf-api</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>config-manager-facade-xml</artifactId>
+        </dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>ietf-netconf-notifications</artifactId>
             <plugin>
                 <groupId>org.apache.felix</groupId>
                 <artifactId>maven-bundle-plugin</artifactId>
-                <configuration>
-                    <instructions>
-                        <Export-Package>org.opendaylight.controller.netconf.notifications.*</Export-Package>
-                    </instructions>
-                </configuration>
             </plugin>
         </plugins>
     </build>
index 899ab85e92ef46e5964915921c32596630765ffe..577aee39fb1a2f1e6f55e19ab1b8ce141a61e189 100644 (file)
@@ -21,7 +21,7 @@ public interface BaseNetconfNotificationListener {
     /**
      * Callback used to notify about a change in used capabilities
      */
-    void onCapabilityChanged(NetconfCapabilityChange capabilityChange);
+    void onCapabilityChanged(final NetconfCapabilityChange capabilityChange);
 
     // TODO add other base notifications
 
index 2663a5db5ffb63604525517e24c5244156300ca8..9d3d5bab026b07b7633be2d27b925306e036e889 100644 (file)
@@ -14,7 +14,7 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.r
 /**
  * Collector of all notifications. Base or generic
  */
-public interface NetconfNotificationCollector  {
+public interface NetconfNotificationCollector {
 
     /**
      * Add notification publisher for a particular stream
index 64255edc81f2770c88ba8ae979e5a5f4c336b1ab..31f52918ba493d7a2aced7190d193d318f4e57ed 100644 (file)
@@ -58,6 +58,7 @@
                 <configuration>
                     <instructions>
                         <Bundle-Activator>org.opendaylight.controller.netconf.notifications.impl.osgi.Activator</Bundle-Activator>
+                        <Export-Package>org.opendaylight.controller.netconf.notifications.impl.*</Export-Package>
                     </instructions>
                 </configuration>
             </plugin>
index d2dbcaf4162f76b5802b509dd8bdf2ea2a06770e..2bddb096901b52953059dbb25a363c61c1229fd5 100644 (file)
@@ -77,7 +77,7 @@ public class NetconfNotificationManager implements NetconfNotificationCollector,
     @Override
     public synchronized void onNotification(final StreamNameType stream, final NetconfNotification notification) {
         LOG.debug("Notification of type {} detected", stream);
-        if(LOG.isTraceEnabled()) {
+        if (LOG.isTraceEnabled()) {
             LOG.debug("Notification of type {} detected: {}", stream, notification);
         }
 
@@ -129,7 +129,7 @@ public class NetconfNotificationManager implements NetconfNotificationCollector,
         return new NotificationRegistration() {
             @Override
             public void close() {
-                synchronized(NetconfNotificationManager.this) {
+                synchronized (NetconfNotificationManager.this) {
                     streamListeners.remove(listener);
                 }
             }
@@ -160,11 +160,11 @@ public class NetconfNotificationManager implements NetconfNotificationCollector,
         final StreamNameType streamName = stream.getName();
 
         LOG.debug("Notification publisher registered for stream: {}", streamName);
-        if(LOG.isTraceEnabled()) {
+        if (LOG.isTraceEnabled()) {
             LOG.trace("Notification publisher registered for stream: {}", stream);
         }
 
-        if(streamMetadata.containsKey(streamName)) {
+        if (streamMetadata.containsKey(streamName)) {
             LOG.warn("Notification stream {} already registered as: {}. Will be reused", streamName, streamMetadata.get(streamName));
         } else {
             streamMetadata.put(streamName, stream);
@@ -206,6 +206,7 @@ public class NetconfNotificationManager implements NetconfNotificationCollector,
             streamListener.onStreamRegistered(stream);
         }
     }
+
     private synchronized void notifyStreamRemoved(final StreamNameType stream) {
         for (final NetconfNotificationStreamListener streamListener : streamListeners) {
             streamListener.onStreamUnregistered(stream);
@@ -254,13 +255,14 @@ public class NetconfNotificationManager implements NetconfNotificationCollector,
             baseRegistration.close();
         }
 
+        private static NetconfNotification serializeNotification(final NetconfCapabilityChange capabilityChange) {
+            return NotificationsTransformUtil.transform(capabilityChange);
+        }
+
         @Override
         public void onCapabilityChanged(final NetconfCapabilityChange capabilityChange) {
             baseRegistration.onNotification(BASE_STREAM_NAME, serializeNotification(capabilityChange));
-        }
-
-        private static NetconfNotification serializeNotification(final NetconfCapabilityChange capabilityChange) {
-            return NotificationsTransformUtil.transform(capabilityChange);
+//            baseRegistration.onNotification(BASE_STREAM_NAME, serializeNotification(computeDiff(removed, added)));
         }
     }
 
index 0d6b4248f6a9a1ea741c0456e35828e2f15b0ffd..bdd1c3a6a72a2cebd1cba700b1936826667f085b 100644 (file)
@@ -12,7 +12,9 @@ import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.Lists;
 import java.util.List;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.config.util.xml.XmlElement;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.netconf.api.NetconfSession;
 import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
 import org.opendaylight.controller.netconf.mapping.api.SessionAwareNetconfOperation;
@@ -22,8 +24,6 @@ import org.opendaylight.controller.netconf.notifications.NetconfNotificationRegi
 import org.opendaylight.controller.netconf.notifications.NotificationListenerRegistration;
 import org.opendaylight.controller.netconf.notifications.impl.NetconfNotificationManager;
 import org.opendaylight.controller.netconf.util.mapping.AbstractLastNetconfOperation;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.CreateSubscriptionInput;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.StreamNameType;
 import org.slf4j.Logger;
@@ -51,7 +51,7 @@ public class CreateSubscription extends AbstractLastNetconfOperation implements
     }
 
     @Override
-    protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement operationElement) throws NetconfDocumentedException {
+    protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement operationElement) throws DocumentedException {
         operationElement.checkName(CREATE_SUBSCRIPTION);
         operationElement.checkNamespace(CreateSubscriptionInput.QNAME.getNamespace().toString());
         // FIXME reimplement using CODEC_REGISTRY and parse everything into generated class instance
@@ -84,7 +84,7 @@ public class CreateSubscription extends AbstractLastNetconfOperation implements
         return XmlUtil.createElement(document, XmlNetconfConstants.OK, Optional.<String>absent());
     }
 
-    private static StreamNameType parseStreamIfPresent(final XmlElement operationElement) throws NetconfDocumentedException {
+    private static StreamNameType parseStreamIfPresent(final XmlElement operationElement) throws DocumentedException {
         final Optional<XmlElement> stream = operationElement.getOnlyChildElementWithSameNamespaceOptionally("stream");
         return stream.isPresent() ? new StreamNameType(stream.get().getTextContent()) : NetconfNotificationManager.BASE_STREAM_NAME;
     }
index 85f29360c5f7261799f9b8574c3e265ee39b4f70..93848c5b0fb6efb20515f08a0d441ca7fa86d3cf 100644 (file)
@@ -12,13 +12,14 @@ import com.google.common.base.Preconditions;
 import java.io.IOException;
 import javax.xml.stream.XMLStreamException;
 import javax.xml.transform.dom.DOMResult;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.config.util.xml.XmlElement;
+import org.opendaylight.controller.config.util.xml.XmlMappingConstants;
 import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
 import org.opendaylight.controller.netconf.mapping.api.HandlingPriority;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperationChainedExecution;
 import org.opendaylight.controller.netconf.notifications.NetconfNotificationRegistry;
 import org.opendaylight.controller.netconf.util.mapping.AbstractNetconfOperation;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.Netconf;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.NetconfBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.Streams;
@@ -51,7 +52,7 @@ public class Get extends AbstractNetconfOperation implements AutoCloseable {
     }
 
     @Override
-    public Document handle(final Document requestMessage, final NetconfOperationChainedExecution subsequentOperation) throws NetconfDocumentedException {
+    public Document handle(final Document requestMessage, final NetconfOperationChainedExecution subsequentOperation) throws DocumentedException {
         final Document partialResponse = subsequentOperation.execute(requestMessage);
         final Streams availableStreams = notificationRegistry.getNotificationPublishers();
         if(availableStreams.getStream().isEmpty() == false) {
@@ -60,7 +61,7 @@ public class Get extends AbstractNetconfOperation implements AutoCloseable {
         return partialResponse;
     }
 
-    static void serializeStreamsSubtree(final Document partialResponse, final Streams availableStreams) throws NetconfDocumentedException {
+    static void serializeStreamsSubtree(final Document partialResponse, final Streams availableStreams) throws DocumentedException {
         final Netconf netconfSubtree = new NetconfBuilder().setStreams(availableStreams).build();
         final NormalizedNode<?, ?> normalized = toNormalized(netconfSubtree);
 
@@ -74,9 +75,9 @@ public class Get extends AbstractNetconfOperation implements AutoCloseable {
     }
 
     private static Element getPlaceholder(final Document innerResult)
-            throws NetconfDocumentedException {
+            throws DocumentedException {
         final XmlElement rootElement = XmlElement.fromDomElementWithExpected(
-                innerResult.getDocumentElement(), XmlNetconfConstants.RPC_REPLY_KEY, XmlNetconfConstants.RFC4741_TARGET_NAMESPACE);
+                innerResult.getDocumentElement(), XmlMappingConstants.RPC_REPLY_KEY, XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
         return rootElement.getOnlyChildElement(XmlNetconfConstants.DATA_KEY).getDomElement();
     }
 
@@ -86,7 +87,7 @@ public class Get extends AbstractNetconfOperation implements AutoCloseable {
 
     @Override
     protected Element handle(final Document document, final XmlElement message, final NetconfOperationChainedExecution subsequentOperation)
-            throws NetconfDocumentedException {
+            throws DocumentedException {
         throw new UnsupportedOperationException("Never gets called");
     }
 
index 080176dcd4cd015623dde34509e34f40d2eb45f4..131d3496bc55d206c1d0330e9b39447ba726414f 100644 (file)
@@ -21,8 +21,8 @@ import javax.xml.stream.XMLOutputFactory;
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamWriter;
 import javax.xml.transform.dom.DOMResult;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.netconf.notifications.NetconfNotification;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.$YangModuleInfoImpl;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfCapabilityChange;
 import org.opendaylight.yangtools.binding.data.codec.gen.impl.StreamWriterGenerator;
index 64442f743d576a55f39146ed80570443c450b51b..bd2d5d6b7985bf4724e0f8da453cedb51867ac2e 100644 (file)
@@ -13,7 +13,8 @@ import java.util.Collections;
 import java.util.Dictionary;
 import java.util.Hashtable;
 import java.util.Set;
-import org.opendaylight.controller.netconf.api.Capability;
+import org.opendaylight.controller.config.util.capability.BasicCapability;
+import org.opendaylight.controller.config.util.capability.Capability;
 import org.opendaylight.controller.netconf.api.monitoring.CapabilityListener;
 import org.opendaylight.controller.netconf.api.util.NetconfConstants;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperation;
@@ -24,13 +25,16 @@ import org.opendaylight.controller.netconf.notifications.NetconfNotificationColl
 import org.opendaylight.controller.netconf.notifications.impl.NetconfNotificationManager;
 import org.opendaylight.controller.netconf.notifications.impl.ops.CreateSubscription;
 import org.opendaylight.controller.netconf.notifications.impl.ops.Get;
-import org.opendaylight.controller.netconf.util.capability.BasicCapability;
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceRegistration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class Activator implements BundleActivator {
 
+    private static final Logger LOG = LoggerFactory.getLogger(Activator.class);
+
     private ServiceRegistration<NetconfNotificationCollector> netconfNotificationCollectorServiceRegistration;
     private ServiceRegistration<NetconfOperationServiceFactory> operationaServiceRegistration;
     private NetconfNotificationManager netconfNotificationManager;
@@ -51,11 +55,11 @@ public class Activator implements BundleActivator {
 
             @Override
             public AutoCloseable registerCapabilityListener(final CapabilityListener listener) {
-                listener.onCapabilitiesAdded(capabilities);
+                listener.onCapabilitiesChanged(capabilities, Collections.<Capability>emptySet());
                 return new AutoCloseable() {
                     @Override
                     public void close() {
-                        listener.onCapabilitiesRemoved(capabilities);
+                        listener.onCapabilitiesChanged(Collections.<Capability>emptySet(), capabilities);
                     }
                 };
             }
@@ -66,7 +70,6 @@ public class Activator implements BundleActivator {
 
                     private final CreateSubscription createSubscription = new CreateSubscription(netconfSessionIdForReporting, netconfNotificationManager);
 
-
                     @Override
                     public Set<NetconfOperation> getNetconfOperations() {
                         return Sets.<NetconfOperation>newHashSet(
@@ -85,7 +88,6 @@ public class Activator implements BundleActivator {
         final Dictionary<String, String> properties = new Hashtable<>();
         properties.put(NetconfConstants.SERVICE_NAME, NetconfConstants.NETCONF_MONITORING);
         operationaServiceRegistration = context.registerService(NetconfOperationServiceFactory.class, netconfOperationServiceFactory, properties);
-
     }
 
     @Override
index aca8f2de91764e491fd32799bb1d995235f8637d..1711a5bba174f2d9622f1a4f7cf9ef34f53572f8 100644 (file)
@@ -18,12 +18,12 @@ import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
+import org.opendaylight.controller.config.util.xml.XmlElement;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.netconf.api.NetconfSession;
 import org.opendaylight.controller.netconf.notifications.NetconfNotificationListener;
 import org.opendaylight.controller.netconf.notifications.NetconfNotificationRegistry;
 import org.opendaylight.controller.netconf.notifications.NotificationListenerRegistration;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.StreamNameType;
 import org.w3c.dom.Element;
 
index ac826a5e4454650c9d58dc9503b5ae013736f394..3fe5e5c7e5ac6c521902a1c9257444b41d9c5e4a 100644 (file)
@@ -11,7 +11,7 @@ package org.opendaylight.controller.netconf.notifications.impl.ops;
 import com.google.common.collect.Lists;
 import java.io.IOException;
 import org.junit.Test;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.StreamNameType;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.Streams;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.StreamsBuilder;
index 7bb213ab46942578e4fdce191a5c7a3eb0436d79..ec1fe55c5c5e7a934c373593493d9b5638ac4f10 100644 (file)
@@ -19,8 +19,8 @@ import org.custommonkey.xmlunit.Diff;
 import org.custommonkey.xmlunit.XMLUnit;
 import org.custommonkey.xmlunit.examples.RecursiveElementNameAndTextQualifier;
 import org.junit.Test;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.netconf.notifications.NetconfNotification;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfCapabilityChange;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfCapabilityChangeBuilder;
index 5412ff80b5756682d69dc607fcce479ff708a9e4..3094362fe9124ef42045efe4b92c477e0fa3024b 100644 (file)
         <plugin>
             <groupId>org.opendaylight.yangtools</groupId>
             <artifactId>yang-maven-plugin</artifactId>
-            <executions>
-                <execution>
-                    <id>config</id>
-                    <goals>
-                        <goal>generate-sources</goal>
-                    </goals>
-                    <configuration>
-                        <codeGenerators>
-                            <generator>
-                                <codeGeneratorClass>org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator</codeGeneratorClass>
-                                <outputBaseDir>${jmxGeneratorPath}</outputBaseDir>
-                                <additionalConfiguration>
-                                    <namespaceToPackage1>urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang</namespaceToPackage1>
-                                </additionalConfiguration>
-                            </generator>
-                            <generator>
-                                <codeGeneratorClass>org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl</codeGeneratorClass>
-                                <outputBaseDir>${salGeneratorPath}</outputBaseDir>
-                            </generator>
-                        </codeGenerators>
-                        <inspectDependencies>true</inspectDependencies>
-                    </configuration>
-                </execution>
-            </executions>
-            <dependencies>
-                <dependency>
-                    <groupId>org.opendaylight.controller</groupId>
-                    <artifactId>yang-jmx-generator-plugin</artifactId>
-                    <version>${config.version}</version>
-                </dependency>
-            </dependencies>
         </plugin>
     </plugins>
   </build>
index e1e650b4da3c8ff06f98ac8747b89865814ef1d2..bc6b1bc459c4a1ca7a9a74ab36dc96dc7be6b4cb 100644 (file)
         <plugin>
             <groupId>org.opendaylight.yangtools</groupId>
             <artifactId>yang-maven-plugin</artifactId>
-            <executions>
-                <execution>
-                    <id>config</id>
-                    <goals>
-                        <goal>generate-sources</goal>
-                    </goals>
-                    <configuration>
-                        <codeGenerators>
-                            <generator>
-                                <codeGeneratorClass>org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator</codeGeneratorClass>
-                                <outputBaseDir>${jmxGeneratorPath}</outputBaseDir>
-                                <additionalConfiguration>
-                                    <namespaceToPackage1>urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang</namespaceToPackage1>
-                                </additionalConfiguration>
-                            </generator>
-                            <generator>
-                                <codeGeneratorClass>org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl</codeGeneratorClass>
-                                <outputBaseDir>${salGeneratorPath}</outputBaseDir>
-                            </generator>
-                        </codeGenerators>
-                        <inspectDependencies>true</inspectDependencies>
-                    </configuration>
-                </execution>
-            </executions>
-            <dependencies>
-                <dependency>
-                    <groupId>org.opendaylight.controller</groupId>
-                    <artifactId>yang-jmx-generator-plugin</artifactId>
-                    <version>${config.version}</version>
-                </dependency>
-            </dependencies>
         </plugin>
     </plugins>
   </build>
index b629e2861807a792057ff6b29b01dbce632a59fc..5097570b12a0a15de7425be29d67ed6eff84e4cb 100644 (file)
 
   <dependencies>
     <!-- compile dependencies -->
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>config-manager-facade-xml</artifactId>
+      <version>0.4.0-SNAPSHOT</version>
+    </dependency>
     <dependency>
       <groupId>${project.groupId}</groupId>
       <artifactId>netconf-api</artifactId>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>config-api</artifactId>
     </dependency>
-    <dependency>
-      <groupId>org.osgi</groupId>
-      <artifactId>org.osgi.core</artifactId>
-    </dependency>
     <dependency>
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-api</artifactId>
index 5fd53dce55639e0b5c8a811e11ab4b7b2a637117..40b894fc75d0331d64e0ca55d0134d45e4bebf15 100644 (file)
@@ -8,10 +8,11 @@
 package org.opendaylight.controller.netconf.util;
 
 import com.google.common.base.Preconditions;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.config.util.xml.XmlElement;
+import org.opendaylight.controller.config.util.xml.XmlMappingConstants;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
@@ -22,9 +23,9 @@ public final class NetconfUtil {
 
     private NetconfUtil() {}
 
-    public static Document checkIsMessageOk(Document response) throws NetconfDocumentedException {
+    public static Document checkIsMessageOk(Document response) throws DocumentedException {
         XmlElement element = XmlElement.fromDomDocument(response);
-        Preconditions.checkState(element.getName().equals(XmlNetconfConstants.RPC_REPLY_KEY));
+        Preconditions.checkState(element.getName().equals(XmlMappingConstants.RPC_REPLY_KEY));
         element = element.getOnlyChildElement();
         if (element.getName().equals(XmlNetconfConstants.OK)) {
             return response;
diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/capability/BasicCapability.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/capability/BasicCapability.java
deleted file mode 100644 (file)
index 999f83c..0000000
+++ /dev/null
@@ -1,61 +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.netconf.util.capability;
-
-import com.google.common.base.Optional;
-import java.util.Collection;
-import java.util.Collections;
-import org.opendaylight.controller.netconf.api.Capability;
-
-/**
- * Capability representing a basic, one-line, string based capability
- */
-public class BasicCapability implements Capability {
-
-    private final String capability;
-
-    public BasicCapability(final String capability) {
-        this.capability = capability;
-    }
-
-    @Override
-    public String getCapabilityUri() {
-        return capability;
-    }
-
-    @Override
-    public Optional<String> getModuleNamespace() {
-        return Optional.absent();
-    }
-
-    @Override
-    public Optional<String> getModuleName() {
-        return Optional.absent();
-    }
-
-    @Override
-    public Optional<String> getRevision() {
-        return Optional.absent();
-    }
-
-    @Override
-    public Optional<String> getCapabilitySchema() {
-        return Optional.absent();
-    }
-
-    @Override
-    public Collection<String> getLocation() {
-        return Collections.emptyList();
-    }
-
-    @Override
-    public String toString() {
-        return capability;
-    }
-}
diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/capability/YangModuleCapability.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/capability/YangModuleCapability.java
deleted file mode 100644 (file)
index e41affd..0000000
+++ /dev/null
@@ -1,57 +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.netconf.util.capability;
-
-import com.google.common.base.Optional;
-import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil;
-import org.opendaylight.yangtools.yang.model.api.Module;
-
-/**
- * Yang model representing capability.
- */
-public final class YangModuleCapability extends BasicCapability {
-
-    private final String content;
-    private final String revision;
-    private final String moduleName;
-    private final String moduleNamespace;
-
-    public YangModuleCapability(final Module module, final String moduleContent) {
-        super(toCapabilityURI(module));
-        this.content = moduleContent;
-        this.moduleName = module.getName();
-        this.moduleNamespace = module.getNamespace().toString();
-        this.revision = SimpleDateFormatUtil.getRevisionFormat().format(module.getRevision());
-    }
-
-    @Override
-    public Optional<String> getCapabilitySchema() {
-        return Optional.of(content);
-    }
-
-    private static String toCapabilityURI(final Module module) {
-        return String.valueOf(module.getNamespace()) + "?module="
-                + module.getName() + "&revision=" + SimpleDateFormatUtil.getRevisionFormat().format(module.getRevision());
-    }
-
-    @Override
-    public Optional<String> getModuleName() {
-        return Optional.of(moduleName);
-    }
-
-    @Override
-    public Optional<String> getModuleNamespace() {
-        return Optional.of(moduleNamespace);
-    }
-
-    @Override
-    public Optional<String> getRevision() {
-        return Optional.of(revision);
-    }
-}
diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/exception/MissingNameSpaceException.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/exception/MissingNameSpaceException.java
deleted file mode 100644 (file)
index d2a6d2b..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.util.exception;
-
-import java.util.Collections;
-import java.util.Map;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-
-public class MissingNameSpaceException extends NetconfDocumentedException {
-    private static final long serialVersionUID = 1L;
-
-    public MissingNameSpaceException(final String message, final ErrorType errorType, final ErrorTag errorTag,
-                                     final ErrorSeverity errorSeverity) {
-        this(message, errorType, errorTag, errorSeverity, Collections.<String, String> emptyMap());
-    }
-
-    public MissingNameSpaceException(final String message, final ErrorType errorType, final ErrorTag errorTag,
-                                     final ErrorSeverity errorSeverity, final Map<String, String> errorInfo){
-        super(message,errorType,errorTag,errorSeverity,errorInfo);
-    }
-}
diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/exception/UnexpectedElementException.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/exception/UnexpectedElementException.java
deleted file mode 100644 (file)
index 6d7c7ca..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.util.exception;
-
-import java.util.Collections;
-import java.util.Map;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-
-public class UnexpectedElementException extends NetconfDocumentedException {
-    private static final long serialVersionUID = 1L;
-
-    public UnexpectedElementException(final String message, final ErrorType errorType, final ErrorTag errorTag,
-                                      final ErrorSeverity errorSeverity) {
-        this(message, errorType, errorTag, errorSeverity, Collections.<String, String> emptyMap());
-    }
-
-    public UnexpectedElementException(final String message, final ErrorType errorType, final ErrorTag errorTag,
-                                      final ErrorSeverity errorSeverity, final Map<String, String> errorInfo) {
-        super(message,errorType,errorTag,errorSeverity,errorInfo);
-    }
-}
diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/exception/UnexpectedNamespaceException.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/exception/UnexpectedNamespaceException.java
deleted file mode 100644 (file)
index 4a19390..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.util.exception;
-
-import java.util.Collections;
-import java.util.Map;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-
-public class UnexpectedNamespaceException extends NetconfDocumentedException {
-    private static final long serialVersionUID = 1L;
-
-    public UnexpectedNamespaceException(final String message, final ErrorType errorType, final ErrorTag errorTag,
-                                          final ErrorSeverity errorSeverity) {
-        this(message, errorType, errorTag, errorSeverity, Collections.<String, String> emptyMap());
-    }
-
-    public UnexpectedNamespaceException(final String message, final ErrorType errorType, final ErrorTag errorTag,
-                                          final ErrorSeverity errorSeverity, final Map<String, String> errorInfo){
-        super(message,errorType,errorTag,errorSeverity,errorInfo);
-    }
-}
index c40bf3909a029e275467ce7c987fa6fe05063e2c..96553a4defb6d221acd38837b28129ec271950fa 100644 (file)
@@ -7,10 +7,10 @@
  */
 package org.opendaylight.controller.netconf.util.mapping;
 
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.config.util.xml.XmlElement;
 import org.opendaylight.controller.netconf.mapping.api.HandlingPriority;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperationChainedExecution;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
@@ -22,12 +22,12 @@ public abstract class AbstractLastNetconfOperation extends AbstractNetconfOperat
 
     @Override
     protected Element handle(Document document, XmlElement operationElement,
-            NetconfOperationChainedExecution subsequentOperation) throws NetconfDocumentedException {
+            NetconfOperationChainedExecution subsequentOperation) throws DocumentedException {
         if (!subsequentOperation.isExecutionTermination()){
-            throw new NetconfDocumentedException(String.format("No netconf operation expected to be subsequent to %s, but is %s", this, subsequentOperation),
-                    NetconfDocumentedException.ErrorType.application,
-                    NetconfDocumentedException.ErrorTag.malformed_message,
-                    NetconfDocumentedException.ErrorSeverity.error);
+            throw new DocumentedException(String.format("No netconf operation expected to be subsequent to %s, but is %s", this, subsequentOperation),
+                    DocumentedException.ErrorType.application,
+                    DocumentedException.ErrorTag.malformed_message,
+                    DocumentedException.ErrorSeverity.error);
         }
 
         return handleWithNoSubsequentOperations(document, operationElement);
@@ -38,5 +38,5 @@ public abstract class AbstractLastNetconfOperation extends AbstractNetconfOperat
         return HandlingPriority.HANDLE_WITH_DEFAULT_PRIORITY;
     }
 
-    protected abstract Element handleWithNoSubsequentOperations(Document document, XmlElement operationElement) throws NetconfDocumentedException;
+    protected abstract Element handleWithNoSubsequentOperations(Document document, XmlElement operationElement) throws DocumentedException;
 }
index b7ebc51b70712a5ebabc322018c5707636113d13..707274ed4a1522235c2004c5adca7c4bf9d4e731 100644 (file)
@@ -10,13 +10,14 @@ package org.opendaylight.controller.netconf.util.mapping;
 
 import com.google.common.base.Optional;
 import java.util.Map;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.config.util.xml.XmlElement;
+import org.opendaylight.controller.config.util.xml.XmlMappingConstants;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
 import org.opendaylight.controller.netconf.mapping.api.HandlingPriority;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperation;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperationChainedExecution;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.w3c.dom.Attr;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
@@ -34,7 +35,7 @@ public abstract class AbstractNetconfOperation implements NetconfOperation {
     }
 
     @Override
-    public HandlingPriority canHandle(final Document message) throws NetconfDocumentedException {
+    public HandlingPriority canHandle(final Document message) throws DocumentedException {
         OperationNameAndNamespace operationNameAndNamespace = null;
         operationNameAndNamespace = new OperationNameAndNamespace(message);
         return canHandle(operationNameAndNamespace.getOperationName(), operationNameAndNamespace.getNamespace());
@@ -44,7 +45,7 @@ public abstract class AbstractNetconfOperation implements NetconfOperation {
         private final String operationName, namespace;
         private final XmlElement operationElement;
 
-        public OperationNameAndNamespace(final Document message) throws NetconfDocumentedException {
+        public OperationNameAndNamespace(final Document message) throws DocumentedException {
             XmlElement requestElement = null;
             requestElement = getRequestElementWithCheck(message);
             operationElement = requestElement.getOnlyChildElement();
@@ -65,7 +66,7 @@ public abstract class AbstractNetconfOperation implements NetconfOperation {
         }
     }
 
-    protected static XmlElement getRequestElementWithCheck(final Document message) throws NetconfDocumentedException {
+    protected static XmlElement getRequestElementWithCheck(final Document message) throws DocumentedException {
         return XmlElement.fromDomElementWithExpected(message.getDocumentElement(), XmlNetconfConstants.RPC_KEY,
                 XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
     }
@@ -88,7 +89,7 @@ public abstract class AbstractNetconfOperation implements NetconfOperation {
 
     @Override
     public Document handle(final Document requestMessage,
-            final NetconfOperationChainedExecution subsequentOperation) throws NetconfDocumentedException {
+            final NetconfOperationChainedExecution subsequentOperation) throws DocumentedException {
 
         XmlElement requestElement = getRequestElementWithCheck(requestMessage);
 
@@ -98,7 +99,7 @@ public abstract class AbstractNetconfOperation implements NetconfOperation {
         Map<String, Attr> attributes = requestElement.getAttributes();
 
         Element response = handle(document, operationElement, subsequentOperation);
-        Element rpcReply = XmlUtil.createElement(document, XmlNetconfConstants.RPC_REPLY_KEY, Optional.of(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0));
+        Element rpcReply = XmlUtil.createElement(document, XmlMappingConstants.RPC_REPLY_KEY, Optional.of(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0));
 
         if(XmlElement.fromDomElement(response).hasNamespace()) {
             rpcReply.appendChild(response);
@@ -119,7 +120,7 @@ public abstract class AbstractNetconfOperation implements NetconfOperation {
     }
 
     protected abstract Element handle(Document document, XmlElement message, NetconfOperationChainedExecution subsequentOperation)
-            throws NetconfDocumentedException;
+            throws DocumentedException;
 
     @Override
     public String toString() {
index 3e64e93ed74875b71738beca56db8d224b10dead..307a7d7288d8329a484ed87a089a6d73d714effd 100644 (file)
@@ -7,10 +7,10 @@
  */
 package org.opendaylight.controller.netconf.util.mapping;
 
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.config.util.xml.XmlElement;
 import org.opendaylight.controller.netconf.mapping.api.HandlingPriority;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperationChainedExecution;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
@@ -22,7 +22,7 @@ public abstract class AbstractSingletonNetconfOperation extends AbstractLastNetc
 
     @Override
     protected Element handle(Document document, XmlElement operationElement,
-                             NetconfOperationChainedExecution subsequentOperation) throws NetconfDocumentedException {
+                             NetconfOperationChainedExecution subsequentOperation) throws DocumentedException {
         return handleWithNoSubsequentOperations(document, operationElement);
     }
 
index 404885db7e9a497a243abd12d468df7c48f8b6ae..75f74d078feb673637ded1cf474be787ff5ac748 100644 (file)
@@ -12,12 +12,12 @@ import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.Sets;
 import java.util.Set;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.config.util.xml.XmlElement;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
 import org.opendaylight.controller.netconf.api.NetconfMessage;
 import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.util.exception.MissingNameSpaceException;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
@@ -97,7 +97,7 @@ public final class NetconfHelloMessage extends NetconfMessage {
             // accept even if hello has no namespace
             return element.getName().equals(HELLO_TAG) &&
                     (!element.hasNamespace() || element.getNamespace().equals(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0));
-        } catch (MissingNameSpaceException e) {
+        } catch (DocumentedException e) {
             // Cannot happen, since we check for hasNamespace
             throw new IllegalStateException(e);
         }
index 3c6b6ccab9efa0a0a28b5630da5d5c9f30157610..354d74016d48f170321bfca9e9d5886a5a03b851 100644 (file)
@@ -14,10 +14,11 @@ import com.google.common.collect.Collections2;
 import java.util.Collection;
 import java.util.List;
 import javax.annotation.Nonnull;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.config.util.xml.XmlElement;
 import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
 import org.opendaylight.controller.netconf.api.NetconfMessage;
 import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
@@ -40,7 +41,11 @@ public final class NetconfMessageUtil {
         if(xmlElement.getChildElements().size() != 1) {
             return false;
         }
-        return xmlElement.getOnlyChildElement().getName().equals(XmlNetconfConstants.OK);
+        try {
+            return xmlElement.getOnlyChildElement().getName().equals(XmlNetconfConstants.OK);
+        } catch (DocumentedException e) {
+            throw new NetconfDocumentedException(e);
+        }
     }
 
     public static boolean isErrorMessage(NetconfMessage message) throws NetconfDocumentedException {
@@ -55,7 +60,11 @@ public final class NetconfMessageUtil {
         if(xmlElement.getChildElements().size() != 1) {
             return false;
         }
-        return xmlElement.getOnlyChildElement().getName().equals(XmlNetconfConstants.RPC_ERROR);
+        try {
+            return xmlElement.getOnlyChildElement().getName().equals(DocumentedException.RPC_ERROR);
+        } catch (DocumentedException e) {
+            throw new NetconfDocumentedException(e);
+        }
     }
 
     public static Collection<String> extractCapabilitiesFromHello(Document doc) throws NetconfDocumentedException {
@@ -74,7 +83,7 @@ public final class NetconfMessageUtil {
                 // Trim possible leading/tailing whitespace
                 try {
                     return input.getTextContent().trim();
-                } catch (NetconfDocumentedException e) {
+                } catch (DocumentedException e) {
                     LOG.trace("Error fetching input text content",e);
                     return null;
                 }
index 490eb95b82be8a4c9d092c4f721fadf18059d7bd..a187d546514a3bfb2e5abba9af1776ddcacde0c5 100644 (file)
@@ -12,11 +12,12 @@ import com.google.common.base.Preconditions;
 import io.netty.channel.Channel;
 import io.netty.channel.ChannelFuture;
 import io.netty.channel.ChannelFutureListener;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.config.util.xml.XmlMappingConstants;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.netconf.api.NetconfMessage;
 import org.opendaylight.controller.netconf.api.NetconfSession;
 import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Attr;
@@ -30,21 +31,21 @@ public final class SendErrorExceptionUtil {
     private SendErrorExceptionUtil() {}
 
     public static void sendErrorMessage(final NetconfSession session,
-            final NetconfDocumentedException sendErrorException) {
+            final DocumentedException sendErrorException) {
         LOG.trace("Sending error {}", sendErrorException.getMessage(), sendErrorException);
         final Document errorDocument = createDocument(sendErrorException);
         ChannelFuture f = session.sendMessage(new NetconfMessage(errorDocument));
         f.addListener(new SendErrorVerifyingListener(sendErrorException));
     }
 
-    public static void sendErrorMessage(final Channel channel, final NetconfDocumentedException sendErrorException) {
+    public static void sendErrorMessage(final Channel channel, final DocumentedException sendErrorException) {
         LOG.trace("Sending error {}", sendErrorException.getMessage(), sendErrorException);
         final Document errorDocument = createDocument(sendErrorException);
         ChannelFuture f = channel.writeAndFlush(new NetconfMessage(errorDocument));
         f.addListener(new SendErrorVerifyingListener(sendErrorException));
     }
 
-    public static void sendErrorMessage(final NetconfSession session, final NetconfDocumentedException sendErrorException,
+    public static void sendErrorMessage(final NetconfSession session, final DocumentedException sendErrorException,
             final NetconfMessage incommingMessage) {
         final Document errorDocument = createDocument(sendErrorException);
         if (LOG.isTraceEnabled()) {
@@ -57,15 +58,15 @@ public final class SendErrorExceptionUtil {
     }
 
     private static void tryToCopyAttributes(final Document incommingDocument, final Document errorDocument,
-            final NetconfDocumentedException sendErrorException) {
+            final DocumentedException sendErrorException) {
         try {
             final Element incommingRpc = incommingDocument.getDocumentElement();
             Preconditions.checkState(incommingRpc.getTagName().equals(XmlNetconfConstants.RPC_KEY), "Missing %s element",
                     XmlNetconfConstants.RPC_KEY);
 
             final Element rpcReply = errorDocument.getDocumentElement();
-            Preconditions.checkState(rpcReply.getTagName().equals(XmlNetconfConstants.RPC_REPLY_KEY), "Missing %s element",
-                    XmlNetconfConstants.RPC_REPLY_KEY);
+            Preconditions.checkState(rpcReply.getTagName().equals(XmlMappingConstants.RPC_REPLY_KEY), "Missing %s element",
+                    XmlMappingConstants.RPC_REPLY_KEY);
 
             final NamedNodeMap incomingAttributes = incommingRpc.getAttributes();
             for (int i = 0; i < incomingAttributes.getLength(); i++) {
@@ -82,7 +83,7 @@ public final class SendErrorExceptionUtil {
         }
     }
 
-    private static Document createDocument(final NetconfDocumentedException sendErrorException) {
+    private static Document createDocument(final DocumentedException sendErrorException) {
         return sendErrorException.toXMLDocument();
     }
 
@@ -90,9 +91,9 @@ public final class SendErrorExceptionUtil {
      * Checks if netconf error was sent successfully.
      */
     private static final class SendErrorVerifyingListener implements ChannelFutureListener {
-        private final NetconfDocumentedException sendErrorException;
+        private final DocumentedException sendErrorException;
 
-        public SendErrorVerifyingListener(final NetconfDocumentedException sendErrorException) {
+        public SendErrorVerifyingListener(final DocumentedException sendErrorException) {
             this.sendErrorException = sendErrorException;
         }
 
diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlElement.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlElement.java
deleted file mode 100644 (file)
index 3d46bf6..0000000
+++ /dev/null
@@ -1,540 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.util.xml;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Predicate;
-import com.google.common.base.Strings;
-import com.google.common.collect.Collections2;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.util.exception.MissingNameSpaceException;
-import org.opendaylight.controller.netconf.util.exception.UnexpectedElementException;
-import org.opendaylight.controller.netconf.util.exception.UnexpectedNamespaceException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Attr;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.w3c.dom.Text;
-import org.xml.sax.SAXException;
-
-public final class XmlElement {
-
-    public static final String DEFAULT_NAMESPACE_PREFIX = "";
-
-    private final Element element;
-    private static final Logger LOG = LoggerFactory.getLogger(XmlElement.class);
-
-    private XmlElement(Element element) {
-        this.element = element;
-    }
-
-    public static XmlElement fromDomElement(Element e) {
-        return new XmlElement(e);
-    }
-
-    public static XmlElement fromDomDocument(Document xml) {
-        return new XmlElement(xml.getDocumentElement());
-    }
-
-    public static XmlElement fromString(String s) throws NetconfDocumentedException {
-        try {
-            return new XmlElement(XmlUtil.readXmlToElement(s));
-        } catch (IOException | SAXException e) {
-            throw NetconfDocumentedException.wrap(e);
-        }
-    }
-
-    public static XmlElement fromDomElementWithExpected(Element element, String expectedName) throws NetconfDocumentedException {
-        XmlElement xmlElement = XmlElement.fromDomElement(element);
-        xmlElement.checkName(expectedName);
-        return xmlElement;
-    }
-
-    public static XmlElement fromDomElementWithExpected(Element element, String expectedName, String expectedNamespace) throws NetconfDocumentedException {
-        XmlElement xmlElement = XmlElement.fromDomElementWithExpected(element, expectedName);
-        xmlElement.checkNamespace(expectedNamespace);
-        return xmlElement;
-    }
-
-    private Map<String, String> extractNamespaces() throws NetconfDocumentedException {
-        Map<String, String> namespaces = new HashMap<>();
-        NamedNodeMap attributes = element.getAttributes();
-        for (int i = 0; i < attributes.getLength(); i++) {
-            Node attribute = attributes.item(i);
-            String attribKey = attribute.getNodeName();
-            if (attribKey.startsWith(XmlUtil.XMLNS_ATTRIBUTE_KEY)) {
-                String prefix;
-                if (attribKey.equals(XmlUtil.XMLNS_ATTRIBUTE_KEY)) {
-                    prefix = DEFAULT_NAMESPACE_PREFIX;
-                } else {
-                    if (!attribKey.startsWith(XmlUtil.XMLNS_ATTRIBUTE_KEY + ":")){
-                        throw new NetconfDocumentedException("Attribute doesn't start with :",
-                                NetconfDocumentedException.ErrorType.application,
-                                NetconfDocumentedException.ErrorTag.invalid_value,
-                                NetconfDocumentedException.ErrorSeverity.error);
-                    }
-                    prefix = attribKey.substring(XmlUtil.XMLNS_ATTRIBUTE_KEY.length() + 1);
-                }
-                namespaces.put(prefix, attribute.getNodeValue());
-            }
-        }
-
-        // namespace does not have to be defined on this element but inherited
-        if(!namespaces.containsKey(DEFAULT_NAMESPACE_PREFIX)) {
-            Optional<String> namespaceOptionally = getNamespaceOptionally();
-            if(namespaceOptionally.isPresent()) {
-                namespaces.put(DEFAULT_NAMESPACE_PREFIX, namespaceOptionally.get());
-            }
-        }
-
-        return namespaces;
-    }
-
-    public void checkName(String expectedName) throws UnexpectedElementException {
-        if (!getName().equals(expectedName)){
-            throw new UnexpectedElementException(String.format("Expected %s xml element but was %s", expectedName,
-                    getName()),
-                    NetconfDocumentedException.ErrorType.application,
-                    NetconfDocumentedException.ErrorTag.operation_failed,
-                    NetconfDocumentedException.ErrorSeverity.error);
-        }
-    }
-
-    public void checkNamespaceAttribute(String expectedNamespace) throws UnexpectedNamespaceException, MissingNameSpaceException {
-        if (!getNamespaceAttribute().equals(expectedNamespace))
-        {
-            throw new UnexpectedNamespaceException(String.format("Unexpected namespace %s should be %s",
-                    getNamespaceAttribute(),
-                    expectedNamespace),
-                    NetconfDocumentedException.ErrorType.application,
-                    NetconfDocumentedException.ErrorTag.operation_failed,
-                    NetconfDocumentedException.ErrorSeverity.error);
-        }
-    }
-
-    public void checkNamespace(String expectedNamespace) throws UnexpectedNamespaceException, MissingNameSpaceException {
-        if (!getNamespace().equals(expectedNamespace))
-        {
-            throw new UnexpectedNamespaceException(String.format("Unexpected namespace %s should be %s",
-                    getNamespace(),
-                    expectedNamespace),
-                    NetconfDocumentedException.ErrorType.application,
-                    NetconfDocumentedException.ErrorTag.operation_failed,
-                    NetconfDocumentedException.ErrorSeverity.error);
-        }
-    }
-
-    public String getName() {
-        final String localName = element.getLocalName();
-        if (!Strings.isNullOrEmpty(localName)){
-            return localName;
-        }
-        return element.getTagName();
-    }
-
-    public String getAttribute(String attributeName) {
-        return element.getAttribute(attributeName);
-    }
-
-    public String getAttribute(String attributeName, String namespace) {
-        return element.getAttributeNS(namespace, attributeName);
-    }
-
-    public NodeList getElementsByTagName(String name) {
-        return element.getElementsByTagName(name);
-    }
-
-    public void appendChild(Element element) {
-        this.element.appendChild(element);
-    }
-
-    public Element getDomElement() {
-        return element;
-    }
-
-    public Map<String, Attr> getAttributes() {
-
-        Map<String, Attr> mappedAttributes = Maps.newHashMap();
-
-        NamedNodeMap attributes = element.getAttributes();
-        for (int i = 0; i < attributes.getLength(); i++) {
-            Attr attr = (Attr) attributes.item(i);
-            mappedAttributes.put(attr.getNodeName(), attr);
-        }
-
-        return mappedAttributes;
-    }
-
-    /**
-     * Non recursive
-     */
-    private List<XmlElement> getChildElementsInternal(ElementFilteringStrategy strat) {
-        NodeList childNodes = element.getChildNodes();
-        final List<XmlElement> result = new ArrayList<>();
-        for (int i = 0; i < childNodes.getLength(); i++) {
-            Node item = childNodes.item(i);
-            if (!(item instanceof Element)) {
-                continue;
-            }
-            if (strat.accept((Element) item)) {
-                result.add(new XmlElement((Element) item));
-            }
-        }
-
-        return result;
-    }
-
-    public List<XmlElement> getChildElements() {
-        return getChildElementsInternal(new ElementFilteringStrategy() {
-            @Override
-            public boolean accept(Element e) {
-                return true;
-            }
-        });
-    }
-
-    public List<XmlElement> getChildElementsWithinNamespace(final String childName, String namespace) {
-        return Lists.newArrayList(Collections2.filter(getChildElementsWithinNamespace(namespace),
-                new Predicate<XmlElement>() {
-                    @Override
-                    public boolean apply(XmlElement xmlElement) {
-                        return xmlElement.getName().equals(childName);
-                    }
-                }));
-    }
-
-    public List<XmlElement> getChildElementsWithinNamespace(final String namespace) {
-        return getChildElementsInternal(new ElementFilteringStrategy() {
-            @Override
-            public boolean accept(Element e) {
-                try {
-                    return XmlElement.fromDomElement(e).getNamespace().equals(namespace);
-                } catch (MissingNameSpaceException e1) {
-                    return false;
-                }
-            }
-
-        });
-    }
-
-    /**
-     *
-     * @param tagName tag name without prefix
-     * @return List of child elements
-     */
-    public List<XmlElement> getChildElements(final String tagName) {
-        return getChildElementsInternal(new ElementFilteringStrategy() {
-            @Override
-            public boolean accept(Element e) {
-                // localName returns pure localName without prefix
-                return e.getLocalName().equals(tagName);
-            }
-        });
-    }
-
-    public XmlElement getOnlyChildElement(String childName) throws NetconfDocumentedException {
-        List<XmlElement> nameElements = getChildElements(childName);
-        if (nameElements.size() != 1){
-            throw new NetconfDocumentedException("One element " + childName + " expected in " + toString(),
-                    NetconfDocumentedException.ErrorType.application,
-                    NetconfDocumentedException.ErrorTag.invalid_value,
-                    NetconfDocumentedException.ErrorSeverity.error);
-        }
-        return nameElements.get(0);
-    }
-
-    public Optional<XmlElement> getOnlyChildElementOptionally(String childName) {
-        List<XmlElement> nameElements = getChildElements(childName);
-        if (nameElements.size() != 1) {
-            return Optional.absent();
-        }
-        return Optional.of(nameElements.get(0));
-    }
-
-    public Optional<XmlElement> getOnlyChildElementOptionally(final String childName, final String namespace) {
-        List<XmlElement> children = getChildElementsWithinNamespace(namespace);
-        children = Lists.newArrayList(Collections2.filter(children, new Predicate<XmlElement>() {
-            @Override
-            public boolean apply(XmlElement xmlElement) {
-                return xmlElement.getName().equals(childName);
-            }
-        }));
-        if (children.size() != 1){
-            return Optional.absent();
-        }
-        return Optional.of(children.get(0));
-    }
-
-    public XmlElement getOnlyChildElementWithSameNamespace(String childName) throws  NetconfDocumentedException {
-        return getOnlyChildElement(childName, getNamespace());
-    }
-
-    public Optional<XmlElement> getOnlyChildElementWithSameNamespaceOptionally(final String childName) {
-        Optional<String> namespace = getNamespaceOptionally();
-        if (namespace.isPresent()) {
-            List<XmlElement> children = getChildElementsWithinNamespace(namespace.get());
-            children = Lists.newArrayList(Collections2.filter(children, new Predicate<XmlElement>() {
-                @Override
-                public boolean apply(XmlElement xmlElement) {
-                    return xmlElement.getName().equals(childName);
-                }
-            }));
-            if (children.size() != 1){
-                return Optional.absent();
-            }
-            return Optional.of(children.get(0));
-        }
-        return Optional.absent();
-    }
-
-    public XmlElement getOnlyChildElementWithSameNamespace() throws NetconfDocumentedException {
-        XmlElement childElement = getOnlyChildElement();
-        childElement.checkNamespace(getNamespace());
-        return childElement;
-    }
-
-    public Optional<XmlElement> getOnlyChildElementWithSameNamespaceOptionally() {
-        Optional<XmlElement> child = getOnlyChildElementOptionally();
-        if (child.isPresent()
-                && child.get().getNamespaceOptionally().isPresent()
-                && getNamespaceOptionally().isPresent()
-                && getNamespaceOptionally().get().equals(child.get().getNamespaceOptionally().get())) {
-            return child;
-        }
-        return Optional.absent();
-    }
-
-    public XmlElement getOnlyChildElement(final String childName, String namespace) throws NetconfDocumentedException {
-        List<XmlElement> children = getChildElementsWithinNamespace(namespace);
-        children = Lists.newArrayList(Collections2.filter(children, new Predicate<XmlElement>() {
-            @Override
-            public boolean apply(XmlElement xmlElement) {
-                return xmlElement.getName().equals(childName);
-            }
-        }));
-        if (children.size() != 1){
-            throw new NetconfDocumentedException(String.format("One element %s:%s expected in %s but was %s", namespace,
-                    childName, toString(), children.size()),
-                    NetconfDocumentedException.ErrorType.application,
-                    NetconfDocumentedException.ErrorTag.invalid_value,
-                    NetconfDocumentedException.ErrorSeverity.error);
-        }
-
-        return children.get(0);
-    }
-
-    public XmlElement getOnlyChildElement() throws NetconfDocumentedException {
-        List<XmlElement> children = getChildElements();
-        if (children.size() != 1){
-            throw new NetconfDocumentedException(String.format( "One element expected in %s but was %s", toString(),
-                    children.size()),
-                    NetconfDocumentedException.ErrorType.application,
-                    NetconfDocumentedException.ErrorTag.invalid_value,
-                    NetconfDocumentedException.ErrorSeverity.error);
-        }
-        return children.get(0);
-    }
-
-    public Optional<XmlElement> getOnlyChildElementOptionally() {
-        List<XmlElement> children = getChildElements();
-        if (children.size() != 1) {
-            return Optional.absent();
-        }
-        return Optional.of(children.get(0));
-    }
-
-    public String getTextContent() throws NetconfDocumentedException {
-        NodeList childNodes = element.getChildNodes();
-        if (childNodes.getLength() == 0) {
-            return DEFAULT_NAMESPACE_PREFIX;
-        }
-        for(int i = 0; i < childNodes.getLength(); i++) {
-            Node textChild = childNodes.item(i);
-            if (textChild instanceof Text) {
-                String content = textChild.getTextContent();
-                return content.trim();
-            }
-        }
-        throw new NetconfDocumentedException(getName() + " should contain text.",
-                NetconfDocumentedException.ErrorType.application,
-                NetconfDocumentedException.ErrorTag.invalid_value,
-                NetconfDocumentedException.ErrorSeverity.error
-        );
-    }
-
-    public Optional<String> getOnlyTextContentOptionally() {
-        // only return text content if this node has exactly one Text child node
-        if (element.getChildNodes().getLength() == 1) {
-            Node item = element.getChildNodes().item(0);
-            if (item instanceof Text) {
-                return Optional.of(((Text) item).getWholeText());
-            }
-        }
-        return Optional.absent();
-    }
-
-    public String getNamespaceAttribute() throws MissingNameSpaceException {
-        String attribute = element.getAttribute(XmlUtil.XMLNS_ATTRIBUTE_KEY);
-        if (attribute == null || attribute.equals(DEFAULT_NAMESPACE_PREFIX)){
-            throw new MissingNameSpaceException(String.format("Element %s must specify namespace",
-                    toString()),
-                    NetconfDocumentedException.ErrorType.application,
-                    NetconfDocumentedException.ErrorTag.operation_failed,
-                    NetconfDocumentedException.ErrorSeverity.error);
-        }
-        return attribute;
-    }
-
-    public Optional<String> getNamespaceAttributeOptionally(){
-        String attribute = element.getAttribute(XmlUtil.XMLNS_ATTRIBUTE_KEY);
-        if (attribute == null || attribute.equals(DEFAULT_NAMESPACE_PREFIX)){
-            return Optional.absent();
-        }
-        return Optional.of(attribute);
-    }
-
-    public Optional<String> getNamespaceOptionally() {
-        String namespaceURI = element.getNamespaceURI();
-        if (Strings.isNullOrEmpty(namespaceURI)) {
-            return Optional.absent();
-        } else {
-            return Optional.of(namespaceURI);
-        }
-    }
-
-    public String getNamespace() throws MissingNameSpaceException {
-        Optional<String> namespaceURI = getNamespaceOptionally();
-        if (!namespaceURI.isPresent()){
-            throw new MissingNameSpaceException(String.format("No namespace defined for %s", this),
-                    NetconfDocumentedException.ErrorType.application,
-                    NetconfDocumentedException.ErrorTag.operation_failed,
-                    NetconfDocumentedException.ErrorSeverity.error);
-        }
-        return namespaceURI.get();
-    }
-
-    @Override
-    public String toString() {
-        final StringBuilder sb = new StringBuilder("XmlElement{");
-        sb.append("name='").append(getName()).append('\'');
-        if (element.getNamespaceURI() != null) {
-            try {
-                sb.append(", namespace='").append(getNamespace()).append('\'');
-            } catch (MissingNameSpaceException e) {
-                LOG.trace("Missing namespace for element.");
-            }
-        }
-        sb.append('}');
-        return sb.toString();
-    }
-
-    /**
-     * Search for element's attributes defining namespaces. Look for the one
-     * namespace that matches prefix of element's text content. E.g.
-     *
-     * <pre>
-     * &lt;type
-     * xmlns:th-java="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl"&gt;th-java:threadfactory-naming&lt;/type&gt;
-     * </pre>
-     *
-     * returns {"th-java","urn:.."}. If no prefix is matched, then default
-     * namespace is returned with empty string as key. If no default namespace
-     * is found value will be null.
-     */
-    public Map.Entry<String/* prefix */, String/* namespace */> findNamespaceOfTextContent() throws NetconfDocumentedException {
-        Map<String, String> namespaces = extractNamespaces();
-        String textContent = getTextContent();
-        int indexOfColon = textContent.indexOf(':');
-        String prefix;
-        if (indexOfColon > -1) {
-            prefix = textContent.substring(0, indexOfColon);
-        } else {
-            prefix = DEFAULT_NAMESPACE_PREFIX;
-        }
-        if (!namespaces.containsKey(prefix)) {
-            throw new IllegalArgumentException("Cannot find namespace for " + XmlUtil.toString(element) + ". Prefix from content is "
-                    + prefix + ". Found namespaces " + namespaces);
-        }
-        return Maps.immutableEntry(prefix, namespaces.get(prefix));
-    }
-
-    public List<XmlElement> getChildElementsWithSameNamespace(final String childName) throws MissingNameSpaceException {
-        List<XmlElement> children = getChildElementsWithinNamespace(getNamespace());
-        return Lists.newArrayList(Collections2.filter(children, new Predicate<XmlElement>() {
-            @Override
-            public boolean apply(XmlElement xmlElement) {
-                return xmlElement.getName().equals(childName);
-            }
-        }));
-    }
-
-    public void checkUnrecognisedElements(List<XmlElement> recognisedElements,
-            XmlElement... additionalRecognisedElements) throws NetconfDocumentedException {
-        List<XmlElement> childElements = getChildElements();
-        childElements.removeAll(recognisedElements);
-        for (XmlElement additionalRecognisedElement : additionalRecognisedElements) {
-            childElements.remove(additionalRecognisedElement);
-        }
-        if (!childElements.isEmpty()){
-            throw new NetconfDocumentedException(String.format("Unrecognised elements %s in %s", childElements, this),
-                    NetconfDocumentedException.ErrorType.application,
-                    NetconfDocumentedException.ErrorTag.invalid_value,
-                    NetconfDocumentedException.ErrorSeverity.error);
-        }
-    }
-
-    public void checkUnrecognisedElements(XmlElement... additionalRecognisedElements) throws NetconfDocumentedException {
-        checkUnrecognisedElements(Collections.<XmlElement>emptyList(), additionalRecognisedElements);
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) {
-            return true;
-        }
-        if (o == null || getClass() != o.getClass()) {
-            return false;
-        }
-
-        XmlElement that = (XmlElement) o;
-
-        return element.isEqualNode(that.element);
-
-    }
-
-    @Override
-    public int hashCode() {
-        return element.hashCode();
-    }
-
-    public boolean hasNamespace() {
-        if (!getNamespaceAttributeOptionally().isPresent()) {
-            if (!getNamespaceOptionally().isPresent()) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    private interface ElementFilteringStrategy {
-        boolean accept(Element e);
-    }
-}
index bdab8c6209184d1262542bcd1b25b7d171157919..4de55a7ff3d40ae2e77e6eb48354f01517bfc3d3 100644 (file)
@@ -15,6 +15,7 @@ import javax.xml.transform.Source;
 import javax.xml.transform.dom.DOMSource;
 import javax.xml.validation.Schema;
 import javax.xml.validation.Validator;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.w3c.dom.Document;
 import org.xml.sax.SAXException;
 
diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlUtil.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlUtil.java
deleted file mode 100644 (file)
index 65754e6..0000000
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.util.xml;
-
-import com.google.common.base.Charsets;
-import com.google.common.base.Optional;
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.StringWriter;
-import javax.xml.XMLConstants;
-import javax.xml.namespace.QName;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.transform.OutputKeys;
-import javax.xml.transform.Source;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.TransformerFactoryConfigurationError;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
-import javax.xml.transform.stream.StreamSource;
-import javax.xml.validation.Schema;
-import javax.xml.validation.SchemaFactory;
-import javax.xml.xpath.XPathExpression;
-import javax.xml.xpath.XPathExpressionException;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.xml.sax.SAXException;
-
-public final class XmlUtil {
-
-    public static final String XMLNS_ATTRIBUTE_KEY = "xmlns";
-    public static final String XMLNS_URI = "http://www.w3.org/2000/xmlns/";
-    private static final DocumentBuilderFactory BUILDER_FACTORY;
-    private static final TransformerFactory TRANSFORMER_FACTORY = TransformerFactory.newInstance();
-    private static final SchemaFactory SCHEMA_FACTORY = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
-
-    static {
-        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
-        try {
-            factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
-            factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
-            factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
-            factory.setXIncludeAware(false);
-            factory.setExpandEntityReferences(false);
-            // Performance improvement for messages with size <10k according to
-            // https://xerces.apache.org/xerces2-j/faq-performance.html
-            factory.setFeature("http://apache.org/xml/features/dom/defer-node-expansion", false);
-        } catch (ParserConfigurationException e) {
-            throw new ExceptionInInitializerError(e);
-        }
-        factory.setNamespaceAware(true);
-        factory.setCoalescing(true);
-        factory.setIgnoringElementContentWhitespace(true);
-        factory.setIgnoringComments(true);
-        BUILDER_FACTORY = factory;
-    }
-
-    private static final ThreadLocal<DocumentBuilder> DEFAULT_DOM_BUILDER = new ThreadLocal<DocumentBuilder>(){
-        @Override
-        protected DocumentBuilder initialValue() {
-            try {
-                return BUILDER_FACTORY.newDocumentBuilder();
-            } catch (ParserConfigurationException e) {
-                throw new IllegalStateException("Failed to create threadLocal dom builder", e);
-            }
-        }
-
-        @Override
-        public void set(DocumentBuilder value) {
-            throw new UnsupportedOperationException();
-        }
-    };
-
-    private XmlUtil() {
-        throw new UnsupportedOperationException("Utility class");
-    }
-
-    public static Element readXmlToElement(final String xmlContent) throws SAXException, IOException {
-        Document doc = readXmlToDocument(xmlContent);
-        return doc.getDocumentElement();
-    }
-
-    public static Element readXmlToElement(final InputStream xmlContent) throws SAXException, IOException {
-        Document doc = readXmlToDocument(xmlContent);
-        return doc.getDocumentElement();
-    }
-
-    public static Document readXmlToDocument(final String xmlContent) throws SAXException, IOException {
-        return readXmlToDocument(new ByteArrayInputStream(xmlContent.getBytes(Charsets.UTF_8)));
-    }
-
-    // TODO improve exceptions throwing
-    // along with XmlElement
-
-    public static Document readXmlToDocument(final InputStream xmlContent) throws SAXException, IOException {
-        Document doc = DEFAULT_DOM_BUILDER.get().parse(xmlContent);
-
-        doc.getDocumentElement().normalize();
-        return doc;
-    }
-
-    public static Element readXmlToElement(final File xmlFile) throws SAXException, IOException {
-        return readXmlToDocument(new FileInputStream(xmlFile)).getDocumentElement();
-    }
-
-    public static Document newDocument() {
-        return DEFAULT_DOM_BUILDER.get().newDocument();
-    }
-
-    public static Element createElement(final Document document, final String qName, final Optional<String> namespaceURI) {
-        if(namespaceURI.isPresent()) {
-            final Element element = document.createElementNS(namespaceURI.get(), qName);
-            String name = XMLNS_ATTRIBUTE_KEY;
-            if(element.getPrefix() != null) {
-                name += ":" + element.getPrefix();
-            }
-            element.setAttributeNS(XMLNS_URI, name, namespaceURI.get());
-            return element;
-        }
-        return document.createElement(qName);
-    }
-
-    public static Element createTextElement(final Document document, final String qName, final String content, final Optional<String> namespaceURI) {
-        Element typeElement = createElement(document, qName, namespaceURI);
-        typeElement.appendChild(document.createTextNode(content));
-        return typeElement;
-    }
-
-    public static Element createTextElementWithNamespacedContent(final Document document, final String qName, final String prefix,
-                                                                 final String namespace, final String contentWithoutPrefix) {
-
-        return createTextElementWithNamespacedContent(document, qName, prefix, namespace, contentWithoutPrefix, Optional.<String>absent());
-    }
-
-    public static Element createTextElementWithNamespacedContent(final Document document, final String qName, final String prefix,
-                                                                 final String namespace, final String contentWithoutPrefix, final Optional<String> namespaceURI) {
-
-        String content = createPrefixedValue(XmlNetconfConstants.PREFIX, contentWithoutPrefix);
-        Element element = createTextElement(document, qName, content, namespaceURI);
-        String prefixedNamespaceAttr = createPrefixedValue(XMLNS_ATTRIBUTE_KEY, prefix);
-        element.setAttributeNS(XMLNS_URI, prefixedNamespaceAttr, namespace);
-        return element;
-    }
-
-    public static String createPrefixedValue(final String prefix, final String value) {
-        return prefix + ":" + value;
-    }
-
-    public static String toString(final Document document) {
-        return toString(document.getDocumentElement());
-    }
-
-    public static String toString(final Element xml) {
-        return toString(xml, false);
-    }
-
-    public static String toString(final XmlElement xmlElement) {
-        return toString(xmlElement.getDomElement(), false);
-    }
-
-    public static String toString(final Element xml, final boolean addXmlDeclaration) {
-        try {
-            Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
-            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
-            transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, addXmlDeclaration ? "no" : "yes");
-
-            StreamResult result = new StreamResult(new StringWriter());
-            DOMSource source = new DOMSource(xml);
-            transformer.transform(source, result);
-
-            return result.getWriter().toString();
-        } catch (Exception |  TransformerFactoryConfigurationError e) {
-            throw new IllegalStateException("Unable to serialize xml element " + xml, e);
-        }
-    }
-
-    public static String toString(final Document doc, final boolean addXmlDeclaration) {
-        return toString(doc.getDocumentElement(), addXmlDeclaration);
-    }
-
-    public static Schema loadSchema(final InputStream... fromStreams) {
-        Source[] sources = new Source[fromStreams.length];
-        int i = 0;
-        for (InputStream stream : fromStreams) {
-            sources[i++] = new StreamSource(stream);
-        }
-
-        try {
-            return SCHEMA_FACTORY.newSchema(sources);
-        } catch (SAXException e) {
-            throw new IllegalStateException("Failed to instantiate XML schema", e);
-        }
-    }
-
-    public static Object evaluateXPath(final XPathExpression expr, final Object rootNode, final QName returnType) {
-        try {
-            return expr.evaluate(rootNode, returnType);
-        } catch (XPathExpressionException e) {
-            throw new IllegalStateException("Error while evaluating xpath expression " + expr, e);
-        }
-    }
-
-    public static Document createDocumentCopy(final Document original) {
-        final Document copiedDocument = newDocument();
-        final Node copiedRoot = copiedDocument.importNode(original.getDocumentElement(), true);
-        copiedDocument.appendChild(copiedRoot);
-        return copiedDocument;
-    }
-}
index 007dfdc1e7576aad45830d3e0089c6964409e420..d85128067c7725acf9367dfe65871bc697cb8bf3 100644 (file)
@@ -12,7 +12,7 @@ import static org.junit.Assert.assertThat;
 import static org.junit.Assert.fail;
 
 import org.junit.Test;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.w3c.dom.Document;
 
 public class NetconfUtilTest {
index a6d1d5b999bcfa0757ec12b5aa13db0f2485d400..5fca285719d3beea809dae687efa68abec0c2ce0 100644 (file)
@@ -15,10 +15,10 @@ import static org.mockito.Mockito.mock;
 
 import org.junit.Before;
 import org.junit.Test;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.config.util.xml.XmlElement;
 import org.opendaylight.controller.netconf.mapping.api.HandlingPriority;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperationChainedExecution;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
@@ -33,7 +33,7 @@ public class AbstractLastNetconfOperationTest {
         }
 
         @Override
-        protected Element handleWithNoSubsequentOperations(Document document, XmlElement operationElement) throws NetconfDocumentedException {
+        protected Element handleWithNoSubsequentOperations(Document document, XmlElement operationElement) throws DocumentedException{
             handleWithNoSubsequentOperationsRun = true;
             return null;
         }
@@ -58,7 +58,7 @@ public class AbstractLastNetconfOperationTest {
         assertEquals(HandlingPriority.HANDLE_WITH_DEFAULT_PRIORITY, netconfOperation.getHandlingPriority());
     }
 
-    @Test(expected = NetconfDocumentedException.class)
+    @Test(expected = DocumentedException.class)
     public void testHandle() throws Exception {
         NetconfOperationChainedExecution operation = mock(NetconfOperationChainedExecution.class);
         doReturn("").when(operation).toString();
index c7f6321e2c2c22d6c5893af56e76817790ca7323..1002ea06f8aec05292171777d148bf4e43149c62 100644 (file)
@@ -16,12 +16,12 @@ import static org.mockito.Mockito.mock;
 import java.io.IOException;
 import org.junit.Before;
 import org.junit.Test;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.config.util.xml.XmlElement;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.netconf.mapping.api.HandlingPriority;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperationChainedExecution;
 import org.opendaylight.controller.netconf.util.test.XmlFileLoader;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.xml.sax.SAXException;
@@ -43,7 +43,7 @@ public class AbstractNetconfOperationTest {
         }
 
         @Override
-        protected Element handle(Document document, XmlElement message, NetconfOperationChainedExecution subsequentOperation) throws NetconfDocumentedException {
+        protected Element handle(Document document, XmlElement message, NetconfOperationChainedExecution subsequentOperation) throws DocumentedException{
             this.handleRun = true;
             try {
                 return XmlUtil.readXmlToElement("<element/>");
index 911b73f097ffad0c24af495e3cc39ce113bba617..14db47f92bf8a89c57436b207fb46b083f067ee0 100644 (file)
@@ -11,9 +11,9 @@ package org.opendaylight.controller.netconf.util.mapping;
 import static org.junit.Assert.assertEquals;
 
 import org.junit.Test;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.config.util.xml.XmlElement;
 import org.opendaylight.controller.netconf.mapping.api.HandlingPriority;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
@@ -25,7 +25,7 @@ public class AbstractSingletonNetconfOperationTest {
         }
 
         @Override
-        protected Element handleWithNoSubsequentOperations(Document document, XmlElement operationElement) throws NetconfDocumentedException {
+        protected Element handleWithNoSubsequentOperations(Document document, XmlElement operationElement) throws DocumentedException{
             return null;
         }
 
index 20287741b9fd57532a8fb4007ae320c517f34540..f98e6d9840e525cb187af32051d8b932a7e7e78f 100644 (file)
@@ -19,7 +19,7 @@ import io.netty.channel.ChannelFuture;
 import io.netty.util.concurrent.GenericFutureListener;
 import org.junit.Before;
 import org.junit.Test;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
 import org.opendaylight.controller.netconf.api.NetconfMessage;
 import org.opendaylight.controller.netconf.api.NetconfSession;
 import org.opendaylight.controller.netconf.util.test.XmlFileLoader;
@@ -30,7 +30,7 @@ public class SendErrorExceptionUtilTest {
     NetconfSession netconfSession;
     ChannelFuture channelFuture;
     Channel channel;
-    private NetconfDocumentedException exception;
+    private DocumentedException exception;
 
     @Before
     public void setUp() throws Exception {
@@ -40,7 +40,7 @@ public class SendErrorExceptionUtilTest {
         doReturn(channelFuture).when(netconfSession).sendMessage(any(NetconfMessage.class));
         doReturn(channelFuture).when(channelFuture).addListener(any(GenericFutureListener.class));
         doReturn(channelFuture).when(channel).writeAndFlush(any(NetconfMessage.class));
-        exception = new NetconfDocumentedException("err");
+        exception = new DocumentedException("err");
     }
 
     @Test
index 176a0de9a48f1d87a7eebb4ac2e48a74b89cac6e..125162e524bee62fd173c4d25eaa7be999a2a7be 100644 (file)
@@ -14,8 +14,8 @@ import com.google.common.io.ByteSource;
 import java.io.IOException;
 import java.io.InputStream;
 import javax.xml.parsers.ParserConfigurationException;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.xml.sax.SAXException;
index e0d432f27cbb14c581a3bf9fc3453f76d2b2d984..4cd7fccd25489f79e82a4d6c64ec34e492d9dd3b 100644 (file)
@@ -16,7 +16,7 @@ import org.custommonkey.xmlunit.AbstractNodeTester;
 import org.custommonkey.xmlunit.NodeTest;
 import org.custommonkey.xmlunit.NodeTestException;
 import org.custommonkey.xmlunit.NodeTester;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
diff --git a/opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/xml/XMLNetconfUtilTest.java b/opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/xml/XMLNetconfUtilTest.java
new file mode 100644 (file)
index 0000000..c702f6c
--- /dev/null
@@ -0,0 +1,25 @@
+package org.opendaylight.controller.netconf.util.xml;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpression;
+import org.junit.Test;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
+import org.w3c.dom.Element;
+
+public class XMLNetconfUtilTest {
+
+    @Test
+    public void testXPath() throws Exception {
+        final XPathExpression correctXPath = XMLNetconfUtil.compileXPath("/top/innerText");
+        try {
+            XMLNetconfUtil.compileXPath("!@(*&$!");
+            fail("Incorrect xpath should fail");
+        } catch (IllegalStateException e) {}
+        final Object value = XmlUtil.evaluateXPath(correctXPath, XmlUtil.readXmlToDocument("<top><innerText>value</innerText></top>"), XPathConstants.NODE);
+        assertEquals("value", ((Element) value).getTextContent());
+    }
+
+}
\ No newline at end of file
diff --git a/opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/xml/XmlElementTest.java b/opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/xml/XmlElementTest.java
deleted file mode 100644 (file)
index 22210a3..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.util.xml;
-
-import static org.hamcrest.CoreMatchers.both;
-import static org.hamcrest.CoreMatchers.containsString;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import com.google.common.base.Optional;
-import java.util.Map;
-import org.junit.Before;
-import org.junit.Test;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.util.exception.MissingNameSpaceException;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-public class XmlElementTest {
-
-    private final String elementAsString = "<top xmlns=\"namespace\" xmlns:a=\"attrNamespace\" a:attr1=\"value1\" attr2=\"value2\">" +
-            "<inner>" +
-            "<deepInner>deepValue</deepInner>" +
-            "</inner>" +
-            "<innerNamespace xmlns=\"innerNamespace\">innerNamespaceValue</innerNamespace>" +
-            "<innerPrefixed xmlns:b=\"prefixedValueNamespace\">b:valueWithPrefix</innerPrefixed>" +
-            "</top>";
-    private Document document;
-    private Element element;
-    private XmlElement xmlElement;
-
-    @Before
-    public void setUp() throws Exception {
-        document = XmlUtil.readXmlToDocument(elementAsString);
-        element = document.getDocumentElement();
-        xmlElement = XmlElement.fromDomElement(element);
-    }
-
-    @Test
-    public void testConstruct() throws Exception {
-        final XmlElement fromString = XmlElement.fromString(elementAsString);
-        assertEquals(fromString, xmlElement);
-        XmlElement.fromDomDocument(document);
-        XmlElement.fromDomElement(element);
-        XmlElement.fromDomElementWithExpected(element, "top");
-        XmlElement.fromDomElementWithExpected(element, "top", "namespace");
-
-        try {
-            XmlElement.fromString("notXml");
-            fail();
-        } catch (final NetconfDocumentedException e) {}
-
-        try {
-            XmlElement.fromDomElementWithExpected(element, "notTop");
-            fail();
-        } catch (final NetconfDocumentedException e) {}
-
-        try {
-            XmlElement.fromDomElementWithExpected(element, "top", "notNamespace");
-            fail();
-        } catch (final NetconfDocumentedException e) {}
-    }
-
-    @Test
-    public void testGetters() throws Exception {
-        assertEquals(element, xmlElement.getDomElement());
-        assertEquals(element.getElementsByTagName("inner").getLength(), xmlElement.getElementsByTagName("inner").getLength());
-
-        assertEquals("top", xmlElement.getName());
-        assertTrue(xmlElement.hasNamespace());
-        assertEquals("namespace", xmlElement.getNamespace());
-        assertEquals("namespace", xmlElement.getNamespaceAttribute());
-        assertEquals(Optional.of("namespace"), xmlElement.getNamespaceOptionally());
-
-        assertEquals("value1", xmlElement.getAttribute("attr1", "attrNamespace"));
-        assertEquals("value2", xmlElement.getAttribute("attr2"));
-        assertEquals(2 + 2/*Namespace definition*/, xmlElement.getAttributes().size());
-
-        assertEquals(3, xmlElement.getChildElements().size());
-        assertEquals(1, xmlElement.getChildElements("inner").size());
-        assertTrue(xmlElement.getOnlyChildElementOptionally("inner").isPresent());
-        assertTrue(xmlElement.getOnlyChildElementWithSameNamespaceOptionally("inner").isPresent());
-        assertEquals(0, xmlElement.getChildElements("unknown").size());
-        assertFalse(xmlElement.getOnlyChildElementOptionally("unknown").isPresent());
-        assertEquals(1, xmlElement.getChildElementsWithSameNamespace("inner").size());
-        assertEquals(0, xmlElement.getChildElementsWithSameNamespace("innerNamespace").size());
-        assertEquals(1, xmlElement.getChildElementsWithinNamespace("innerNamespace", "innerNamespace").size());
-        assertTrue(xmlElement.getOnlyChildElementOptionally("innerNamespace", "innerNamespace").isPresent());
-        assertFalse(xmlElement.getOnlyChildElementOptionally("innerNamespace", "unknownNamespace").isPresent());
-
-        final XmlElement noNamespaceElement = XmlElement.fromString("<noNamespace/>");
-        assertFalse(noNamespaceElement.hasNamespace());
-        try {
-            noNamespaceElement.getNamespace();
-            fail();
-        } catch (final MissingNameSpaceException e) {}
-
-        final XmlElement inner = xmlElement.getOnlyChildElement("inner");
-        final XmlElement deepInner = inner.getOnlyChildElementWithSameNamespaceOptionally().get();
-        assertEquals(deepInner, inner.getOnlyChildElementWithSameNamespace());
-        assertEquals(Optional.<XmlElement>absent(), xmlElement.getOnlyChildElementOptionally("unknown"));
-        assertEquals("deepValue", deepInner.getTextContent());
-        assertEquals("deepValue", deepInner.getOnlyTextContentOptionally().get());
-        assertEquals("deepValue", deepInner.getOnlyTextContentOptionally().get());
-    }
-
-    @Test
-    public void testExtractNamespaces() throws Exception {
-        final XmlElement innerPrefixed = xmlElement.getOnlyChildElement("innerPrefixed");
-        Map.Entry<String, String> namespaceOfTextContent = innerPrefixed.findNamespaceOfTextContent();
-
-        assertNotNull(namespaceOfTextContent);
-        assertEquals("b", namespaceOfTextContent.getKey());
-        assertEquals("prefixedValueNamespace", namespaceOfTextContent.getValue());
-        final XmlElement innerNamespace = xmlElement.getOnlyChildElement("innerNamespace");
-        namespaceOfTextContent = innerNamespace.findNamespaceOfTextContent();
-
-        assertEquals("", namespaceOfTextContent.getKey());
-        assertEquals("innerNamespace", namespaceOfTextContent.getValue());
-    }
-
-    @Test
-    public void testUnrecognisedElements() throws Exception {
-        xmlElement.checkUnrecognisedElements(xmlElement.getOnlyChildElement("inner"), xmlElement.getOnlyChildElement("innerPrefixed"), xmlElement.getOnlyChildElement("innerNamespace"));
-
-        try {
-            xmlElement.checkUnrecognisedElements(xmlElement.getOnlyChildElement("inner"));
-            fail();
-        } catch (final NetconfDocumentedException e) {
-            assertThat(e.getMessage(), both(containsString("innerNamespace")).and(containsString("innerNamespace")));
-        }
-    }
-}
diff --git a/opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/xml/XmlUtilTest.java b/opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/xml/XmlUtilTest.java
deleted file mode 100644 (file)
index 79aa565..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.util.xml;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import com.google.common.base.Optional;
-import javax.xml.xpath.XPathConstants;
-import javax.xml.xpath.XPathExpression;
-import org.custommonkey.xmlunit.Diff;
-import org.custommonkey.xmlunit.XMLUnit;
-import org.junit.Test;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.xml.sax.SAXParseException;
-
-public class XmlUtilTest {
-
-    private final String xml = "<top xmlns=\"namespace\">\n" +
-            "<innerText>value</innerText>\n" +
-            "<innerPrefixedText xmlns:pref=\"prefixNamespace\">prefix:value</innerPrefixedText>\n" +
-            "<innerPrefixedText xmlns=\"randomNamespace\" xmlns:pref=\"prefixNamespace\">prefix:value</innerPrefixedText>\n" +
-            "</top>";
-
-    @Test
-    public void testCreateElement() throws Exception {
-        final Document document = XmlUtil.newDocument();
-        final Element top = XmlUtil.createElement(document, "top", Optional.of("namespace"));
-
-        top.appendChild(XmlUtil.createTextElement(document, "innerText", "value", Optional.of("namespace")));
-        top.appendChild(XmlUtil.createTextElementWithNamespacedContent(document, "innerPrefixedText", "pref", "prefixNamespace", "value", Optional.of("namespace")));
-        top.appendChild(XmlUtil.createTextElementWithNamespacedContent(document, "innerPrefixedText", "pref", "prefixNamespace", "value", Optional.of("randomNamespace")));
-
-        document.appendChild(top);
-        assertEquals("top", XmlUtil.createDocumentCopy(document).getDocumentElement().getTagName());
-
-        XMLUnit.setIgnoreAttributeOrder(true);
-        XMLUnit.setIgnoreWhitespace(true);
-
-        final Diff diff = XMLUnit.compareXML(XMLUnit.buildControlDocument(xml), document);
-        assertTrue(diff.toString(), diff.similar());
-    }
-
-    @Test
-    public void testLoadSchema() throws Exception {
-        XmlUtil.loadSchema();
-        try {
-            XmlUtil.loadSchema(getClass().getResourceAsStream("/netconfMessages/commit.xml"));
-            fail("Input stream does not contain xsd");
-        } catch (final IllegalStateException e) {
-            assertTrue(e.getCause() instanceof SAXParseException);
-        }
-
-    }
-
-    @Test(expected = SAXParseException.class)
-    public void testXXEFlaw() throws Exception {
-        XmlUtil.readXmlToDocument("<!DOCTYPE foo [  \n" +
-                "<!ELEMENT foo ANY >\n" +
-                "<!ENTITY xxe SYSTEM \"file:///etc/passwd\" >]>\n" +
-                "<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n" +
-                "  <capabilities>\n" +
-                "    <capability>urn:ietf:params:netconf:base:1.0 &xxe;</capability>\n" +
-                "  </capabilities>\n" +
-                "  </hello>]]>]]>");
-    }
-
-    @Test
-    public void testXPath() throws Exception {
-        final XPathExpression correctXPath = XMLNetconfUtil.compileXPath("/top/innerText");
-        try {
-            XMLNetconfUtil.compileXPath("!@(*&$!");
-            fail("Incorrect xpath should fail");
-        } catch (IllegalStateException e) {}
-        final Object value = XmlUtil.evaluateXPath(correctXPath, XmlUtil.readXmlToDocument("<top><innerText>value</innerText></top>"), XPathConstants.NODE);
-        assertEquals("value", ((Element) value).getTextContent());
-    }
-}
\ No newline at end of file
index c5ffc80205417cb26e65db4a095a35430891cd62..a98f632e8fd4a8382407a0e5eef834235be03904 100644 (file)
@@ -16,7 +16,6 @@
 
   <modules>
     <module>netconf-api</module>
-    <module>netconf-cli</module>
     <module>netconf-config</module>
     <module>netconf-impl</module>
     <module>config-netconf-connector</module>
     <module>mdsal-netconf-monitoring</module>
     <module>netconf-util</module>
     <module>netconf-netty-util</module>
-    <module>config-persister-impl</module>
     <module>netconf-mapping-api</module>
     <module>netconf-client</module>
+    <module>netconf-config-dispatcher</module>
     <module>netconf-ssh</module>
     <module>netconf-tcp</module>
     <module>netconf-monitoring</module>
-    <module>ietf-netconf</module>
-    <module>ietf-netconf-monitoring</module>
-    <module>ietf-netconf-notifications</module>
-    <module>ietf-netconf-monitoring-extension</module>
     <module>netconf-connector-config</module>
     <module>netconf-mdsal-config</module>
     <module>netconf-auth</module>
-    <module>netconf-testtool</module>
     <module>netconf-notifications-impl</module>
     <module>netconf-notifications-api</module>
+    <module>sal-netconf-connector</module>
+    <module>features</module>
+    <module>models</module>
+    <module>tools</module>
 
     <module>netconf-artifacts</module>
   </modules>
         <plugin>
           <groupId>org.opendaylight.yangtools</groupId>
           <artifactId>yang-maven-plugin</artifactId>
-          <version>${yangtools.version}</version>
-          <dependencies>
-            <dependency>
-              <groupId>org.opendaylight.yangtools</groupId>
-              <artifactId>maven-sal-api-gen-plugin</artifactId>
-              <version>${yangtools.version}</version>
-            </dependency>
-          </dependencies>
           <executions>
             <execution>
+              <id>config</id>
               <goals>
                 <goal>generate-sources</goal>
               </goals>
               <configuration>
-                <yangFilesRootDir>src/main/yang</yangFilesRootDir>
                 <codeGenerators>
                   <generator>
-                    <codeGeneratorClass>org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl</codeGeneratorClass>
-                    <outputBaseDir>${salGeneratorPath}</outputBaseDir>
+                    <codeGeneratorClass>org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator</codeGeneratorClass>
+                    <outputBaseDir>${jmxGeneratorPath}</outputBaseDir>
+                    <additionalConfiguration>
+                      <namespaceToPackage1>urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang</namespaceToPackage1>
+                    </additionalConfiguration>
                   </generator>
                   <generator>
-                    <codeGeneratorClass>org.opendaylight.yangtools.yang.unified.doc.generator.maven.DocumentationGeneratorImpl</codeGeneratorClass>
-                    <outputBaseDir>${project.build.directory}/site/models</outputBaseDir>
+                    <codeGeneratorClass>org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl</codeGeneratorClass>
+                    <outputBaseDir>${salGeneratorPath}</outputBaseDir>
                   </generator>
                 </codeGenerators>
                 <inspectDependencies>true</inspectDependencies>
               </configuration>
             </execution>
           </executions>
+          <dependencies>
+            <dependency>
+              <groupId>org.opendaylight.controller</groupId>
+              <artifactId>yang-jmx-generator-plugin</artifactId>
+              <version>${config.version}</version>
+            </dependency>
+          </dependencies>
         </plugin>
       </plugins>
 
diff --git a/opendaylight/netconf/sal-netconf-connector/pom.xml b/opendaylight/netconf/sal-netconf-connector/pom.xml
new file mode 100644 (file)
index 0000000..1de7635
--- /dev/null
@@ -0,0 +1,189 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.opendaylight.controller</groupId>
+    <artifactId>netconf-subsystem</artifactId>
+    <version>0.4.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>sal-netconf-connector</artifactId>
+
+  <packaging>bundle</packaging>
+
+  <!-- Preserve version from mdsal -->
+  <version>${mdsal.version}</version>
+
+  <dependencies>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>netconf-config-dispatcher</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>sal-common-util</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>sal-connector-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>ietf-netconf-monitoring</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>ietf-netconf-notifications</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>netconf-client</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>netconf-notifications-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>netty-config-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>netty-threadgroup-config</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal-binding-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.yangtools</groupId>
+      <artifactId>binding-generator-impl</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal-binding-config</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>threadpool-config-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller.model</groupId>
+      <artifactId>model-inventory</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.yangtools.model</groupId>
+      <artifactId>ietf-topology</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal-broker-impl</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.yangtools</groupId>
+      <artifactId>yang-data-impl</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.yangtools</groupId>
+      <artifactId>yang-parser-impl</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.yangtools.model</groupId>
+      <artifactId>ietf-inet-types</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+    </dependency>
+      <dependency>
+          <groupId>xmlunit</groupId>
+          <artifactId>xmlunit</artifactId>
+      </dependency>
+      <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>config-api</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>config-manager</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>config-manager</artifactId>
+      <type>test-jar</type>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>config-netconf-connector</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>config-persister-impl</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>config-util</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>netconf-impl</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>netconf-mapping-api</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>netconf-util</artifactId>
+      <type>test-jar</type>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>yang-test</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>logback-config</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal-binding-broker-impl</artifactId>
+      <type>test-jar</type>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.yangtools</groupId>
+      <artifactId>mockito-configuration</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+      </plugin>
+      <plugin>
+        <groupId>org.opendaylight.yangtools</groupId>
+        <artifactId>yang-maven-plugin</artifactId>
+      </plugin>
+    </plugins>
+  </build>
+  <scm>
+    <connection>scm:git:http://git.opendaylight.org/gerrit/controller.git</connection>
+    <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
+    <tag>HEAD</tag>
+    <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL</url>
+  </scm>
+</project>
diff --git a/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/connector/netconf/NetconfConnectorModule.java b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/connector/netconf/NetconfConnectorModule.java
new file mode 100644 (file)
index 0000000..b7c518e
--- /dev/null
@@ -0,0 +1,273 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.config.yang.md.sal.connector.netconf;
+
+import static org.opendaylight.controller.config.api.JmxAttributeValidationException.checkCondition;
+import static org.opendaylight.controller.config.api.JmxAttributeValidationException.checkNotNull;
+
+import com.google.common.base.Optional;
+import io.netty.util.concurrent.EventExecutor;
+import java.math.BigDecimal;
+import java.net.InetSocketAddress;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ThreadFactory;
+import org.opendaylight.controller.config.api.JmxAttributeValidationException;
+import org.opendaylight.controller.netconf.client.NetconfClientDispatcher;
+import org.opendaylight.controller.netconf.client.conf.NetconfClientConfiguration;
+import org.opendaylight.controller.netconf.client.conf.NetconfReconnectingClientConfiguration;
+import org.opendaylight.controller.netconf.client.conf.NetconfReconnectingClientConfigurationBuilder;
+import org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication.LoginPassword;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
+import org.opendaylight.controller.sal.connect.api.RemoteDeviceHandler;
+import org.opendaylight.controller.sal.connect.netconf.NetconfDevice;
+import org.opendaylight.controller.sal.connect.netconf.NetconfStateSchemas;
+import org.opendaylight.controller.sal.connect.netconf.listener.NetconfDeviceCommunicator;
+import org.opendaylight.controller.sal.connect.netconf.listener.NetconfSessionPreferences;
+import org.opendaylight.controller.sal.connect.netconf.sal.KeepaliveSalFacade;
+import org.opendaylight.controller.sal.connect.netconf.sal.NetconfDeviceSalFacade;
+import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
+import org.opendaylight.controller.sal.core.api.Broker;
+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.rev100924.Host;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+import org.opendaylight.yangtools.yang.model.repo.api.SchemaContextFactory;
+import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceRegistry;
+import org.osgi.framework.BundleContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ */
+public final class NetconfConnectorModule extends org.opendaylight.controller.config.yang.md.sal.connector.netconf.AbstractNetconfConnectorModule
+{
+    private static final Logger LOG = LoggerFactory.getLogger(NetconfConnectorModule.class);
+
+    private BundleContext bundleContext;
+    private Optional<NetconfSessionPreferences> userCapabilities;
+    private SchemaSourceRegistry schemaRegistry;
+    private SchemaContextFactory schemaContextFactory;
+
+    public NetconfConnectorModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier, final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+        super(identifier, dependencyResolver);
+    }
+
+    public NetconfConnectorModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier, final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, final NetconfConnectorModule oldModule, final java.lang.AutoCloseable oldInstance) {
+        super(identifier, dependencyResolver, oldModule, oldInstance);
+    }
+
+    @Override
+    protected void customValidation() {
+        checkNotNull(getAddress(), addressJmxAttribute);
+        checkCondition(isHostAddressPresent(getAddress()), "Host address not present in " + getAddress(), addressJmxAttribute);
+        checkNotNull(getPort(), portJmxAttribute);
+        checkNotNull(getDomRegistry(), portJmxAttribute);
+        checkNotNull(getDomRegistry(), domRegistryJmxAttribute);
+
+        checkNotNull(getConnectionTimeoutMillis(), connectionTimeoutMillisJmxAttribute);
+        checkCondition(getConnectionTimeoutMillis() > 0, "must be > 0", connectionTimeoutMillisJmxAttribute);
+
+        checkNotNull(getConnectionTimeoutMillis(), defaultRequestTimeoutMillisJmxAttribute);
+        checkCondition(getConnectionTimeoutMillis() > 0, "must be > 0", defaultRequestTimeoutMillisJmxAttribute);
+
+        checkNotNull(getBetweenAttemptsTimeoutMillis(), betweenAttemptsTimeoutMillisJmxAttribute);
+        checkCondition(getBetweenAttemptsTimeoutMillis() > 0, "must be > 0", betweenAttemptsTimeoutMillisJmxAttribute);
+
+        checkNotNull(getClientDispatcher(), clientDispatcherJmxAttribute);
+        checkNotNull(getBindingRegistry(), bindingRegistryJmxAttribute);
+        checkNotNull(getProcessingExecutor(), processingExecutorJmxAttribute);
+
+        // Check username + password in case of ssh
+        if(getTcpOnly() == false) {
+            checkNotNull(getUsername(), usernameJmxAttribute);
+            checkNotNull(getPassword(), passwordJmxAttribute);
+        }
+
+        userCapabilities = getUserCapabilities();
+
+        if(getKeepaliveExecutor() == null) {
+            LOG.warn("Keepalive executor missing. Using default instance for now, the configuration needs to be updated");
+
+            // Instantiate the default executor, now we know its necessary
+            if(DEFAULT_KEEPALIVE_EXECUTOR == null) {
+                DEFAULT_KEEPALIVE_EXECUTOR = Executors.newScheduledThreadPool(2, new ThreadFactory() {
+                    @Override
+                    public Thread newThread(final Runnable r) {
+                        final Thread thread = new Thread(r);
+                        thread.setName("netconf-southound-keepalives-" + thread.getId());
+                        thread.setDaemon(true);
+                        return thread;
+                    }
+                });
+            }
+        }
+    }
+
+    private boolean isHostAddressPresent(final Host address) {
+        return address.getDomainName() != null ||
+               address.getIpAddress() != null && (address.getIpAddress().getIpv4Address() != null || address.getIpAddress().getIpv6Address() != null);
+    }
+
+    @Deprecated
+    private static ScheduledExecutorService DEFAULT_KEEPALIVE_EXECUTOR;
+
+    @Override
+    public java.lang.AutoCloseable createInstance() {
+        final RemoteDeviceId id = new RemoteDeviceId(getIdentifier(), getSocketAddress());
+
+        final ExecutorService globalProcessingExecutor = getProcessingExecutorDependency().getExecutor();
+
+        final Broker domBroker = getDomRegistryDependency();
+        final BindingAwareBroker bindingBroker = getBindingRegistryDependency();
+
+        RemoteDeviceHandler<NetconfSessionPreferences> salFacade
+                = new NetconfDeviceSalFacade(id, domBroker, bindingBroker, getDefaultRequestTimeoutMillis());
+
+        final Long keepaliveDelay = getKeepaliveDelay();
+        if(shouldSendKeepalive()) {
+            // Keepalive executor is optional for now and a default instance is supported
+            final ScheduledExecutorService executor = getKeepaliveExecutor() == null ?
+                    DEFAULT_KEEPALIVE_EXECUTOR : getKeepaliveExecutorDependency().getExecutor();
+            salFacade = new KeepaliveSalFacade(id, salFacade, executor, keepaliveDelay);
+        }
+
+        final NetconfDevice.SchemaResourcesDTO schemaResourcesDTO =
+                new NetconfDevice.SchemaResourcesDTO(schemaRegistry, schemaContextFactory, new NetconfStateSchemas.NetconfStateSchemasResolverImpl());
+
+        final NetconfDevice device =
+                new NetconfDevice(schemaResourcesDTO, id, salFacade, globalProcessingExecutor, getReconnectOnChangedSchema());
+
+        final NetconfDeviceCommunicator listener = userCapabilities.isPresent() ?
+                new NetconfDeviceCommunicator(id, device, userCapabilities.get()) : new NetconfDeviceCommunicator(id, device);
+
+        if(shouldSendKeepalive()) {
+            ((KeepaliveSalFacade) salFacade).setListener(listener);
+        }
+
+        final NetconfReconnectingClientConfiguration clientConfig = getClientConfig(listener);
+        final NetconfClientDispatcher dispatcher = getClientDispatcherDependency();
+
+        listener.initializeRemoteConnection(dispatcher, clientConfig);
+
+        return new SalConnectorCloseable(listener, salFacade);
+    }
+
+    private boolean shouldSendKeepalive() {
+        return getKeepaliveDelay() > 0;
+    }
+
+    private Optional<NetconfSessionPreferences> getUserCapabilities() {
+        if(getYangModuleCapabilities() == null) {
+            return Optional.absent();
+        }
+
+        final List<String> capabilities = getYangModuleCapabilities().getCapability();
+        if(capabilities == null || capabilities.isEmpty()) {
+            return Optional.absent();
+        }
+
+        final NetconfSessionPreferences parsedOverrideCapabilities = NetconfSessionPreferences.fromStrings(capabilities);
+        JmxAttributeValidationException.checkCondition(
+                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(),
+                yangModuleCapabilitiesJmxAttribute);
+
+        return Optional.of(parsedOverrideCapabilities);
+    }
+
+    public NetconfReconnectingClientConfiguration getClientConfig(final NetconfDeviceCommunicator listener) {
+        final InetSocketAddress socketAddress = getSocketAddress();
+        final long clientConnectionTimeoutMillis = getConnectionTimeoutMillis();
+
+        final ReconnectStrategyFactory sf = new TimedReconnectStrategyFactory(
+            getEventExecutorDependency(), getMaxConnectionAttempts(), getBetweenAttemptsTimeoutMillis(), getSleepFactor());
+        final ReconnectStrategy strategy = sf.createReconnectStrategy();
+
+        return NetconfReconnectingClientConfigurationBuilder.create()
+        .withAddress(socketAddress)
+        .withConnectionTimeoutMillis(clientConnectionTimeoutMillis)
+        .withReconnectStrategy(strategy)
+        .withAuthHandler(new LoginPassword(getUsername(), getPassword()))
+        .withProtocol(getTcpOnly() ?
+                NetconfClientConfiguration.NetconfClientProtocol.TCP :
+                NetconfClientConfiguration.NetconfClientProtocol.SSH)
+        .withConnectStrategyFactory(sf)
+        .withSessionListener(listener)
+        .build();
+    }
+
+    private static final class SalConnectorCloseable implements AutoCloseable {
+        private final RemoteDeviceHandler<NetconfSessionPreferences> salFacade;
+        private final NetconfDeviceCommunicator listener;
+
+        public SalConnectorCloseable(final NetconfDeviceCommunicator listener,
+                                     final RemoteDeviceHandler<NetconfSessionPreferences> salFacade) {
+            this.listener = listener;
+            this.salFacade = salFacade;
+        }
+
+        @Override
+        public void close() {
+            listener.close();
+            salFacade.close();
+        }
+    }
+
+    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 {
+                LOG.trace("Setting {} on {} to infinity", maxConnectionAttemptsJmxAttribute, this);
+                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);
+        }
+    }
+
+    private InetSocketAddress getSocketAddress() {
+        if(getAddress().getDomainName() != null) {
+            return new InetSocketAddress(getAddress().getDomainName().getValue(), getPort().getValue());
+        } else {
+            final IpAddress ipAddress = getAddress().getIpAddress();
+            final String ip = ipAddress.getIpv4Address() != null ? ipAddress.getIpv4Address().getValue() : ipAddress.getIpv6Address().getValue();
+            return new InetSocketAddress(ip, getPort().getValue());
+        }
+    }
+
+    public void setSchemaRegistry(final SchemaSourceRegistry schemaRegistry) {
+        this.schemaRegistry = schemaRegistry;
+    }
+
+    public void setSchemaContextFactory(final SchemaContextFactory schemaContextFactory) {
+        this.schemaContextFactory = schemaContextFactory;
+    }
+}
diff --git a/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/connector/netconf/NetconfConnectorModuleFactory.java b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/connector/netconf/NetconfConnectorModuleFactory.java
new file mode 100644 (file)
index 0000000..afae0c8
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.config.yang.md.sal.connector.netconf;
+
+import java.io.File;
+
+import org.opendaylight.controller.config.api.DependencyResolver;
+import org.opendaylight.controller.config.api.DynamicMBeanWithInstance;
+import org.opendaylight.controller.config.spi.Module;
+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 org.opendaylight.yangtools.yang.parser.util.TextToASTTransformer;
+import org.osgi.framework.BundleContext;
+
+/**
+*
+*/
+public class NetconfConnectorModuleFactory extends
+        org.opendaylight.controller.config.yang.md.sal.connector.netconf.AbstractNetconfConnectorModuleFactory {
+
+    // TODO this should be injected
+    // Netconf devices have separated schema registry + factory from controller
+    private final SharedSchemaRepository repository = new SharedSchemaRepository(NAME);
+    private final SchemaContextFactory schemaContextFactory
+            = repository.createSchemaContextFactory(SchemaSourceFilter.ALWAYS_ACCEPT);
+
+    public NetconfConnectorModuleFactory() {
+        // Start cache and Text to AST transformer
+        final FilesystemSchemaSourceCache<YangTextSchemaSource> cache = new FilesystemSchemaSourceCache<>(repository, YangTextSchemaSource.class, new File("cache/schema"));
+        repository.registerSchemaSourceListener(cache);
+        repository.registerSchemaSourceListener(TextToASTTransformer.create(repository, repository));
+    }
+
+    @Override
+    public Module createModule(final String instanceName, final DependencyResolver dependencyResolver,
+            final DynamicMBeanWithInstance old, final BundleContext bundleContext) throws Exception {
+        final NetconfConnectorModule module = (NetconfConnectorModule) super.createModule(instanceName, dependencyResolver,
+                old, bundleContext);
+
+        module.setSchemaRegistry(repository);
+        module.setSchemaContextFactory(schemaContextFactory);
+        return module;
+    }
+
+    @Override
+    public Module createModule(final String instanceName, final DependencyResolver dependencyResolver, final BundleContext bundleContext) {
+        final NetconfConnectorModule module = (NetconfConnectorModule) super.createModule(instanceName, dependencyResolver,
+                bundleContext);
+        module.setSchemaRegistry(repository);
+        module.setSchemaContextFactory(schemaContextFactory);
+        return module;
+    }
+}
diff --git a/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/api/MessageTransformer.java b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/api/MessageTransformer.java
new file mode 100644 (file)
index 0000000..861aaa4
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.connect.api;
+
+import org.opendaylight.controller.md.sal.dom.api.DOMNotification;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+
+public interface MessageTransformer<M> {
+
+    DOMNotification toNotification(M message);
+
+    M toRpcRequest(SchemaPath rpc, NormalizedNode<?, ?> node);
+
+    DOMRpcResult toRpcResult(M message, SchemaPath rpc);
+
+}
diff --git a/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/api/RemoteDevice.java b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/api/RemoteDevice.java
new file mode 100644 (file)
index 0000000..ca12e59
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.connect.api;
+
+/**
+ *
+ */
+public interface RemoteDevice<PREF, M, LISTENER extends RemoteDeviceCommunicator<M>> {
+
+    void onRemoteSessionUp(PREF remoteSessionCapabilities, LISTENER listener);
+
+    void onRemoteSessionDown();
+
+    void onRemoteSessionFailed(Throwable throwable);
+
+    void onNotification(M notification);
+}
diff --git a/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/api/RemoteDeviceCommunicator.java b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/api/RemoteDeviceCommunicator.java
new file mode 100644 (file)
index 0000000..4d2f284
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.connect.api;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+
+public interface RemoteDeviceCommunicator<M> extends AutoCloseable {
+
+    ListenableFuture<RpcResult<M>> sendRequest(M message, QName rpc);
+
+    void close();
+}
diff --git a/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/api/RemoteDeviceHandler.java b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/api/RemoteDeviceHandler.java
new file mode 100644 (file)
index 0000000..07c5fcb
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.connect.api;
+
+import org.opendaylight.controller.md.sal.dom.api.DOMNotification;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+public interface RemoteDeviceHandler<PREF> extends AutoCloseable {
+
+    void onDeviceConnected(SchemaContext remoteSchemaContext,
+                           PREF netconfSessionPreferences, DOMRpcService deviceRpc);
+
+    void onDeviceDisconnected();
+
+    void onDeviceFailed(Throwable throwable);
+
+    void onNotification(DOMNotification domNotification);
+
+    void close();
+}
diff --git a/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/api/SchemaContextProviderFactory.java b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/api/SchemaContextProviderFactory.java
new file mode 100644 (file)
index 0000000..43577c3
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.connect.api;
+
+import java.io.InputStream;
+import java.util.Collection;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider;
+import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProvider;
+
+public interface SchemaContextProviderFactory {
+
+    SchemaContextProvider createContextProvider(Collection<QName> capabilities, SchemaSourceProvider<InputStream> sourceProvider);
+
+}
\ No newline at end of file
diff --git a/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/api/package-info.java b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/api/package-info.java
new file mode 100644 (file)
index 0000000..f8c8655
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2014, 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
+ */
+
+/**
+ * General API for remote connectors e.g. netconf connector
+ *
+ * TODO extract into separate bundle when another connector is implemented e.g. restconf connector
+ */
+package org.opendaylight.controller.sal.connect.api;
diff --git a/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDevice.java b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDevice.java
new file mode 100644 (file)
index 0000000..260ed80
--- /dev/null
@@ -0,0 +1,507 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.connect.netconf;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+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.ListeningExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import org.opendaylight.controller.md.sal.dom.api.DOMNotification;
+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.controller.netconf.api.NetconfMessage;
+import org.opendaylight.controller.sal.connect.api.MessageTransformer;
+import org.opendaylight.controller.sal.connect.api.RemoteDevice;
+import org.opendaylight.controller.sal.connect.api.RemoteDeviceCommunicator;
+import org.opendaylight.controller.sal.connect.api.RemoteDeviceHandler;
+import org.opendaylight.controller.sal.connect.netconf.listener.NetconfDeviceCapabilities;
+import org.opendaylight.controller.sal.connect.netconf.listener.NetconfDeviceCommunicator;
+import org.opendaylight.controller.sal.connect.netconf.listener.NetconfSessionPreferences;
+import org.opendaylight.controller.sal.connect.netconf.sal.NetconfDeviceRpc;
+import org.opendaylight.controller.sal.connect.netconf.schema.NetconfRemoteSchemaYangSourceProvider;
+import org.opendaylight.controller.sal.connect.netconf.schema.mapping.NetconfMessageTransformer;
+import org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil;
+import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.extension.rev131210.$YangModuleInfoImpl;
+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.fields.unavailable.capabilities.UnavailableCapability;
+import org.opendaylight.yangtools.sal.binding.generator.impl.ModuleInfoBackedContext;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.repo.api.MissingSchemaSourceException;
+import org.opendaylight.yangtools.yang.model.repo.api.SchemaContextFactory;
+import org.opendaylight.yangtools.yang.model.repo.api.SchemaResolutionException;
+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;
+
+/**
+ *  This is a mediator between NetconfDeviceCommunicator and NetconfDeviceSalFacade
+ */
+public final class NetconfDevice implements RemoteDevice<NetconfSessionPreferences, NetconfMessage, NetconfDeviceCommunicator> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(NetconfDevice.class);
+
+    /**
+     * Initial schema context contains schemas for netconf monitoring and netconf notifications
+     */
+    public static final SchemaContext INIT_SCHEMA_CTX;
+
+    static {
+        try {
+            final ModuleInfoBackedContext moduleInfoBackedContext = ModuleInfoBackedContext.create();
+            moduleInfoBackedContext.addModuleInfos(
+                    Lists.newArrayList(
+                            $YangModuleInfoImpl.getInstance(),
+                            org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.$YangModuleInfoImpl.getInstance(),
+                            org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.base._1._0.rev110601.$YangModuleInfoImpl.getInstance()));
+            INIT_SCHEMA_CTX = moduleInfoBackedContext.tryToCreateSchemaContext().get();
+        } catch (final RuntimeException e) {
+            LOG.error("Unable to prepare schema context for netconf initialization", e);
+            throw new ExceptionInInitializerError(e);
+        }
+    }
+
+    public static final Function<QName, SourceIdentifier> QNAME_TO_SOURCE_ID_FUNCTION = new Function<QName, SourceIdentifier>() {
+        @Override
+        public SourceIdentifier apply(final QName input) {
+            return new SourceIdentifier(input.getLocalName(), Optional.fromNullable(input.getFormattedRevision()));
+        }
+    };
+
+    private final RemoteDeviceId id;
+    private final boolean reconnectOnSchemasChange;
+
+    private final SchemaContextFactory schemaContextFactory;
+    private final RemoteDeviceHandler<NetconfSessionPreferences> salFacade;
+    private final ListeningExecutorService processingExecutor;
+    private final SchemaSourceRegistry schemaRegistry;
+    private final NetconfStateSchemas.NetconfStateSchemasResolver stateSchemasResolver;
+    private final NotificationHandler notificationHandler;
+    private final List<SchemaSourceRegistration<? extends SchemaSourceRepresentation>> sourceRegistrations = Lists.newArrayList();
+
+    // Message transformer is constructed once the schemas are available
+    private MessageTransformer<NetconfMessage> messageTransformer;
+
+    public NetconfDevice(final SchemaResourcesDTO schemaResourcesDTO, final RemoteDeviceId id, final RemoteDeviceHandler<NetconfSessionPreferences> salFacade,
+                         final ExecutorService globalProcessingExecutor) {
+        this(schemaResourcesDTO, id, salFacade, globalProcessingExecutor, false);
+    }
+
+    /**
+     * Create rpc implementation capable of handling RPC for monitoring and notifications even before the schemas of remote device are downloaded
+     */
+    static NetconfDeviceRpc getRpcForInitialization(final NetconfDeviceCommunicator listener) {
+        return new NetconfDeviceRpc(INIT_SCHEMA_CTX, listener, new NetconfMessageTransformer(INIT_SCHEMA_CTX, false));
+    }
+
+
+    // FIXME reduce parameters
+    public NetconfDevice(final SchemaResourcesDTO schemaResourcesDTO, final RemoteDeviceId id, final RemoteDeviceHandler<NetconfSessionPreferences> salFacade,
+                         final ExecutorService globalProcessingExecutor, final boolean reconnectOnSchemasChange) {
+        this.id = id;
+        this.reconnectOnSchemasChange = reconnectOnSchemasChange;
+        this.schemaRegistry = schemaResourcesDTO.getSchemaRegistry();
+        this.schemaContextFactory = schemaResourcesDTO.getSchemaContextFactory();
+        this.salFacade = salFacade;
+        this.stateSchemasResolver = schemaResourcesDTO.getStateSchemasResolver();
+        this.processingExecutor = MoreExecutors.listeningDecorator(globalProcessingExecutor);
+        this.notificationHandler = new NotificationHandler(salFacade, id);
+    }
+
+    @Override
+    public void onRemoteSessionUp(final NetconfSessionPreferences remoteSessionCapabilities,
+                                  final NetconfDeviceCommunicator listener) {
+        // SchemaContext setup has to be performed in a dedicated thread since
+        // we are in a netty thread in this method
+        // Yang models are being downloaded in this method and it would cause a
+        // deadlock if we used the netty thread
+        // http://netty.io/wiki/thread-model.html
+        LOG.debug("{}: Session to remote device established with {}", id, remoteSessionCapabilities);
+
+        final NetconfDeviceRpc initRpc = getRpcForInitialization(listener);
+        final DeviceSourcesResolver task = new DeviceSourcesResolver(remoteSessionCapabilities, id, stateSchemasResolver, initRpc);
+        final ListenableFuture<DeviceSources> sourceResolverFuture = processingExecutor.submit(task);
+
+        if (shouldListenOnSchemaChange(remoteSessionCapabilities)) {
+            registerToBaseNetconfStream(initRpc, listener);
+        }
+
+        final FutureCallback<DeviceSources> resolvedSourceCallback = new FutureCallback<DeviceSources>() {
+            @Override
+            public void onSuccess(final DeviceSources result) {
+                addProvidedSourcesToSchemaRegistry(initRpc, result);
+                setUpSchema(result);
+            }
+
+            private void setUpSchema(final DeviceSources result) {
+                processingExecutor.submit(new RecursiveSchemaSetup(result, remoteSessionCapabilities, listener));
+            }
+
+            @Override
+            public void onFailure(final Throwable t) {
+                LOG.warn("{}: Unexpected error resolving device sources: {}", id, t);
+                handleSalInitializationFailure(t, listener);
+            }
+        };
+
+        Futures.addCallback(sourceResolverFuture, resolvedSourceCallback);
+    }
+
+    private void registerToBaseNetconfStream(final NetconfDeviceRpc deviceRpc, final NetconfDeviceCommunicator listener) {
+       // TODO check whether the model describing create subscription is present in schema
+        // Perhaps add a default schema context to support create-subscription if the model was not provided (same as what we do for base netconf operations in transformer)
+        final CheckedFuture<DOMRpcResult, DOMRpcException> rpcResultListenableFuture =
+                deviceRpc.invokeRpc(NetconfMessageTransformUtil.toPath(NetconfMessageTransformUtil.CREATE_SUBSCRIPTION_RPC_QNAME), NetconfMessageTransformUtil.CREATE_SUBSCRIPTION_RPC_CONTENT);
+
+        final NotificationHandler.NotificationFilter filter = new NotificationHandler.NotificationFilter() {
+            @Override
+            public Optional<DOMNotification> filterNotification(final DOMNotification notification) {
+                if (isCapabilityChanged(notification)) {
+                    LOG.info("{}: Schemas change detected, reconnecting", id);
+                    // Only disconnect is enough, the reconnecting nature of the connector will take care of reconnecting
+                    listener.disconnect();
+                    return Optional.absent();
+                }
+                return Optional.of(notification);
+            }
+
+            private boolean isCapabilityChanged(final DOMNotification notification) {
+                return notification.getBody().getNodeType().equals(NetconfCapabilityChange.QNAME);
+            }
+        };
+
+        Futures.addCallback(rpcResultListenableFuture, new FutureCallback<DOMRpcResult>() {
+            @Override
+            public void onSuccess(final DOMRpcResult domRpcResult) {
+                notificationHandler.addNotificationFilter(filter);
+            }
+
+            @Override
+            public void onFailure(final Throwable t) {
+                LOG.warn("Unable to subscribe to base notification stream. Schemas will not be reloaded on the fly", t);
+            }
+        });
+    }
+
+    private boolean shouldListenOnSchemaChange(final NetconfSessionPreferences remoteSessionCapabilities) {
+        return remoteSessionCapabilities.isNotificationsSupported() && reconnectOnSchemasChange;
+    }
+
+    @VisibleForTesting
+    void handleSalInitializationSuccess(final SchemaContext result, final NetconfSessionPreferences remoteSessionCapabilities, final DOMRpcService deviceRpc) {
+        messageTransformer = new NetconfMessageTransformer(result, true);
+
+        updateTransformer(messageTransformer);
+        // salFacade.onDeviceConnected has to be called before the notification handler is initialized
+        salFacade.onDeviceConnected(result, remoteSessionCapabilities, deviceRpc);
+        notificationHandler.onRemoteSchemaUp(messageTransformer);
+
+        LOG.info("{}: Netconf connector initialized successfully", id);
+    }
+
+    private void handleSalInitializationFailure(final Throwable t, final RemoteDeviceCommunicator<NetconfMessage> listener) {
+        LOG.error("{}: Initialization in sal failed, disconnecting from device", id, t);
+        listener.close();
+        onRemoteSessionDown();
+        resetMessageTransformer();
+    }
+
+    /**
+     * Set the transformer to null as is in initial state
+     */
+    private void resetMessageTransformer() {
+        updateTransformer(null);
+    }
+
+    private void updateTransformer(final MessageTransformer<NetconfMessage> transformer) {
+        messageTransformer = transformer;
+    }
+
+    private void addProvidedSourcesToSchemaRegistry(final NetconfDeviceRpc deviceRpc, final DeviceSources deviceSources) {
+        final NetconfRemoteSchemaYangSourceProvider yangProvider = new NetconfRemoteSchemaYangSourceProvider(id, deviceRpc);
+        for (final SourceIdentifier sourceId : deviceSources.getProvidedSources()) {
+            sourceRegistrations.add(schemaRegistry.registerSchemaSource(yangProvider,
+                    PotentialSchemaSource.create(sourceId, YangTextSchemaSource.class, PotentialSchemaSource.Costs.REMOTE_IO.getValue())));
+        }
+    }
+
+    @Override
+    public void onRemoteSessionDown() {
+        notificationHandler.onRemoteSchemaDown();
+
+        salFacade.onDeviceDisconnected();
+        for (final SchemaSourceRegistration<? extends SchemaSourceRepresentation> sourceRegistration : sourceRegistrations) {
+            sourceRegistration.close();
+        }
+        resetMessageTransformer();
+    }
+
+    @Override
+    public void onRemoteSessionFailed(final Throwable throwable) {
+        salFacade.onDeviceFailed(throwable);
+    }
+
+    @Override
+    public void onNotification(final NetconfMessage notification) {
+        notificationHandler.handleNotification(notification);
+    }
+
+    /**
+     * Just a transfer object containing schema related dependencies. Injected in constructor.
+     */
+    public static class SchemaResourcesDTO {
+        private final SchemaSourceRegistry schemaRegistry;
+        private final SchemaContextFactory schemaContextFactory;
+        private final NetconfStateSchemas.NetconfStateSchemasResolver stateSchemasResolver;
+
+        public SchemaResourcesDTO(final SchemaSourceRegistry schemaRegistry, final SchemaContextFactory schemaContextFactory, final NetconfStateSchemas.NetconfStateSchemasResolver stateSchemasResolver) {
+            this.schemaRegistry = Preconditions.checkNotNull(schemaRegistry);
+            this.schemaContextFactory = Preconditions.checkNotNull(schemaContextFactory);
+            this.stateSchemasResolver = Preconditions.checkNotNull(stateSchemasResolver);
+        }
+
+        public SchemaSourceRegistry getSchemaRegistry() {
+            return schemaRegistry;
+        }
+
+        public SchemaContextFactory getSchemaContextFactory() {
+            return schemaContextFactory;
+        }
+
+        public NetconfStateSchemas.NetconfStateSchemasResolver getStateSchemasResolver() {
+            return stateSchemasResolver;
+        }
+    }
+
+    /**
+     * Schema building callable.
+     */
+    private static class DeviceSourcesResolver implements Callable<DeviceSources> {
+
+        private final NetconfDeviceRpc deviceRpc;
+        private final NetconfSessionPreferences remoteSessionCapabilities;
+        private final RemoteDeviceId id;
+        private final NetconfStateSchemas.NetconfStateSchemasResolver stateSchemasResolver;
+
+        DeviceSourcesResolver(final NetconfDeviceRpc deviceRpc, final NetconfSessionPreferences remoteSessionCapabilities,
+                                     final RemoteDeviceId id, final NetconfStateSchemas.NetconfStateSchemasResolver stateSchemasResolver) {
+            this.deviceRpc = deviceRpc;
+            this.remoteSessionCapabilities = remoteSessionCapabilities;
+            this.id = id;
+            this.stateSchemasResolver = stateSchemasResolver;
+        }
+
+        public DeviceSourcesResolver(final NetconfSessionPreferences remoteSessionCapabilities, final RemoteDeviceId id, final NetconfStateSchemas.NetconfStateSchemasResolver stateSchemasResolver, final NetconfDeviceRpc rpcForMonitoring) {
+            this(rpcForMonitoring, remoteSessionCapabilities, id, stateSchemasResolver);
+        }
+
+        @Override
+        public DeviceSources call() throws Exception {
+            final NetconfStateSchemas availableSchemas = stateSchemasResolver.resolve(deviceRpc, remoteSessionCapabilities, id);
+            LOG.debug("{}: Schemas exposed by ietf-netconf-monitoring: {}", id, availableSchemas.getAvailableYangSchemasQNames());
+
+            final Set<QName> requiredSources = Sets.newHashSet(remoteSessionCapabilities.getModuleBasedCaps());
+            final Set<QName> providedSources = availableSchemas.getAvailableYangSchemasQNames();
+
+            final Set<QName> requiredSourcesNotProvided = Sets.difference(requiredSources, providedSources);
+            if (!requiredSourcesNotProvided.isEmpty()) {
+                LOG.warn("{}: Netconf device does not provide all yang models reported in hello message capabilities, required but not provided: {}",
+                        id, requiredSourcesNotProvided);
+                LOG.warn("{}: Attempting to build schema context from required sources", id);
+            }
+
+            // Here all the sources reported in netconf monitoring are merged with those reported in hello.
+            // It is necessary to perform this since submodules are not mentioned in hello but still required.
+            // This clashes with the option of a user to specify supported yang models manually in configuration for netconf-connector
+            // and as a result one is not able to fully override yang models of a device. It is only possible to add additional models.
+            final Set<QName> providedSourcesNotRequired = Sets.difference(providedSources, requiredSources);
+            if (!providedSourcesNotRequired.isEmpty()) {
+                LOG.warn("{}: Netconf device provides additional yang models not reported in hello message capabilities: {}",
+                        id, providedSourcesNotRequired);
+                LOG.warn("{}: Adding provided but not required sources as required to prevent failures", id);
+                LOG.debug("{}: Netconf device reported in hello: {}", id, requiredSources);
+                requiredSources.addAll(providedSourcesNotRequired);
+            }
+
+            return new DeviceSources(requiredSources, providedSources);
+        }
+    }
+
+    /**
+     * Contains RequiredSources - sources from capabilities.
+     */
+    private static final class DeviceSources {
+        private final Set<QName> requiredSources;
+        private final Set<QName> providedSources;
+
+        public DeviceSources(final Set<QName> requiredSources, final Set<QName> providedSources) {
+            this.requiredSources = requiredSources;
+            this.providedSources = providedSources;
+        }
+
+        public Set<QName> getRequiredSourcesQName() {
+            return requiredSources;
+        }
+
+        public Set<QName> getProvidedSourcesQName() {
+            return providedSources;
+        }
+
+        public Collection<SourceIdentifier> getRequiredSources() {
+            return Collections2.transform(requiredSources, QNAME_TO_SOURCE_ID_FUNCTION);
+        }
+
+        public Collection<SourceIdentifier> getProvidedSources() {
+            return Collections2.transform(providedSources, QNAME_TO_SOURCE_ID_FUNCTION);
+        }
+
+    }
+
+    /**
+     * Schema builder that tries to build schema context from provided sources or biggest subset of it.
+     */
+    private final class RecursiveSchemaSetup implements Runnable {
+        private final DeviceSources deviceSources;
+        private final NetconfSessionPreferences remoteSessionCapabilities;
+        private final RemoteDeviceCommunicator<NetconfMessage> listener;
+        private final NetconfDeviceCapabilities capabilities;
+
+        public RecursiveSchemaSetup(final DeviceSources deviceSources, final NetconfSessionPreferences remoteSessionCapabilities, final RemoteDeviceCommunicator<NetconfMessage> listener) {
+            this.deviceSources = deviceSources;
+            this.remoteSessionCapabilities = remoteSessionCapabilities;
+            this.listener = listener;
+            this.capabilities = remoteSessionCapabilities.getNetconfDeviceCapabilities();
+        }
+
+        @Override
+        public void run() {
+            setUpSchema(deviceSources.getRequiredSources());
+        }
+
+        /**
+         * Recursively build schema context, in case of success or final failure notify device
+         */
+        // FIXME reimplement without recursion
+        private void setUpSchema(final Collection<SourceIdentifier> requiredSources) {
+            LOG.trace("{}: Trying to build schema context from {}", id, requiredSources);
+
+            // If no more sources, fail
+            if(requiredSources.isEmpty()) {
+                final IllegalStateException cause = new IllegalStateException(id + ": No more sources for schema context");
+                handleSalInitializationFailure(cause, listener);
+                salFacade.onDeviceFailed(cause);
+                return;
+            }
+
+            final CheckedFuture<SchemaContext, SchemaResolutionException> schemaBuilderFuture = schemaContextFactory.createSchemaContext(requiredSources);
+
+            final FutureCallback<SchemaContext> RecursiveSchemaBuilderCallback = new FutureCallback<SchemaContext>() {
+
+                @Override
+                public void onSuccess(final SchemaContext result) {
+                    LOG.debug("{}: Schema context built successfully from {}", id, requiredSources);
+                    final Collection<QName> filteredQNames = Sets.difference(deviceSources.getProvidedSourcesQName(), capabilities.getUnresolvedCapabilites().keySet());
+                    capabilities.addCapabilities(filteredQNames);
+                    capabilities.addNonModuleBasedCapabilities(remoteSessionCapabilities.getNonModuleCaps());
+                    handleSalInitializationSuccess(result, remoteSessionCapabilities, getDeviceSpecificRpc(result));
+                }
+
+                @Override
+                public void onFailure(final Throwable t) {
+                    // In case source missing, try without it
+                    if (t instanceof MissingSchemaSourceException) {
+                        final SourceIdentifier missingSource = ((MissingSchemaSourceException) t).getSourceId();
+                        LOG.warn("{}: Unable to build schema context, missing source {}, will reattempt without it", id, missingSource);
+                        capabilities.addUnresolvedCapabilities(getQNameFromSourceIdentifiers(Sets.newHashSet(missingSource)), UnavailableCapability.FailureReason.MissingSource);
+                        setUpSchema(stripMissingSource(requiredSources, missingSource));
+
+                    // In case resolution error, try only with resolved sources
+                    } else if (t instanceof SchemaResolutionException) {
+                        // TODO check for infinite loop
+                        final SchemaResolutionException resolutionException = (SchemaResolutionException) t;
+                        final Set<SourceIdentifier> unresolvedSources = resolutionException.getUnsatisfiedImports().keySet();
+                        capabilities.addUnresolvedCapabilities(getQNameFromSourceIdentifiers(unresolvedSources), UnavailableCapability.FailureReason.UnableToResolve);
+                        LOG.warn("{}: Unable to build schema context, unsatisfied imports {}, will reattempt with resolved only", id, resolutionException.getUnsatisfiedImports());
+                        setUpSchema(resolutionException.getResolvedSources());
+                    // unknown error, fail
+                    } else {
+                        handleSalInitializationFailure(t, listener);
+                    }
+                }
+            };
+
+            Futures.addCallback(schemaBuilderFuture, RecursiveSchemaBuilderCallback);
+        }
+
+        private NetconfDeviceRpc getDeviceSpecificRpc(final SchemaContext result) {
+            return new NetconfDeviceRpc(result, listener, new NetconfMessageTransformer(result, true));
+        }
+
+        private Collection<SourceIdentifier> stripMissingSource(final Collection<SourceIdentifier> requiredSources, final SourceIdentifier sIdToRemove) {
+            final LinkedList<SourceIdentifier> sourceIdentifiers = Lists.newLinkedList(requiredSources);
+            final boolean removed = sourceIdentifiers.remove(sIdToRemove);
+            Preconditions.checkState(removed, "{}: Trying to remove {} from {} failed", id, sIdToRemove, requiredSources);
+            return sourceIdentifiers;
+        }
+
+        private Collection<QName> getQNameFromSourceIdentifiers(final Collection<SourceIdentifier> identifiers) {
+            final Collection<QName> qNames = Collections2.transform(identifiers, new Function<SourceIdentifier, QName>() {
+                @Override
+                public QName apply(final SourceIdentifier sourceIdentifier) {
+                    return getQNameFromSourceIdentifier(sourceIdentifier);
+                }
+            });
+
+            if (qNames.isEmpty()) {
+                LOG.debug("{}: Unable to map any source identfiers to a capability reported by device : {}", id, identifiers);
+            }
+            return qNames;
+        }
+
+        private QName getQNameFromSourceIdentifier(final SourceIdentifier identifier) {
+            // Required sources are all required and provided merged in DeviceSourcesResolver
+            for (final QName qname : deviceSources.getRequiredSourcesQName()) {
+                if(qname.getLocalName().equals(identifier.getName()) == false) {
+                    continue;
+                }
+
+                if(identifier.getRevision().equals(SourceIdentifier.NOT_PRESENT_FORMATTED_REVISION) &&
+                        qname.getRevision() == null) {
+                    return qname;
+                }
+
+                if (qname.getFormattedRevision().equals(identifier.getRevision())) {
+                    return qname;
+                }
+            }
+            throw new IllegalArgumentException("Unable to map identifier to a devices reported capability: " + identifier + " Available: " + deviceSources.getRequiredSourcesQName());
+        }
+    }
+}
diff --git a/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfStateSchemas.java b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfStateSchemas.java
new file mode 100644 (file)
index 0000000..e2158ce
--- /dev/null
@@ -0,0 +1,277 @@
+/*
+ * Copyright (c) 2014, 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.sal.connect.netconf;
+
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_DATA_QNAME;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_GET_QNAME;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.toId;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.toPath;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.Sets;
+import java.net.URI;
+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.sal.connect.netconf.listener.NetconfSessionPreferences;
+import org.opendaylight.controller.sal.connect.netconf.sal.NetconfDeviceRpc;
+import org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil;
+import org.opendaylight.controller.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.Yang;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.Schemas;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.schemas.Schema;
+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.DataContainerChild;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
+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;
+import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Holds QNames for all yang modules reported by ietf-netconf-monitoring/state/schemas
+ */
+public final class NetconfStateSchemas {
+
+    private static final Logger LOG = LoggerFactory.getLogger(NetconfStateSchemas.class);
+
+    /**
+     * Factory for NetconfStateSchemas
+     */
+    public interface NetconfStateSchemasResolver {
+        NetconfStateSchemas resolve(final NetconfDeviceRpc deviceRpc, final NetconfSessionPreferences remoteSessionCapabilities, final RemoteDeviceId id);
+    }
+
+    /**
+     * Default implementation resolving schemas QNames from netconf-state
+     */
+    public static final class NetconfStateSchemasResolverImpl implements NetconfStateSchemasResolver {
+
+        @Override
+        public NetconfStateSchemas resolve(final NetconfDeviceRpc deviceRpc, final NetconfSessionPreferences remoteSessionCapabilities, final RemoteDeviceId id) {
+            return NetconfStateSchemas.create(deviceRpc, remoteSessionCapabilities, id);
+        }
+    }
+
+    public static final NetconfStateSchemas EMPTY = new NetconfStateSchemas(Collections.<RemoteYangSchema>emptySet());
+
+    private static final YangInstanceIdentifier STATE_SCHEMAS_IDENTIFIER =
+            YangInstanceIdentifier.builder().node(NetconfState.QNAME).node(Schemas.QNAME).build();
+
+    private static final ContainerNode GET_SCHEMAS_RPC;
+    static {
+        final DataContainerChild<?, ?> filter = NetconfMessageTransformUtil.toFilterStructure(STATE_SCHEMAS_IDENTIFIER, NetconfDevice.INIT_SCHEMA_CTX);
+        GET_SCHEMAS_RPC
+                = Builders.containerBuilder().withNodeIdentifier(toId(NETCONF_GET_QNAME)).withChild(filter).build();
+    }
+
+    private final Set<RemoteYangSchema> availableYangSchemas;
+
+    public NetconfStateSchemas(final Set<RemoteYangSchema> availableYangSchemas) {
+        this.availableYangSchemas = availableYangSchemas;
+    }
+
+    public Set<RemoteYangSchema> getAvailableYangSchemas() {
+        return availableYangSchemas;
+    }
+
+    public Set<QName> getAvailableYangSchemasQNames() {
+        return Sets.newHashSet(Collections2.transform(getAvailableYangSchemas(), new Function<RemoteYangSchema, QName>() {
+            @Override
+            public QName apply(final RemoteYangSchema input) {
+                return input.getQName();
+            }
+        }));
+    }
+
+    /**
+     * Issue get request to remote device and parse response to find all schemas under netconf-state/schemas
+     */
+    private static NetconfStateSchemas create(final NetconfDeviceRpc deviceRpc, final NetconfSessionPreferences remoteSessionCapabilities, final RemoteDeviceId id) {
+        if(remoteSessionCapabilities.isMonitoringSupported() == false) {
+            LOG.warn("{}: Netconf monitoring not supported on device, cannot detect provided schemas", id);
+            return EMPTY;
+        }
+
+        final DOMRpcResult schemasNodeResult;
+        try {
+            schemasNodeResult = deviceRpc.invokeRpc(toPath(NETCONF_GET_QNAME), GET_SCHEMAS_RPC).get();
+        } catch (final InterruptedException e) {
+            Thread.currentThread().interrupt();
+            throw new RuntimeException(id + ": Interrupted while waiting for response to " + STATE_SCHEMAS_IDENTIFIER, e);
+        } catch (final ExecutionException e) {
+            LOG.warn("{}: Unable to detect available schemas, get to {} failed", id, STATE_SCHEMAS_IDENTIFIER, e);
+            return EMPTY;
+        }
+
+        if(schemasNodeResult.getErrors().isEmpty() == false) {
+            LOG.warn("{}: Unable to detect available schemas, get to {} failed, {}", id, STATE_SCHEMAS_IDENTIFIER, schemasNodeResult.getErrors());
+            return EMPTY;
+        }
+
+        final Optional<? extends NormalizedNode<?, ?>> schemasNode = findSchemasNode(schemasNodeResult.getResult());
+
+        if(schemasNode.isPresent()) {
+            Preconditions.checkState(schemasNode.get() instanceof ContainerNode,
+                    "Expecting container containing schemas, but was %s", schemasNode.get());
+            return create(id, ((ContainerNode) schemasNode.get()));
+        } else {
+            LOG.warn("{}: Unable to detect available schemas, get to {} was empty", id, STATE_SCHEMAS_IDENTIFIER);
+            return EMPTY;
+        }
+    }
+
+    private static Optional<? extends NormalizedNode<?, ?>> findSchemasNode(final NormalizedNode<?, ?> result) {
+        if(result == null) {
+            return Optional.absent();
+        }
+        final Optional<DataContainerChild<?, ?>> dataNode = ((DataContainerNode<?>) result).getChild(toId(NETCONF_DATA_QNAME));
+        if(dataNode.isPresent() == false) {
+            return Optional.absent();
+        }
+
+        final Optional<DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?>> nStateNode =
+                ((DataContainerNode<?>) dataNode.get()).getChild(toId(NetconfState.QNAME));
+        if(nStateNode.isPresent() == false) {
+            return Optional.absent();
+        }
+
+        return ((DataContainerNode<?>) nStateNode.get()).getChild(toId(Schemas.QNAME));
+    }
+
+    /**
+     * Parse response of get(netconf-state/schemas) to find all schemas under netconf-state/schemas
+     */
+    @VisibleForTesting
+    protected static NetconfStateSchemas create(final RemoteDeviceId id, final ContainerNode schemasNode) {
+        final Set<RemoteYangSchema> availableYangSchemas = Sets.newHashSet();
+
+        final Optional<DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?>> child = schemasNode.getChild(toId(Schema.QNAME));
+        Preconditions.checkState(child.isPresent(), "Unable to find list: %s in response: %s", Schema.QNAME.withoutRevision(), schemasNode);
+        Preconditions.checkState(child.get() instanceof MapNode, "Unexpected structure for container: %s in response: %s. Expecting a list", Schema.QNAME.withoutRevision(), schemasNode);
+
+        for (final MapEntryNode schemaNode : ((MapNode) child.get()).getValue()) {
+            final Optional<RemoteYangSchema> fromCompositeNode = RemoteYangSchema.createFromNormalizedNode(id, schemaNode);
+            if(fromCompositeNode.isPresent()) {
+                availableYangSchemas.add(fromCompositeNode.get());
+            }
+        }
+
+        return new NetconfStateSchemas(availableYangSchemas);
+    }
+
+    public final static class RemoteYangSchema {
+        private final QName qname;
+
+        RemoteYangSchema(final QName qname) {
+            this.qname = qname;
+        }
+
+        public QName getQName() {
+            return qname;
+        }
+
+        static Optional<RemoteYangSchema> createFromNormalizedNode(final RemoteDeviceId id, final MapEntryNode schemaNode) {
+            Preconditions.checkArgument(schemaNode.getNodeType().equals(Schema.QNAME), "Wrong QName %s", schemaNode.getNodeType());
+
+            QName childNode = NetconfMessageTransformUtil.IETF_NETCONF_MONITORING_SCHEMA_FORMAT;
+
+            String formatAsString = getSingleChildNodeValue(schemaNode, childNode).get();
+
+            if(formatAsString.equals(Yang.QNAME.toString()) == false) {
+                LOG.debug("{}: Ignoring schema due to unsupported format: {}", id, formatAsString);
+                return Optional.absent();
+            }
+
+            childNode = NetconfMessageTransformUtil.IETF_NETCONF_MONITORING_SCHEMA_LOCATION;
+            final Set<String> locationsAsString = getAllChildNodeValues(schemaNode, childNode);
+            if(locationsAsString.contains(Schema.Location.Enumeration.NETCONF.toString()) == false) {
+                LOG.debug("{}: Ignoring schema due to unsupported location: {}", id, locationsAsString);
+                return Optional.absent();
+            }
+
+            childNode = NetconfMessageTransformUtil.IETF_NETCONF_MONITORING_SCHEMA_NAMESPACE;
+            final String namespaceAsString = getSingleChildNodeValue(schemaNode, childNode).get();
+
+            childNode = NetconfMessageTransformUtil.IETF_NETCONF_MONITORING_SCHEMA_VERSION;
+            // Revision does not have to be filled
+            final Optional<String> revisionAsString = getSingleChildNodeValue(schemaNode, childNode);
+
+            childNode = NetconfMessageTransformUtil.IETF_NETCONF_MONITORING_SCHEMA_IDENTIFIER;
+            final String moduleNameAsString = getSingleChildNodeValue(schemaNode, childNode).get();
+
+            final QName moduleQName = revisionAsString.isPresent()
+                    ? QName.create(namespaceAsString, revisionAsString.get(), moduleNameAsString)
+                    : QName.create(URI.create(namespaceAsString), null, moduleNameAsString);
+
+            return Optional.of(new RemoteYangSchema(moduleQName));
+        }
+
+        /**
+         * Extracts all values of a leaf-list node as a set of strings
+         */
+        private static Set<String> getAllChildNodeValues(final DataContainerNode<?> schemaNode, final QName childNodeQName) {
+            final Set<String> extractedValues = Sets.newHashSet();
+            final Optional<DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?>> child = schemaNode.getChild(toId(childNodeQName));
+            Preconditions.checkArgument(child.isPresent(), "Child nodes %s not present", childNodeQName);
+            Preconditions.checkArgument(child.get() instanceof LeafSetNode<?>, "Child nodes %s not present", childNodeQName);
+            for (final LeafSetEntryNode<?> childNode : ((LeafSetNode<?>) child.get()).getValue()) {
+                extractedValues.add(getValueOfSimpleNode(childNode).get());
+            }
+            return extractedValues;
+        }
+
+        private static Optional<String> getSingleChildNodeValue(final DataContainerNode<?> schemaNode, final QName childNode) {
+            final Optional<DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?>> node = schemaNode.getChild(toId(childNode));
+            Preconditions.checkArgument(node.isPresent(), "Child node %s not present", childNode);
+            return getValueOfSimpleNode(node.get());
+        }
+
+        private static Optional<String> getValueOfSimpleNode(final NormalizedNode<? extends YangInstanceIdentifier.PathArgument, ?> node) {
+            final Object value = node.getValue();
+            return value == null || Strings.isNullOrEmpty(value.toString()) ? Optional.<String>absent() : Optional.of(value.toString().trim());
+        }
+
+        @Override
+        public boolean equals(final Object o) {
+            if (this == o) {
+                return true;
+            }
+            if (o == null || getClass() != o.getClass()) {
+                return false;
+            }
+
+            final RemoteYangSchema that = (RemoteYangSchema) o;
+
+            if (!qname.equals(that.qname)) {
+                return false;
+            }
+
+            return true;
+        }
+
+        @Override
+        public int hashCode() {
+            return qname.hashCode();
+        }
+    }
+}
diff --git a/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NotificationHandler.java b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NotificationHandler.java
new file mode 100644 (file)
index 0000000..6a0d898
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.connect.netconf;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import java.util.LinkedList;
+import java.util.List;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
+import org.opendaylight.controller.md.sal.dom.api.DOMNotification;
+import org.opendaylight.controller.netconf.api.NetconfMessage;
+import org.opendaylight.controller.sal.connect.api.MessageTransformer;
+import org.opendaylight.controller.sal.connect.api.RemoteDeviceHandler;
+import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Handles incoming notifications. Either caches them(until onRemoteSchemaUp is called) or passes to sal Facade.
+ */
+final class NotificationHandler {
+
+    private static final Logger LOG = LoggerFactory.getLogger(NotificationHandler.class);
+
+    private final RemoteDeviceHandler<?> salFacade;
+    private final List<NetconfMessage> queue = new LinkedList<>();
+    private final RemoteDeviceId id;
+    private boolean passNotifications = false;
+
+    private NotificationFilter filter;
+    private MessageTransformer<NetconfMessage> messageTransformer;
+
+    NotificationHandler(final RemoteDeviceHandler<?> salFacade, final RemoteDeviceId id) {
+        this.salFacade = Preconditions.checkNotNull(salFacade);
+        this.id = Preconditions.checkNotNull(id);
+    }
+
+    synchronized void handleNotification(final NetconfMessage notification) {
+        if(passNotifications) {
+            passNotification(transformNotification(notification));
+        } else {
+            queueNotification(notification);
+        }
+    }
+
+    /**
+     * Forward all cached notifications and pass all notifications from this point directly to sal facade.
+     * @param messageTransformer
+     */
+    synchronized void onRemoteSchemaUp(final MessageTransformer<NetconfMessage> messageTransformer) {
+        this.messageTransformer = Preconditions.checkNotNull(messageTransformer);
+
+        passNotifications = true;
+
+        for (final NetconfMessage cachedNotification : queue) {
+            passNotification(transformNotification(cachedNotification));
+        }
+
+        queue.clear();
+    }
+
+    private DOMNotification transformNotification(final NetconfMessage cachedNotification) {
+        final DOMNotification parsedNotification = messageTransformer.toNotification(cachedNotification);
+        Preconditions.checkNotNull(parsedNotification, "%s: Unable to parse received notification: %s", id, cachedNotification);
+        return parsedNotification;
+    }
+
+    private void queueNotification(final NetconfMessage notification) {
+        Preconditions.checkState(passNotifications == false);
+
+        LOG.debug("{}: Caching notification {}, remote schema not yet fully built", id, notification);
+        if(LOG.isTraceEnabled()) {
+            LOG.trace("{}: Caching notification {}", id, XmlUtil.toString(notification.getDocument()));
+        }
+
+        queue.add(notification);
+    }
+
+    private synchronized void passNotification(final DOMNotification parsedNotification) {
+        LOG.debug("{}: Forwarding notification {}", id, parsedNotification);
+
+        if(filter == null || filter.filterNotification(parsedNotification).isPresent()) {
+            salFacade.onNotification(parsedNotification);
+        }
+    }
+
+    synchronized void addNotificationFilter(final NotificationFilter filter) {
+        this.filter = filter;
+    }
+
+    synchronized void onRemoteSchemaDown() {
+        queue.clear();
+        passNotifications = false;
+        messageTransformer = null;
+    }
+
+    static interface NotificationFilter {
+
+        Optional<DOMNotification> filterNotification(DOMNotification notification);
+    }
+}
diff --git a/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/listener/NetconfDeviceCapabilities.java b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/listener/NetconfDeviceCapabilities.java
new file mode 100644 (file)
index 0000000..8f30a5c
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * 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.sal.connect.netconf.listener;
+
+import java.util.Collection;
+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.fields.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;
+
+    public NetconfDeviceCapabilities() {
+        this.unresolvedCapabilites = new HashMap<>();
+        this.resolvedCapabilities = new HashSet<>();
+        this.nonModuleBasedCapabilities = new HashSet<>();
+    }
+
+    public void addUnresolvedCapability(QName source, FailureReason reason) {
+        unresolvedCapabilites.put(source, reason);
+    }
+
+    public void addUnresolvedCapabilities(Collection<QName> capabilities, FailureReason reason) {
+        for (QName s : capabilities) {
+            unresolvedCapabilites.put(s, reason);
+        }
+    }
+
+    public void addCapabilities(Collection<QName> availableSchemas) {
+        resolvedCapabilities.addAll(availableSchemas);
+    }
+
+    public void addNonModuleBasedCapabilities(Collection<String> nonModuleCapabilities) {
+        this.nonModuleBasedCapabilities.addAll(nonModuleCapabilities);
+    }
+
+    public Set<String> getNonModuleBasedCapabilities() {
+        return nonModuleBasedCapabilities;
+    }
+
+    public Map<QName, FailureReason> getUnresolvedCapabilites() {
+        return unresolvedCapabilites;
+    }
+
+    public Set<QName> getResolvedCapabilities() {
+        return resolvedCapabilities;
+    }
+
+}
diff --git a/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/listener/NetconfDeviceCommunicator.java b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/listener/NetconfDeviceCommunicator.java
new file mode 100644 (file)
index 0000000..8ed845b
--- /dev/null
@@ -0,0 +1,357 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.connect.netconf.listener;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Strings;
+import com.google.common.collect.Lists;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import io.netty.util.concurrent.Future;
+import io.netty.util.concurrent.FutureListener;
+import io.netty.util.concurrent.GenericFutureListener;
+import java.util.ArrayDeque;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Queue;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+import org.opendaylight.controller.config.util.xml.XmlElement;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.netconf.api.NetconfMessage;
+import org.opendaylight.controller.netconf.api.NetconfTerminationReason;
+import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
+import org.opendaylight.controller.netconf.client.NetconfClientDispatcher;
+import org.opendaylight.controller.netconf.client.NetconfClientSession;
+import org.opendaylight.controller.netconf.client.NetconfClientSessionListener;
+import org.opendaylight.controller.netconf.client.conf.NetconfClientConfiguration;
+import org.opendaylight.controller.netconf.client.conf.NetconfReconnectingClientConfiguration;
+import org.opendaylight.controller.sal.connect.api.RemoteDevice;
+import org.opendaylight.controller.sal.connect.api.RemoteDeviceCommunicator;
+import org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil;
+import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.RpcError;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NetconfDeviceCommunicator implements NetconfClientSessionListener, RemoteDeviceCommunicator<NetconfMessage> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(NetconfDeviceCommunicator.class);
+
+    private final RemoteDevice<NetconfSessionPreferences, NetconfMessage, NetconfDeviceCommunicator> remoteDevice;
+    private final Optional<NetconfSessionPreferences> overrideNetconfCapabilities;
+    private final RemoteDeviceId id;
+    private final Lock sessionLock = new ReentrantLock();
+
+    // TODO implement concurrent message limit
+    private final Queue<Request> requests = new ArrayDeque<>();
+    private NetconfClientSession session;
+    private Future<?> initFuture;
+
+    public NetconfDeviceCommunicator(final RemoteDeviceId id, final RemoteDevice<NetconfSessionPreferences, NetconfMessage, NetconfDeviceCommunicator> remoteDevice,
+            final NetconfSessionPreferences NetconfSessionPreferences) {
+        this(id, remoteDevice, Optional.of(NetconfSessionPreferences));
+    }
+
+    public NetconfDeviceCommunicator(final RemoteDeviceId id,
+                                     final RemoteDevice<NetconfSessionPreferences, NetconfMessage, NetconfDeviceCommunicator> remoteDevice) {
+        this(id, remoteDevice, Optional.<NetconfSessionPreferences>absent());
+    }
+
+    private NetconfDeviceCommunicator(final RemoteDeviceId id, final RemoteDevice<NetconfSessionPreferences, NetconfMessage, NetconfDeviceCommunicator> remoteDevice,
+            final Optional<NetconfSessionPreferences> overrideNetconfCapabilities) {
+        this.id = id;
+        this.remoteDevice = remoteDevice;
+        this.overrideNetconfCapabilities = overrideNetconfCapabilities;
+    }
+
+    @Override
+    public void onSessionUp(final NetconfClientSession session) {
+        sessionLock.lock();
+        try {
+            LOG.debug("{}: Session established", id);
+            this.session = session;
+
+            NetconfSessionPreferences netconfSessionPreferences =
+                                             NetconfSessionPreferences.fromNetconfSession(session);
+            LOG.trace("{}: Session advertised capabilities: {}", id,
+                    netconfSessionPreferences);
+
+            if(overrideNetconfCapabilities.isPresent()) {
+                netconfSessionPreferences = netconfSessionPreferences.addModuleCaps(overrideNetconfCapabilities.get());
+                LOG.debug(
+                        "{}: Session capabilities overridden, capabilities that will be used: {}",
+                        id, netconfSessionPreferences);
+            }
+
+            remoteDevice.onRemoteSessionUp(netconfSessionPreferences, this);
+        }
+        finally {
+            sessionLock.unlock();
+        }
+    }
+
+    public void initializeRemoteConnection(final NetconfClientDispatcher dispatcher, final NetconfClientConfiguration config) {
+        // TODO 2313 extract listener from configuration
+        if(config instanceof NetconfReconnectingClientConfiguration) {
+            initFuture = dispatcher.createReconnectingClient((NetconfReconnectingClientConfiguration) config);
+        } else {
+            initFuture = dispatcher.createClient(config);
+        }
+
+
+        initFuture.addListener(new GenericFutureListener<Future<Object>>(){
+
+            @Override
+            public void operationComplete(Future<Object> future) throws Exception {
+                if (!future.isSuccess() && !future.isCancelled()) {
+                    LOG.debug("{}: Connection failed", id, future.cause());
+                    NetconfDeviceCommunicator.this.remoteDevice.onRemoteSessionFailed(future.cause());
+                }
+            }
+        });
+
+    }
+
+    public void disconnect() {
+        if(session != null) {
+            session.close();
+        }
+    }
+
+    private void tearDown( String reason ) {
+        List<UncancellableFuture<RpcResult<NetconfMessage>>> futuresToCancel = Lists.newArrayList();
+        sessionLock.lock();
+        try {
+            if( session != null ) {
+                session = null;
+
+                /*
+                 * Walk all requests, check if they have been executing
+                 * or cancelled and remove them from the queue.
+                 */
+                final Iterator<Request> it = requests.iterator();
+                while (it.hasNext()) {
+                    final Request r = it.next();
+                    if (r.future.isUncancellable()) {
+                        futuresToCancel.add( r.future );
+                        it.remove();
+                    } else if (r.future.isCancelled()) {
+                        // This just does some house-cleaning
+                        it.remove();
+                    }
+                }
+
+                remoteDevice.onRemoteSessionDown();
+            }
+        }
+        finally {
+            sessionLock.unlock();
+        }
+
+        // Notify pending request futures outside of the sessionLock to avoid unnecessarily
+        // blocking the caller.
+        for( UncancellableFuture<RpcResult<NetconfMessage>> future: futuresToCancel ) {
+            if( Strings.isNullOrEmpty( reason ) ) {
+                future.set( createSessionDownRpcResult() );
+            } else {
+                future.set( createErrorRpcResult( RpcError.ErrorType.TRANSPORT, reason ) );
+            }
+        }
+    }
+
+    private RpcResult<NetconfMessage> createSessionDownRpcResult() {
+        return createErrorRpcResult( RpcError.ErrorType.TRANSPORT,
+                             String.format( "The netconf session to %1$s is disconnected", id.getName() ) );
+    }
+
+    private RpcResult<NetconfMessage> createErrorRpcResult( RpcError.ErrorType errorType, String message ) {
+        return RpcResultBuilder.<NetconfMessage>failed()
+                .withError(errorType, NetconfDocumentedException.ErrorTag.operation_failed.getTagValue(), message).build();
+    }
+
+    @Override
+    public void onSessionDown(final NetconfClientSession session, final Exception e) {
+        LOG.warn("{}: Session went down", id, e);
+        tearDown( null );
+    }
+
+    @Override
+    public void onSessionTerminated(final NetconfClientSession session, final NetconfTerminationReason reason) {
+        LOG.warn("{}: Session terminated {}", id, reason);
+        tearDown( reason.getErrorMessage() );
+    }
+
+    @Override
+    public void close() {
+        // Cancel reconnect if in progress
+        if(initFuture != null) {
+            initFuture.cancel(false);
+        }
+        // Disconnect from device
+        if(session != null) {
+            session.close();
+            // tear down not necessary, called indirectly by above close
+        }
+    }
+
+    @Override
+    public void onMessage(final NetconfClientSession session, final NetconfMessage message) {
+        /*
+         * Dispatch between notifications and messages. Messages need to be processed
+         * with lock held, notifications do not.
+         */
+        if (isNotification(message)) {
+            processNotification(message);
+        } else {
+            processMessage(message);
+        }
+    }
+
+    private void processMessage(final NetconfMessage message) {
+        Request request = null;
+        sessionLock.lock();
+
+        try {
+            request = requests.peek();
+            if (request != null && request.future.isUncancellable()) {
+                requests.poll();
+            } else {
+                request = null;
+                LOG.warn("{}: Ignoring unsolicited message {}", id,
+                        msgToS(message));
+            }
+        }
+        finally {
+            sessionLock.unlock();
+        }
+
+        if( request != null ) {
+
+            LOG.debug("{}: Message received {}", id, message);
+
+            if(LOG.isTraceEnabled()) {
+                LOG.trace( "{}: Matched request: {} to response: {}", id, msgToS( request.request ), msgToS( message ) );
+            }
+
+            try {
+                NetconfMessageTransformUtil.checkValidReply( request.request, message );
+            } catch (final NetconfDocumentedException e) {
+                LOG.warn(
+                        "{}: Invalid request-reply match, reply message contains different message-id, request: {}, response: {}",
+                        id, msgToS(request.request), msgToS(message), e);
+
+                request.future.set( RpcResultBuilder.<NetconfMessage>failed()
+                        .withRpcError( NetconfMessageTransformUtil.toRpcError( e ) ).build() );
+
+                //recursively processing message to eventually find matching request
+                processMessage(message);
+
+                return;
+            }
+
+            try {
+                NetconfMessageTransformUtil.checkSuccessReply(message);
+            } catch(final NetconfDocumentedException e) {
+                LOG.warn(
+                        "{}: Error reply from remote device, request: {}, response: {}",
+                        id, msgToS(request.request), msgToS(message), e);
+
+                request.future.set( RpcResultBuilder.<NetconfMessage>failed()
+                        .withRpcError( NetconfMessageTransformUtil.toRpcError( e ) ).build() );
+                return;
+            }
+
+            request.future.set( RpcResultBuilder.success( message ).build() );
+        }
+    }
+
+    private static String msgToS(final NetconfMessage msg) {
+        return XmlUtil.toString(msg.getDocument());
+    }
+
+    @Override
+    public ListenableFuture<RpcResult<NetconfMessage>> sendRequest(final NetconfMessage message, final QName rpc) {
+        sessionLock.lock();
+        try {
+            return sendRequestWithLock( message, rpc );
+        } finally {
+            sessionLock.unlock();
+        }
+    }
+
+    private ListenableFuture<RpcResult<NetconfMessage>> sendRequestWithLock(
+                                               final NetconfMessage message, final QName rpc) {
+        if(LOG.isTraceEnabled()) {
+            LOG.trace("{}: Sending message {}", id, msgToS(message));
+        }
+
+        if (session == null) {
+            LOG.warn("{}: Session is disconnected, failing RPC request {}",
+                    id, message);
+            return Futures.immediateFuture( createSessionDownRpcResult() );
+        }
+
+        final Request req = new Request( new UncancellableFuture<RpcResult<NetconfMessage>>(true),
+                                         message );
+        requests.add(req);
+
+        session.sendMessage(req.request).addListener(new FutureListener<Void>() {
+            @Override
+            public void operationComplete(final Future<Void> future) throws Exception {
+                if( !future.isSuccess() ) {
+                    // We expect that a session down will occur at this point
+                    LOG.debug("{}: Failed to send request {}", id,
+                            XmlUtil.toString(req.request.getDocument()),
+                            future.cause());
+
+                    if( future.cause() != null ) {
+                        req.future.set( createErrorRpcResult( RpcError.ErrorType.TRANSPORT,
+                                                              future.cause().getLocalizedMessage() ) );
+                    } else {
+                        req.future.set( createSessionDownRpcResult() ); // assume session is down
+                    }
+                    req.future.setException( future.cause() );
+                }
+                else {
+                    LOG.trace("Finished sending request {}", req.request);
+                }
+            }
+        });
+
+        return req.future;
+    }
+
+    private void processNotification(final NetconfMessage notification) {
+        if(LOG.isTraceEnabled()) {
+            LOG.trace("{}: Notification received: {}", id, notification);
+        }
+
+        remoteDevice.onNotification(notification);
+    }
+
+    private static boolean isNotification(final NetconfMessage message) {
+        final XmlElement xmle = XmlElement.fromDomDocument(message.getDocument());
+        return XmlNetconfConstants.NOTIFICATION_ELEMENT_NAME.equals(xmle.getName()) ;
+    }
+
+    private static final class Request {
+        final UncancellableFuture<RpcResult<NetconfMessage>> future;
+        final NetconfMessage request;
+
+        private Request(final UncancellableFuture<RpcResult<NetconfMessage>> future,
+                        final NetconfMessage request) {
+            this.future = future;
+            this.request = request;
+        }
+    }
+}
diff --git a/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/listener/NetconfSessionPreferences.java b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/listener/NetconfSessionPreferences.java
new file mode 100644 (file)
index 0000000..7ff48e3
--- /dev/null
@@ -0,0 +1,205 @@
+/*
+ * 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.sal.connect.netconf.listener;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Predicate;
+import com.google.common.base.Splitter;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Sets;
+import java.net.URI;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+import org.opendaylight.controller.netconf.client.NetconfClientSession;
+import org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public final class NetconfSessionPreferences {
+
+    private static final class ParameterMatcher {
+        private final Predicate<String> predicate;
+        private final int skipLength;
+
+        ParameterMatcher(final String name) {
+            predicate = new Predicate<String>() {
+                @Override
+                public boolean apply(final String input) {
+                    return input.startsWith(name);
+                }
+            };
+
+            this.skipLength = name.length();
+        }
+
+        private String from(final Iterable<String> params) {
+            final Optional<String> o = Iterables.tryFind(params, predicate);
+            if (!o.isPresent()) {
+                return null;
+            }
+
+            return o.get().substring(skipLength);
+        }
+    }
+
+    private static final Logger LOG = LoggerFactory.getLogger(NetconfSessionPreferences.class);
+    private static final ParameterMatcher MODULE_PARAM = new ParameterMatcher("module=");
+    private static final ParameterMatcher REVISION_PARAM = new ParameterMatcher("revision=");
+    private static final ParameterMatcher BROKEN_REVISON_PARAM = new ParameterMatcher("amp;revision=");
+    private static final Splitter AMP_SPLITTER = Splitter.on('&');
+    private static final Predicate<String> CONTAINS_REVISION = new Predicate<String>() {
+        @Override
+        public boolean apply(final String input) {
+            return input.contains("revision=");
+        }
+    };
+
+    private final Set<QName> moduleBasedCaps;
+    private final Set<String> nonModuleCaps;
+
+    private NetconfSessionPreferences(final Set<String> nonModuleCaps, final Set<QName> moduleBasedCaps) {
+        this.nonModuleCaps = Preconditions.checkNotNull(nonModuleCaps);
+        this.moduleBasedCaps = Preconditions.checkNotNull(moduleBasedCaps);
+    }
+
+    public Set<QName> getModuleBasedCaps() {
+        return moduleBasedCaps;
+    }
+
+    public Set<String> getNonModuleCaps() {
+        return nonModuleCaps;
+    }
+
+    public boolean containsNonModuleCapability(final String capability) {
+        return nonModuleCaps.contains(capability);
+    }
+
+    public boolean containsModuleCapability(final QName capability) {
+        return moduleBasedCaps.contains(capability);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+                .add("capabilities", nonModuleCaps)
+                .add("moduleBasedCapabilities", moduleBasedCaps)
+                .add("rollback", isRollbackSupported())
+                .add("monitoring", isMonitoringSupported())
+                .add("candidate", isCandidateSupported())
+                .add("writableRunning", isRunningWritable())
+                .toString();
+    }
+
+    public boolean isRollbackSupported() {
+        return containsNonModuleCapability(NetconfMessageTransformUtil.NETCONF_ROLLBACK_ON_ERROR_URI.toString());
+    }
+
+    public boolean isCandidateSupported() {
+        return containsNonModuleCapability(NetconfMessageTransformUtil.NETCONF_CANDIDATE_URI.toString());
+    }
+
+    public boolean isRunningWritable() {
+        return containsNonModuleCapability(NetconfMessageTransformUtil.NETCONF_RUNNING_WRITABLE_URI.toString());
+    }
+
+    public boolean isNotificationsSupported() {
+        return containsNonModuleCapability(NetconfMessageTransformUtil.NETCONF_NOTIFICATONS_URI.toString())
+                || containsModuleCapability(NetconfMessageTransformUtil.IETF_NETCONF_NOTIFICATIONS);
+    }
+
+    public boolean isMonitoringSupported() {
+        return containsModuleCapability(NetconfMessageTransformUtil.IETF_NETCONF_MONITORING)
+                || containsNonModuleCapability(NetconfMessageTransformUtil.IETF_NETCONF_MONITORING.getNamespace().toString());
+    }
+
+    public NetconfSessionPreferences addModuleCaps(final NetconfSessionPreferences netconfSessionModuleCapabilities) {
+        final HashSet<QName> mergedCaps = Sets.newHashSetWithExpectedSize(moduleBasedCaps.size() + netconfSessionModuleCapabilities.getModuleBasedCaps().size());
+        mergedCaps.addAll(moduleBasedCaps);
+        mergedCaps.addAll(netconfSessionModuleCapabilities.getModuleBasedCaps());
+        return new NetconfSessionPreferences(getNonModuleCaps(), mergedCaps);
+    }
+
+    public static NetconfSessionPreferences fromNetconfSession(final NetconfClientSession session) {
+        return fromStrings(session.getServerCapabilities());
+    }
+
+    private static QName cachedQName(final String namespace, final String revision, final String moduleName) {
+        return QName.cachedReference(QName.create(namespace, revision, moduleName));
+    }
+
+    private static QName cachedQName(final String namespace, final String moduleName) {
+        return QName.cachedReference(QName.create(URI.create(namespace), null, moduleName).withoutRevision());
+    }
+
+    public static NetconfSessionPreferences fromStrings(final Collection<String> capabilities) {
+        final Set<QName> moduleBasedCaps = new HashSet<>();
+        final Set<String> nonModuleCaps = Sets.newHashSet(capabilities);
+
+        for (final String capability : capabilities) {
+            final int qmark = capability.indexOf('?');
+            if (qmark == -1) {
+                continue;
+            }
+
+            final String namespace = capability.substring(0, qmark);
+            final Iterable<String> queryParams = AMP_SPLITTER.split(capability.substring(qmark + 1));
+            final String moduleName = MODULE_PARAM.from(queryParams);
+            if (moduleName == null) {
+                continue;
+            }
+
+            String revision = REVISION_PARAM.from(queryParams);
+            if (revision != null) {
+                addModuleQName(moduleBasedCaps, nonModuleCaps, capability, cachedQName(namespace, revision, moduleName));
+                continue;
+            }
+
+            /*
+             * We have seen devices which mis-escape revision, but the revision may not
+             * even be there. First check if there is a substring that matches revision.
+             */
+            if (Iterables.any(queryParams, CONTAINS_REVISION)) {
+
+                LOG.debug("Netconf device was not reporting revision correctly, trying to get amp;revision=");
+                revision = BROKEN_REVISON_PARAM.from(queryParams);
+                if (revision == null) {
+                    LOG.warn("Netconf device returned revision incorrectly escaped for {}, ignoring it", capability);
+                    addModuleQName(moduleBasedCaps, nonModuleCaps, capability, cachedQName(namespace, moduleName));
+                } else {
+                    addModuleQName(moduleBasedCaps, nonModuleCaps, capability, cachedQName(namespace, revision, moduleName));
+                }
+                continue;
+            }
+
+            // Fallback, no revision provided for module
+            addModuleQName(moduleBasedCaps, nonModuleCaps, capability, cachedQName(namespace, moduleName));
+        }
+
+        return new NetconfSessionPreferences(ImmutableSet.copyOf(nonModuleCaps), ImmutableSet.copyOf(moduleBasedCaps));
+    }
+
+
+    private static void addModuleQName(final Set<QName> moduleBasedCaps, final Set<String> nonModuleCaps, final String capability, final QName qName) {
+        moduleBasedCaps.add(qName);
+        nonModuleCaps.remove(capability);
+    }
+
+    private NetconfDeviceCapabilities capabilities = new NetconfDeviceCapabilities();
+
+    public NetconfDeviceCapabilities getNetconfDeviceCapabilities() {
+        return capabilities;
+    }
+
+
+}
diff --git a/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/listener/UncancellableFuture.java b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/listener/UncancellableFuture.java
new file mode 100644 (file)
index 0000000..6219c4c
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.connect.netconf.listener;
+
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.AbstractFuture;
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.GuardedBy;
+
+final class UncancellableFuture<V> extends AbstractFuture<V> {
+    @GuardedBy("this")
+    private boolean uncancellable = false;
+
+    public UncancellableFuture(final boolean uncancellable) {
+        this.uncancellable = uncancellable;
+    }
+
+    public synchronized boolean setUncancellable() {
+        if (isCancelled()) {
+            return false;
+        }
+
+        uncancellable = true;
+        return true;
+    }
+
+    public synchronized boolean isUncancellable() {
+        return uncancellable;
+    }
+
+    @Override
+    public synchronized boolean cancel(final boolean mayInterruptIfRunning) {
+        return uncancellable ? false : super.cancel(mayInterruptIfRunning);
+    }
+
+    @Override
+    public synchronized boolean set(@Nullable final V value) {
+        Preconditions.checkState(uncancellable);
+        return super.set(value);
+    }
+
+    @Override
+    protected boolean setException(final Throwable throwable) {
+        Preconditions.checkState(uncancellable);
+        return super.setException(throwable);
+    }
+}
diff --git a/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/package-info.java b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/package-info.java
new file mode 100644 (file)
index 0000000..2c0a83d
--- /dev/null
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2014, 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
+ */
+
+ /**
+ * Implementation of netconf southbound connector
+ */
+package org.opendaylight.controller.sal.connect.netconf;
diff --git a/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/KeepaliveSalFacade.java b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/KeepaliveSalFacade.java
new file mode 100644 (file)
index 0000000..6c29f1d
--- /dev/null
@@ -0,0 +1,245 @@
+/*
+ * 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.sal.connect.netconf.sal;
+
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfBaseOps.getSourceNode;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_GET_CONFIG_QNAME;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_RUNNING_QNAME;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.toPath;
+
+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.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+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.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.controller.sal.connect.api.RemoteDeviceHandler;
+import org.opendaylight.controller.sal.connect.netconf.listener.NetconfDeviceCommunicator;
+import org.opendaylight.controller.sal.connect.netconf.listener.NetconfSessionPreferences;
+import org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil;
+import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * SalFacade proxy that invokes keepalive RPCs to prevent session shutdown from remote device
+ * and to detect incorrect session drops (netconf session is inactive, but TCP/SSH connection is still present).
+ * The keepalive RPC is a get-config with empty filter.
+ */
+public final class KeepaliveSalFacade implements RemoteDeviceHandler<NetconfSessionPreferences> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(KeepaliveSalFacade.class);
+
+    // 2 minutes keepalive delay by default
+    private static final long DEFAULT_DELAY = TimeUnit.MINUTES.toSeconds(2);
+
+    private final RemoteDeviceId id;
+    private final RemoteDeviceHandler<NetconfSessionPreferences> salFacade;
+    private final ScheduledExecutorService executor;
+    private final long keepaliveDelaySeconds;
+    private final ResetKeepalive resetKeepaliveTask;
+
+    private volatile NetconfDeviceCommunicator listener;
+    private volatile ScheduledFuture<?> currentKeepalive;
+    private volatile DOMRpcService currentDeviceRpc;
+
+    public KeepaliveSalFacade(final RemoteDeviceId id, final RemoteDeviceHandler<NetconfSessionPreferences> salFacade,
+                              final ScheduledExecutorService executor, final long keepaliveDelaySeconds) {
+        this.id = id;
+        this.salFacade = salFacade;
+        this.executor = executor;
+        this.keepaliveDelaySeconds = keepaliveDelaySeconds;
+        this.resetKeepaliveTask = new ResetKeepalive();
+    }
+
+    public KeepaliveSalFacade(final RemoteDeviceId id, final RemoteDeviceHandler<NetconfSessionPreferences> salFacade,
+                              final ScheduledExecutorService executor) {
+        this(id, salFacade, executor, DEFAULT_DELAY);
+    }
+
+    /**
+     * Set the netconf session listener whenever ready
+     *
+     * @param listener netconf session listener
+     */
+    public void setListener(final NetconfDeviceCommunicator listener) {
+        this.listener = listener;
+    }
+
+    /**
+     * Just cancel current keepalive task.
+     * If its already started, let it finish ... not such a big deal.
+     *
+     * Then schedule next keepalive.
+     */
+    private void resetKeepalive() {
+        LOG.trace("{}: Resetting netconf keepalive timer", id);
+        if(currentKeepalive != null) {
+            currentKeepalive.cancel(false);
+        }
+        scheduleKeepalive();
+    }
+
+    /**
+     * Cancel current keepalive and also reset current deviceRpc
+     */
+    private void stopKeepalives() {
+        if(currentKeepalive != null) {
+            currentKeepalive.cancel(false);
+        }
+        currentDeviceRpc = null;
+    }
+
+    private void reconnect() {
+        Preconditions.checkState(listener != null, "%s: Unable to reconnect, session listener is missing", id);
+        stopKeepalives();
+        LOG.info("{}: Reconnecting inactive netconf session", id);
+        listener.disconnect();
+    }
+
+    @Override
+    public void onDeviceConnected(final SchemaContext remoteSchemaContext, final NetconfSessionPreferences netconfSessionPreferences, final DOMRpcService deviceRpc) {
+        this.currentDeviceRpc = deviceRpc;
+        final DOMRpcService deviceRpc1 = new KeepaliveDOMRpcService(deviceRpc, resetKeepaliveTask);
+        salFacade.onDeviceConnected(remoteSchemaContext, netconfSessionPreferences, deviceRpc1);
+
+        LOG.debug("{}: Netconf session initiated, starting keepalives", id);
+        scheduleKeepalive();
+    }
+
+    private void scheduleKeepalive() {
+        Preconditions.checkState(currentDeviceRpc != null);
+        LOG.trace("{}: Scheduling next keepalive in {} {}", id, keepaliveDelaySeconds, TimeUnit.SECONDS);
+        currentKeepalive = executor.schedule(new Keepalive(), keepaliveDelaySeconds, TimeUnit.SECONDS);
+    }
+
+    @Override
+    public void onDeviceDisconnected() {
+        stopKeepalives();
+        salFacade.onDeviceDisconnected();
+    }
+
+    @Override
+    public void onDeviceFailed(final Throwable throwable) {
+        stopKeepalives();
+        salFacade.onDeviceFailed(throwable);
+    }
+
+    @Override
+    public void onNotification(final DOMNotification domNotification) {
+        resetKeepalive();
+        salFacade.onNotification(domNotification);
+    }
+
+    @Override
+    public void close() {
+        stopKeepalives();
+        salFacade.close();
+    }
+
+    // Keepalive RPC static resources
+    private static final SchemaPath PATH = toPath(NETCONF_GET_CONFIG_QNAME);
+    private static final ContainerNode KEEPALIVE_PAYLOAD =
+            NetconfMessageTransformUtil.wrap(NETCONF_GET_CONFIG_QNAME, getSourceNode(NETCONF_RUNNING_QNAME), NetconfMessageTransformUtil.EMPTY_FILTER);
+
+    /**
+     * Invoke keepalive RPC and check the response. In case of any received response the keepalive
+     * is considered successful and schedules next keepalive with a fixed delay. If the response is unsuccessful (no
+     * response received, or the rcp could not even be sent) immediate reconnect is triggered as netconf session
+     * is considered inactive/failed.
+     */
+    private class Keepalive implements Runnable, FutureCallback<DOMRpcResult> {
+
+        @Override
+        public void run() {
+            LOG.trace("{}: Invoking keepalive RPC", id);
+
+            try {
+                Futures.addCallback(currentDeviceRpc.invokeRpc(PATH, KEEPALIVE_PAYLOAD), this);
+            } catch (NullPointerException e) {
+                LOG.debug("{}: Skipping keepalive while reconnecting", id);
+                // Empty catch block intentional
+                // Do nothing. The currentDeviceRpc was null and it means we hit the reconnect window and
+                // attempted to send keepalive while we were reconnecting. Next keepalive will be scheduled
+                // after reconnect so no action necessary here.
+            }
+        }
+
+        @Override
+        public void onSuccess(final DOMRpcResult result) {
+            LOG.debug("{}: Keepalive RPC successful with response: {}", id, result.getResult());
+            scheduleKeepalive();
+        }
+
+        @Override
+        public void onFailure(@Nonnull final Throwable t) {
+            LOG.warn("{}: Keepalive RPC failed. Reconnecting netconf session.", id, t);
+            reconnect();
+        }
+    }
+
+    /**
+     * Reset keepalive after each RPC response received
+     */
+    private class ResetKeepalive implements com.google.common.util.concurrent.FutureCallback<DOMRpcResult> {
+        @Override
+        public void onSuccess(@Nullable final DOMRpcResult result) {
+            // No matter what response we got, rpc-reply or rpc-error, we got it from device so the netconf session is OK
+            resetKeepalive();
+        }
+
+        @Override
+        public void onFailure(@Nonnull final Throwable t) {
+            // User/Application RPC failed (The RPC did not reach the remote device or .. TODO what other reasons could cause this ?)
+            // There is no point in keeping this session. Reconnect.
+            LOG.warn("{}: Rpc failure detected. Reconnecting netconf session", id, t);
+            reconnect();
+        }
+    }
+
+    /**
+     * DOMRpcService proxy that attaches reset-keepalive-task to each RPC invocation.
+     */
+    private static final class KeepaliveDOMRpcService implements DOMRpcService {
+
+        private final DOMRpcService deviceRpc;
+        private ResetKeepalive resetKeepaliveTask;
+
+        public KeepaliveDOMRpcService(final DOMRpcService deviceRpc, final ResetKeepalive resetKeepaliveTask) {
+            this.deviceRpc = deviceRpc;
+            this.resetKeepaliveTask = resetKeepaliveTask;
+        }
+
+        @Nonnull
+        @Override
+        public CheckedFuture<DOMRpcResult, DOMRpcException> invokeRpc(@Nonnull final SchemaPath type, final NormalizedNode<?, ?> input) {
+            final CheckedFuture<DOMRpcResult, DOMRpcException> domRpcResultDOMRpcExceptionCheckedFuture = deviceRpc.invokeRpc(type, input);
+            Futures.addCallback(domRpcResultDOMRpcExceptionCheckedFuture, resetKeepaliveTask);
+            return domRpcResultDOMRpcExceptionCheckedFuture;
+        }
+
+        @Override
+        public <T extends DOMRpcAvailabilityListener> ListenerRegistration<T> registerRpcListener(@Nonnull final T listener) {
+            // There is no real communication with the device (yet), no reset here
+            return deviceRpc.registerRpcListener(listener);
+        }
+    }
+}
diff --git a/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceDataBroker.java b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceDataBroker.java
new file mode 100644 (file)
index 0000000..34e8133
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.connect.netconf.sal;
+
+import java.util.Collections;
+import java.util.Map;
+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.DOMDataBroker;
+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.controller.sal.connect.netconf.listener.NetconfSessionPreferences;
+import org.opendaylight.controller.sal.connect.netconf.sal.tx.ReadOnlyTx;
+import org.opendaylight.controller.sal.connect.netconf.sal.tx.ReadWriteTx;
+import org.opendaylight.controller.sal.connect.netconf.sal.tx.WriteCandidateRunningTx;
+import org.opendaylight.controller.sal.connect.netconf.sal.tx.WriteCandidateTx;
+import org.opendaylight.controller.sal.connect.netconf.sal.tx.WriteRunningTx;
+import org.opendaylight.controller.sal.connect.netconf.util.NetconfBaseOps;
+import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+final class NetconfDeviceDataBroker implements DOMDataBroker {
+    private final RemoteDeviceId id;
+    private final NetconfBaseOps netconfOps;
+    private final long requestTimeoutMillis;
+
+    private final boolean rollbackSupport;
+    private boolean candidateSupported;
+    private boolean runningWritable;
+
+    public NetconfDeviceDataBroker(final RemoteDeviceId id, final SchemaContext schemaContext, final DOMRpcService rpc, final NetconfSessionPreferences netconfSessionPreferences, long requestTimeoutMillis) {
+        this.id = id;
+        this.netconfOps = new NetconfBaseOps(rpc, schemaContext);
+        this.requestTimeoutMillis = requestTimeoutMillis;
+        // get specific attributes from netconf preferences and get rid of it
+        // no need to keep the entire preferences object, its quite big with all the capability QNames
+        candidateSupported = netconfSessionPreferences.isCandidateSupported();
+        runningWritable = netconfSessionPreferences.isRunningWritable();
+        rollbackSupport = netconfSessionPreferences.isRollbackSupported();
+    }
+
+    @Override
+    public DOMDataReadOnlyTransaction newReadOnlyTransaction() {
+        return new ReadOnlyTx(netconfOps, id);
+    }
+
+    @Override
+    public DOMDataReadWriteTransaction newReadWriteTransaction() {
+        return new ReadWriteTx(newReadOnlyTransaction(), newWriteOnlyTransaction());
+    }
+
+    @Override
+    public DOMDataWriteTransaction newWriteOnlyTransaction() {
+        if(candidateSupported) {
+            if(runningWritable) {
+                return new WriteCandidateRunningTx(id, netconfOps, rollbackSupport, requestTimeoutMillis);
+            } else {
+                return new WriteCandidateTx(id, netconfOps, rollbackSupport, requestTimeoutMillis);
+            }
+        } else {
+            return new WriteRunningTx(id, netconfOps, rollbackSupport, requestTimeoutMillis);
+        }
+    }
+
+    @Override
+    public ListenerRegistration<DOMDataChangeListener> registerDataChangeListener(final LogicalDatastoreType store, final YangInstanceIdentifier path, final DOMDataChangeListener listener, final DataChangeScope triggeringScope) {
+        throw new UnsupportedOperationException(id + ": Data change listeners not supported for netconf mount point");
+    }
+
+    @Override
+    public DOMTransactionChain createTransactionChain(final TransactionChainListener listener) {
+        throw new UnsupportedOperationException(id + ": Transaction chains not supported for netconf mount point");
+    }
+
+    @Override
+    public Map<Class<? extends DOMDataBrokerExtension>, DOMDataBrokerExtension> getSupportedExtensions() {
+        return Collections.emptyMap();
+    }
+
+}
diff --git a/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceNotificationService.java b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceNotificationService.java
new file mode 100644 (file)
index 0000000..b27430f
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * 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.sal.connect.netconf.sal;
+
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Multimap;
+import java.util.Collection;
+import javax.annotation.Nonnull;
+import org.opendaylight.controller.md.sal.dom.api.DOMNotification;
+import org.opendaylight.controller.md.sal.dom.api.DOMNotificationListener;
+import org.opendaylight.controller.md.sal.dom.api.DOMNotificationService;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+
+class NetconfDeviceNotificationService implements DOMNotificationService {
+
+    private final Multimap<SchemaPath, DOMNotificationListener> listeners = HashMultimap.create();
+
+    // Notification publish is very simple and hijacks the thread of the caller
+    // TODO shouldnt we reuse the implementation for notification router from sal-broker-impl ?
+    public synchronized void publishNotification(final DOMNotification notification) {
+        for (final DOMNotificationListener domNotificationListener : listeners.get(notification.getType())) {
+            domNotificationListener.onNotification(notification);
+        }
+    }
+
+    @Override
+    public synchronized <T extends DOMNotificationListener> ListenerRegistration<T> registerNotificationListener(@Nonnull final T listener, @Nonnull final Collection<SchemaPath> types) {
+        for (final SchemaPath type : types) {
+            listeners.put(type, listener);
+        }
+
+        // FIXME this should invoke create-subscription rpc on the remote device for a given notification
+
+        return new ListenerRegistration<T>() {
+            @Override
+            public void close() {
+                for (final SchemaPath type : types) {
+                    listeners.remove(type, listener);
+                }
+            }
+
+            @Override
+            public T getInstance() {
+                return listener;
+            }
+        };
+    }
+
+    @Override
+    public synchronized <T extends DOMNotificationListener> ListenerRegistration<T> registerNotificationListener(@Nonnull final T listener, final SchemaPath... types) {
+        return registerNotificationListener(listener, Lists.newArrayList(types));
+    }
+}
diff --git a/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceRpc.java b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceRpc.java
new file mode 100644 (file)
index 0000000..178b050
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.connect.netconf.sal;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Collections2;
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import java.util.Collection;
+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.DOMRpcIdentifier;
+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.controller.netconf.api.NetconfMessage;
+import org.opendaylight.controller.sal.connect.api.MessageTransformer;
+import org.opendaylight.controller.sal.connect.api.RemoteDeviceCommunicator;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+
+/**
+ * Invokes RPC by sending netconf message via listener. Also transforms result from NetconfMessage to CompositeNode.
+ */
+public final class NetconfDeviceRpc implements DOMRpcService {
+
+    private static final Function<RpcDefinition, DOMRpcIdentifier> RPC_TO_RPC_IDENTIFIER = new Function<RpcDefinition, DOMRpcIdentifier>() {
+        @Override
+        public DOMRpcIdentifier apply(final RpcDefinition input) {
+            // TODO add support for routed rpcs ... is it necessary in this case ?
+            return DOMRpcIdentifier.create(input.getPath());
+        }
+    };
+
+    private final RemoteDeviceCommunicator<NetconfMessage> listener;
+    private final MessageTransformer<NetconfMessage> transformer;
+    private final Collection<DOMRpcIdentifier> availableRpcs;
+
+    public NetconfDeviceRpc(final SchemaContext schemaContext, final RemoteDeviceCommunicator<NetconfMessage> listener, final MessageTransformer<NetconfMessage> transformer) {
+        this.listener = listener;
+        this.transformer = transformer;
+
+        availableRpcs = Collections2.transform(schemaContext.getOperations(), RPC_TO_RPC_IDENTIFIER);
+    }
+
+    @Nonnull
+    @Override
+    public CheckedFuture<DOMRpcResult, DOMRpcException> invokeRpc(@Nonnull final SchemaPath type, @Nullable final NormalizedNode<?, ?> input) {
+        final NetconfMessage message = transformer.toRpcRequest(type, input);
+        final ListenableFuture<RpcResult<NetconfMessage>> delegateFutureWithPureResult = listener.sendRequest(message, type.getLastComponent());
+
+        final ListenableFuture<DOMRpcResult> transformed = Futures.transform(delegateFutureWithPureResult, new Function<RpcResult<NetconfMessage>, DOMRpcResult>() {
+            @Override
+            public DOMRpcResult apply(final RpcResult<NetconfMessage> input) {
+                if (input.isSuccessful()) {
+                    return transformer.toRpcResult(input.getResult(), type);
+                } else {
+                    // TODO check whether the listener sets errors properly
+                    return new DefaultDOMRpcResult(input.getErrors());
+                }
+            }
+        });
+
+        return Futures.makeChecked(transformed, new Function<Exception, DOMRpcException>() {
+            @Nullable
+            @Override
+            public DOMRpcException apply(@Nullable final Exception e) {
+                // FIXME what other possible exceptions are there ?
+                return new DOMRpcImplementationNotAvailableException(e, "Unable to invoke rpc %s", type);
+            }
+        });
+    }
+
+    @Nonnull
+    @Override
+    public <T extends DOMRpcAvailabilityListener> ListenerRegistration<T> registerRpcListener(@Nonnull final T listener) {
+
+        listener.onRpcAvailable(availableRpcs);
+
+        return new ListenerRegistration<T>() {
+            @Override
+            public void close() {
+                // NOOP, no rpcs appear and disappear in this implementation
+            }
+
+            @Override
+            public T getInstance() {
+                return listener;
+            }
+        };
+    }
+}
diff --git a/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceSalFacade.java b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceSalFacade.java
new file mode 100644 (file)
index 0000000..96b0d43
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.connect.netconf.sal;
+
+import com.google.common.collect.Lists;
+import java.util.List;
+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.connect.api.RemoteDeviceHandler;
+import org.opendaylight.controller.sal.connect.netconf.listener.NetconfDeviceCapabilities;
+import org.opendaylight.controller.sal.connect.netconf.listener.NetconfSessionPreferences;
+import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
+import org.opendaylight.controller.sal.core.api.Broker;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public final class NetconfDeviceSalFacade implements AutoCloseable, RemoteDeviceHandler<NetconfSessionPreferences> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(NetconfDeviceSalFacade.class);
+
+    private final RemoteDeviceId id;
+    private final NetconfDeviceSalProvider salProvider;
+    private final long defaultRequestTimeoutMillis;
+
+    private final List<AutoCloseable> salRegistrations = Lists.newArrayList();
+
+    public NetconfDeviceSalFacade(final RemoteDeviceId id, final Broker domBroker, final BindingAwareBroker bindingBroker, long defaultRequestTimeoutMillis) {
+        this.id = id;
+        this.salProvider = new NetconfDeviceSalProvider(id);
+        this.defaultRequestTimeoutMillis = defaultRequestTimeoutMillis;
+        registerToSal(domBroker, bindingBroker);
+    }
+
+    public void registerToSal(final Broker domRegistryDependency, final BindingAwareBroker bindingBroker) {
+        domRegistryDependency.registerProvider(salProvider);
+        bindingBroker.registerProvider(salProvider);
+    }
+
+    @Override
+    public synchronized void onNotification(final DOMNotification domNotification) {
+        salProvider.getMountInstance().publish(domNotification);
+    }
+
+    @Override
+    public synchronized void onDeviceConnected(final SchemaContext schemaContext,
+                                               final NetconfSessionPreferences netconfSessionPreferences, final DOMRpcService deviceRpc) {
+
+        final DOMDataBroker domBroker = new NetconfDeviceDataBroker(id, schemaContext, deviceRpc, netconfSessionPreferences, defaultRequestTimeoutMillis);
+
+        final NetconfDeviceNotificationService notificationService = new NetconfDeviceNotificationService();
+
+        salProvider.getMountInstance().onTopologyDeviceConnected(schemaContext, domBroker, deviceRpc, notificationService);
+        salProvider.getTopologyDatastoreAdapter().updateDeviceData(true, netconfSessionPreferences.getNetconfDeviceCapabilities());
+    }
+
+    @Override
+    public synchronized void onDeviceDisconnected() {
+        salProvider.getTopologyDatastoreAdapter().updateDeviceData(false,
+                new NetconfDeviceCapabilities());
+        salProvider.getMountInstance().onTopologyDeviceDisconnected();
+    }
+
+    @Override
+    public synchronized void onDeviceFailed(final Throwable throwable) {
+        salProvider.getTopologyDatastoreAdapter().setDeviceAsFailed(throwable);
+        salProvider.getMountInstance().onTopologyDeviceDisconnected();
+    }
+
+    @Override
+    public synchronized void close() {
+        for (final AutoCloseable reg : Lists.reverse(salRegistrations)) {
+            closeGracefully(reg);
+        }
+        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);
+            }
+        }
+    }
+
+}
diff --git a/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceSalProvider.java b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceSalProvider.java
new file mode 100644 (file)
index 0000000..f39c0c0
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.connect.netconf.sal;
+
+import com.google.common.base.Preconditions;
+import java.util.Collection;
+import java.util.Collections;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+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.controller.sal.binding.api.BindingAwareBroker;
+import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
+import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
+import org.opendaylight.controller.sal.core.api.Broker;
+import org.opendaylight.controller.sal.core.api.Provider;
+import org.opendaylight.yangtools.concepts.ObjectRegistration;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+final class NetconfDeviceSalProvider implements AutoCloseable, Provider, BindingAwareProvider {
+
+    private static final Logger LOG = LoggerFactory.getLogger(NetconfDeviceSalProvider.class);
+
+    private final RemoteDeviceId id;
+    private MountInstance mountInstance;
+
+    private volatile NetconfDeviceTopologyAdapter topologyDatastoreAdapter;
+
+    public NetconfDeviceSalProvider(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;
+    }
+
+    public NetconfDeviceTopologyAdapter getTopologyDatastoreAdapter() {
+        Preconditions.checkState(topologyDatastoreAdapter != null,
+                "%s: Sal provider %s was not initialized by sal. Cannot get topology datastore adapter", id);
+        return topologyDatastoreAdapter;
+    }
+
+    @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<Provider.ProviderFunctionality> getProviderFunctionality() {
+        return Collections.emptySet();
+    }
+
+    @Override
+    public void onSessionInitiated(final BindingAwareBroker.ProviderContext session) {
+        LOG.debug("{}: Session with sal established {}", id, session);
+
+        final DataBroker dataBroker = session.getSALService(DataBroker.class);
+
+        topologyDatastoreAdapter = new NetconfDeviceTopologyAdapter(id, dataBroker);
+    }
+
+    public void close() throws Exception {
+        mountInstance.close();
+        topologyDatastoreAdapter.close();
+        topologyDatastoreAdapter = null;
+    }
+
+    static final class MountInstance implements AutoCloseable {
+
+        private DOMMountPointService mountService;
+        private final RemoteDeviceId id;
+        private NetconfDeviceNotificationService notificationService;
+
+        private ObjectRegistration<DOMMountPoint> topologyRegistration;
+
+        MountInstance(final DOMMountPointService mountService, final RemoteDeviceId id) {
+            this.mountService = Preconditions.checkNotNull(mountService);
+            this.id = Preconditions.checkNotNull(id);
+        }
+
+        synchronized void onTopologyDeviceConnected(final SchemaContext initialCtx,
+                                                    final DOMDataBroker broker, final DOMRpcService rpc,
+                                                    final NetconfDeviceNotificationService notificationService) {
+
+            Preconditions.checkNotNull(mountService, "Closed");
+            Preconditions.checkState(topologyRegistration == null, "Already initialized");
+
+            final DOMMountPointService.DOMMountPointBuilder mountBuilder = mountService.createMountPoint(id.getTopologyPath());
+            mountBuilder.addInitialSchemaContext(initialCtx);
+
+            mountBuilder.addService(DOMDataBroker.class, broker);
+            mountBuilder.addService(DOMRpcService.class, rpc);
+            mountBuilder.addService(DOMNotificationService.class, notificationService);
+            this.notificationService = notificationService;
+
+            topologyRegistration = mountBuilder.register();
+            LOG.debug("{}: TOPOLOGY Mountpoint exposed into MD-SAL {}", id,
+                    topologyRegistration);
+
+        }
+
+        synchronized void onTopologyDeviceDisconnected() {
+            if(topologyRegistration == null) {
+                LOG.trace(
+                        "{}: Not removing TOPOLOGY mountpoint from MD-SAL, mountpoint was not registered yet",
+                        id);
+                return;
+            }
+
+            try {
+                topologyRegistration.close();
+            } catch (final Exception e) {
+                // Only log and ignore
+                LOG.warn(
+                        "Unable to unregister mount instance for {}. Ignoring exception",
+                        id.getTopologyPath(), e);
+            } finally {
+                LOG.debug("{}: TOPOLOGY Mountpoint removed from MD-SAL {}",
+                        id, topologyRegistration);
+                topologyRegistration = null;
+            }
+        }
+
+        @Override
+        synchronized public void close() throws Exception {
+            onTopologyDeviceDisconnected();
+            mountService = null;
+        }
+
+        public synchronized void publish(final DOMNotification domNotification) {
+            Preconditions.checkNotNull(notificationService, "Device not set up yet, cannot handle notification {}", domNotification);
+            notificationService.publishNotification(domNotification);
+        }
+    }
+
+}
diff --git a/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceTopologyAdapter.java b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceTopologyAdapter.java
new file mode 100644 (file)
index 0000000..3be30f4
--- /dev/null
@@ -0,0 +1,262 @@
+/*
+ * 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.sal.connect.netconf.sal;
+
+import com.google.common.base.Function;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.FluentIterable;
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map.Entry;
+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.controller.sal.connect.netconf.listener.NetconfDeviceCapabilities;
+import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.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.NetconfNodeFields.ConnectionStatus;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.fields.AvailableCapabilitiesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.fields.UnavailableCapabilities;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.fields.UnavailableCapabilitiesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.fields.unavailable.capabilities.UnavailableCapability;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.fields.unavailable.capabilities.UnavailableCapability.FailureReason;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.fields.unavailable.capabilities.UnavailableCapabilityBuilder;
+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.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.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+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>() {
+        @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 final RemoteDeviceId id;
+    private final BindingTransactionChain txChain;
+
+    private final InstanceIdentifier<NetworkTopology> networkTopologyPath;
+    private final KeyedInstanceIdentifier<Topology, TopologyKey> topologyListPath;
+    private static final String UNKNOWN_REASON = "Unknown reason";
+
+    NetconfDeviceTopologyAdapter(final RemoteDeviceId id, final DataBroker dataService) {
+        this.id = id;
+        this.txChain = Preconditions.checkNotNull(dataService).createTransactionChain(new TransactionChainListener() {
+            @Override
+            public void onTransactionChainFailed(TransactionChain<?, ?> chain, AsyncTransaction<?, ?> transaction, Throwable cause) {
+                LOG.error("{}: TransactionChain({}) {} FAILED!", id, chain,
+                        transaction.getIdentifier(), cause);
+                throw new IllegalStateException(id + "  TransactionChain(" + chain + ") not committed correctly", cause);
+            }
+
+            @Override
+            public void onTransactionChainSuccessful(TransactionChain<?, ?> chain) {
+                LOG.trace("{}: TransactionChain({}) SUCCESSFUL", id, chain);
+            }
+        });
+
+        this.networkTopologyPath = InstanceIdentifier.builder(NetworkTopology.class).build();
+        this.topologyListPath = networkTopologyPath.child(Topology.class, new TopologyKey(new TopologyId(TopologyNetconf.QNAME.getLocalName())));
+
+        initDeviceData();
+    }
+
+    private void initDeviceData() {
+        final WriteTransaction writeTx = txChain.newWriteOnlyTransaction();
+
+        createNetworkTopologyIfNotPresent(writeTx);
+
+        final InstanceIdentifier<Node> path = id.getTopologyBindingPath();
+        NodeBuilder nodeBuilder = getNodeIdBuilder(id);
+        NetconfNodeBuilder netconfNodeBuilder = new NetconfNodeBuilder();
+        netconfNodeBuilder.setConnectionStatus(ConnectionStatus.Connecting);
+        netconfNodeBuilder.setHost(id.getHost());
+        netconfNodeBuilder.setPort(new PortNumber(id.getAddress().getPort()));
+        nodeBuilder.addAugmentation(NetconfNode.class, netconfNodeBuilder.build());
+        Node node = nodeBuilder.build();
+
+        LOG.trace(
+                "{}: Init device state transaction {} putting if absent operational data started.",
+                id, writeTx.getIdentifier());
+        writeTx.put(LogicalDatastoreType.OPERATIONAL, path, node);
+        LOG.trace(
+                "{}: Init device state transaction {} putting operational data ended.",
+                id, writeTx.getIdentifier());
+
+        LOG.trace(
+                "{}: Init device state transaction {} putting if absent config data started.",
+                id, writeTx.getIdentifier());
+        writeTx.put(LogicalDatastoreType.CONFIGURATION, path, getNodeWithId(id));
+        LOG.trace(
+                "{}: Init device state transaction {} putting config data ended.",
+                id, writeTx.getIdentifier());
+
+        commitTransaction(writeTx, "init");
+    }
+
+    public void updateDeviceData(boolean up, NetconfDeviceCapabilities capabilities) {
+        final Node data = buildDataForNetconfNode(up, 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(), data);
+        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;
+
+        final NetconfNode netconfNode = new NetconfNodeBuilder().setConnectionStatus(ConnectionStatus.UnableToConnect).setConnectedMessage(reason).build();
+        final Node data = getNodeIdBuilder(id).addAugmentation(NetconfNode.class, netconfNode).build();
+
+        final WriteTransaction writeTx = txChain.newWriteOnlyTransaction();
+        LOG.trace(
+                "{}: Setting device state as failed {} putting operational data started.",
+                id, writeTx.getIdentifier());
+        writeTx.put(LogicalDatastoreType.OPERATIONAL, id.getTopologyBindingPath(), data);
+        LOG.trace(
+                "{}: Setting device state as failed {} putting operational data ended.",
+                id, writeTx.getIdentifier());
+
+        commitTransaction(writeTx, "update-failed-device");
+    }
+
+    private Node buildDataForNetconfNode(boolean up, NetconfDeviceCapabilities capabilities) {
+        List<String> capabilityList = new ArrayList<>();
+        capabilityList.addAll(capabilities.getNonModuleBasedCapabilities());
+        capabilityList.addAll(FluentIterable.from(capabilities.getResolvedCapabilities()).transform(AVAILABLE_CAPABILITY_TRANSFORMER).toList());
+        final AvailableCapabilitiesBuilder avCapabalitiesBuilder = new AvailableCapabilitiesBuilder();
+        avCapabalitiesBuilder.setAvailableCapability(capabilityList);
+
+        final UnavailableCapabilities unavailableCapabilities =
+                new UnavailableCapabilitiesBuilder().setUnavailableCapability(FluentIterable.from(capabilities.getUnresolvedCapabilites().entrySet())
+                        .transform(UNAVAILABLE_CAPABILITY_TRANSFORMER).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);
+
+        final NodeBuilder nodeBuilder = getNodeIdBuilder(id);
+
+        return nodeBuilder.addAugmentation(NetconfNode.class, netconfNodeBuilder.build()).build();
+    }
+
+    public void removeDeviceConfiguration() {
+        final WriteTransaction writeTx = txChain.newWriteOnlyTransaction();
+
+        LOG.trace(
+                "{}: Close device state transaction {} removing all data started.",
+                id, writeTx.getIdentifier());
+        writeTx.delete(LogicalDatastoreType.CONFIGURATION, id.getTopologyBindingPath());
+        writeTx.delete(LogicalDatastoreType.OPERATIONAL, id.getTopologyBindingPath());
+        LOG.trace(
+                "{}: Close device state transaction {} removing all data ended.",
+                id, writeTx.getIdentifier());
+
+        commitTransaction(writeTx, "close");
+    }
+
+    private void createNetworkTopologyIfNotPresent(final WriteTransaction writeTx) {
+
+        final NetworkTopology networkTopology = new NetworkTopologyBuilder().build();
+        LOG.trace("{}: Merging {} container to ensure its presence", id,
+                networkTopology.QNAME, writeTx.getIdentifier());
+        writeTx.merge(LogicalDatastoreType.CONFIGURATION, networkTopologyPath, networkTopology);
+        writeTx.merge(LogicalDatastoreType.OPERATIONAL, networkTopologyPath, networkTopology);
+
+        final Topology topology = new TopologyBuilder().setTopologyId(new TopologyId(TopologyNetconf.QNAME.getLocalName())).build();
+        LOG.trace("{}: Merging {} container to ensure its presence", id,
+                topology.QNAME, writeTx.getIdentifier());
+        writeTx.merge(LogicalDatastoreType.CONFIGURATION, topologyListPath, topology);
+        writeTx.merge(LogicalDatastoreType.OPERATIONAL, topologyListPath, topology);
+    }
+
+    private void commitTransaction(final WriteTransaction transaction, final String txType) {
+        LOG.trace("{}: Committing Transaction {}:{}", id, 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, txType,
+                        transaction.getIdentifier());
+            }
+
+            @Override
+            public void onFailure(final Throwable t) {
+                LOG.error("{}: Transaction({}) {} FAILED!", id, txType,
+                        transaction.getIdentifier(), t);
+                throw new IllegalStateException(id + "  Transaction(" + txType + ") not committed correctly", t);
+            }
+        });
+
+    }
+
+    private static Node getNodeWithId(final RemoteDeviceId id) {
+        final NodeBuilder builder = getNodeIdBuilder(id);
+        return builder.build();
+    }
+
+    private static NodeBuilder getNodeIdBuilder(final RemoteDeviceId id) {
+        final NodeBuilder nodeBuilder = new NodeBuilder();
+        nodeBuilder.setKey(new NodeKey(new NodeId(id.getName())));
+        return nodeBuilder;
+    }
+
+    @Override
+    public void close() throws Exception {
+        removeDeviceConfiguration();
+        txChain.close();
+    }
+}
diff --git a/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/AbstractWriteTx.java b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/AbstractWriteTx.java
new file mode 100644 (file)
index 0000000..c7c0c02
--- /dev/null
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2014, 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.sal.connect.netconf.sal.tx;
+
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.ListenableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+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.DOMDataWriteTransaction;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.sal.connect.netconf.util.NetconfBaseOps;
+import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+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.MixinNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public abstract class AbstractWriteTx implements DOMDataWriteTransaction {
+
+    private static final Logger LOG  = LoggerFactory.getLogger(AbstractWriteTx.class);
+
+    private final long defaultRequestTimeoutMillis;
+    protected final RemoteDeviceId id;
+    protected final NetconfBaseOps netOps;
+    protected final boolean rollbackSupport;
+    // Allow commit to be called only once
+    protected boolean finished = false;
+
+    public AbstractWriteTx(final long requestTimeoutMillis, final NetconfBaseOps netOps, final RemoteDeviceId id, final boolean rollbackSupport) {
+        this.defaultRequestTimeoutMillis = requestTimeoutMillis;
+        this.netOps = netOps;
+        this.id = id;
+        this.rollbackSupport = rollbackSupport;
+        init();
+    }
+
+    static boolean isSuccess(final DOMRpcResult result) {
+        return result.getErrors().isEmpty();
+    }
+
+    protected void checkNotFinished() {
+        Preconditions.checkState(!isFinished(), "%s: Transaction %s already finished", id, getIdentifier());
+    }
+
+    protected boolean isFinished() {
+        return finished;
+    }
+
+    protected void invokeBlocking(final String msg, final Function<NetconfBaseOps, ListenableFuture<DOMRpcResult>> op) throws NetconfDocumentedException {
+        try {
+            final DOMRpcResult compositeNodeRpcResult = op.apply(netOps).get(defaultRequestTimeoutMillis, TimeUnit.MILLISECONDS);
+            if(isSuccess(compositeNodeRpcResult) == false) {
+                throw new NetconfDocumentedException(id + ": " + msg + " failed: " + compositeNodeRpcResult.getErrors(), NetconfDocumentedException.ErrorType.application,
+                        NetconfDocumentedException.ErrorTag.operation_failed, NetconfDocumentedException.ErrorSeverity.warning);
+            }
+        } catch (final InterruptedException e) {
+            Thread.currentThread().interrupt();
+            throw new RuntimeException(e);
+        } catch (final ExecutionException | TimeoutException e) {
+            throw new NetconfDocumentedException(id + ": " + msg + " failed: " + e.getMessage(), e, NetconfDocumentedException.ErrorType.application,
+                    NetconfDocumentedException.ErrorTag.operation_failed, NetconfDocumentedException.ErrorSeverity.warning);
+        }
+    }
+
+    @Override
+    public synchronized boolean cancel() {
+        if(isFinished()) {
+            return false;
+        }
+
+        finished = true;
+        cleanup();
+        return true;
+    }
+
+    protected abstract void init();
+
+    protected abstract void cleanup();
+
+    @Override
+    public Object getIdentifier() {
+        return this;
+    }
+
+    @Override
+    public synchronized void put(final LogicalDatastoreType store, final YangInstanceIdentifier path, final NormalizedNode<?, ?> data) {
+        checkEditable(store);
+
+        // trying to write only mixin nodes (not visible when serialized). Ignoring. Some devices cannot handle empty edit-config rpc
+        if(containsOnlyNonVisibleData(path, data)) {
+            LOG.debug("Ignoring put for {} and data {}. Resulting data structure is empty.", path, data);
+            return;
+        }
+
+        try {
+            editConfig(
+                    netOps.createEditConfigStrcture(Optional.<NormalizedNode<?, ?>>fromNullable(data), Optional.of(ModifyAction.REPLACE), path), Optional.of(ModifyAction.NONE));
+        } catch (final NetconfDocumentedException e) {
+            handleEditException(path, data, e, "putting");
+        }
+    }
+
+    protected abstract void handleEditException(YangInstanceIdentifier path, NormalizedNode<?, ?> data, NetconfDocumentedException e, String editType);
+    protected abstract void handleDeleteException(YangInstanceIdentifier path, NetconfDocumentedException e);
+
+    @Override
+    public synchronized void merge(final LogicalDatastoreType store, final YangInstanceIdentifier path, final NormalizedNode<?, ?> data) {
+        checkEditable(store);
+
+        // trying to write only mixin nodes (not visible when serialized). Ignoring. Some devices cannot handle empty edit-config rpc
+        if (containsOnlyNonVisibleData(path, data)) {
+            LOG.debug("Ignoring merge for {} and data {}. Resulting data structure is empty.", path, data);
+            return;
+        }
+
+        try {
+            editConfig(
+                    netOps.createEditConfigStrcture(Optional.<NormalizedNode<?, ?>>fromNullable(data), Optional.<ModifyAction>absent(), path), Optional.<ModifyAction>absent());
+        } catch (final NetconfDocumentedException e) {
+            handleEditException(path, data, e, "merge");
+        }
+    }
+
+    /**
+     * Check whether the data to be written consists only from mixins
+     */
+    private static boolean containsOnlyNonVisibleData(final YangInstanceIdentifier path, final NormalizedNode<?, ?> data) {
+        // There's only one such case:top level list (pathArguments == 1 && data is Mixin)
+        // any other mixin nodes are contained by a "regular" node thus visible when serialized
+        return path.getPathArguments().size() == 1 && data instanceof MixinNode;
+    }
+
+    @Override
+    public synchronized void delete(final LogicalDatastoreType store, final YangInstanceIdentifier path) {
+        checkEditable(store);
+
+        try {
+            editConfig(
+                    netOps.createEditConfigStrcture(Optional.<NormalizedNode<?, ?>>absent(), Optional.of(ModifyAction.DELETE), path), Optional.of(ModifyAction.NONE));
+        } catch (final NetconfDocumentedException e) {
+            handleDeleteException(path, e);
+        }
+    }
+
+    @Override
+    public final ListenableFuture<RpcResult<TransactionStatus>> commit() {
+        checkNotFinished();
+        finished = true;
+
+        return performCommit();
+    }
+
+    protected abstract ListenableFuture<RpcResult<TransactionStatus>> performCommit();
+
+    private void checkEditable(final LogicalDatastoreType store) {
+        checkNotFinished();
+        Preconditions.checkArgument(store == LogicalDatastoreType.CONFIGURATION, "Can edit only configuration data, not %s", store);
+    }
+
+    protected abstract void editConfig(DataContainerChild<?, ?> editStructure, Optional<ModifyAction> defaultOperation) throws NetconfDocumentedException;
+}
diff --git a/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/ReadOnlyTx.java b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/ReadOnlyTx.java
new file mode 100644 (file)
index 0000000..b28b0e7
--- /dev/null
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.connect.netconf.sal.tx;
+
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+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 com.google.common.util.concurrent.ListenableFuture;
+import java.util.concurrent.ExecutionException;
+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.controller.md.sal.dom.api.DOMRpcResult;
+import org.opendaylight.controller.sal.connect.netconf.util.NetconfBaseOps;
+import org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil;
+import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
+import org.opendaylight.yangtools.util.concurrent.MappingCheckedFuture;
+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.DataContainerChild;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodes;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+public final class ReadOnlyTx implements DOMDataReadOnlyTransaction {
+
+    private static final Logger LOG  = LoggerFactory.getLogger(ReadOnlyTx.class);
+
+    private final NetconfBaseOps netconfOps;
+    private final RemoteDeviceId id;
+    private final FutureCallback<DOMRpcResult> loggingCallback;
+
+    public ReadOnlyTx(final NetconfBaseOps netconfOps, final RemoteDeviceId id) {
+        this.netconfOps = netconfOps;
+        this.id = id;
+
+        // Simple logging callback to log result of read operation
+        loggingCallback = new FutureCallback<DOMRpcResult>() {
+            @Override
+            public void onSuccess(final DOMRpcResult result) {
+                if(AbstractWriteTx.isSuccess(result)) {
+                    LOG.trace("{}: Reading data successful", id);
+                } else {
+                    LOG.warn("{}: Reading data unsuccessful: {}", id, result.getErrors());
+                }
+
+            }
+
+            @Override
+            public void onFailure(final Throwable t) {
+                LOG.warn("{}: Reading data failed", id, t);
+            }
+        };
+    }
+
+    private CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> readConfigurationData(
+            final YangInstanceIdentifier path) {
+        final ListenableFuture<DOMRpcResult> configRunning = netconfOps.getConfigRunning(loggingCallback, Optional.fromNullable(path));
+
+        final ListenableFuture<Optional<NormalizedNode<?, ?>>> transformedFuture = Futures.transform(configRunning, new Function<DOMRpcResult, Optional<NormalizedNode<?, ?>>>() {
+            @Override
+            public Optional<NormalizedNode<?, ?>> apply(final DOMRpcResult result) {
+                checkReadSuccess(result, path);
+
+                final DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?> dataNode = findDataNode(result);
+                return NormalizedNodes.findNode(dataNode, path.getPathArguments());
+            }
+        });
+
+        return MappingCheckedFuture.create(transformedFuture, ReadFailedException.MAPPER);
+    }
+
+    private DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?> findDataNode(final DOMRpcResult result) {
+        return ((ContainerNode) result.getResult()).getChild(NetconfMessageTransformUtil.toId(NetconfMessageTransformUtil.NETCONF_DATA_QNAME)).get();
+    }
+
+    private void checkReadSuccess(final DOMRpcResult result, final YangInstanceIdentifier path) {
+        try {
+            Preconditions.checkArgument(AbstractWriteTx.isSuccess(result), "%s: Unable to read data: %s, errors: %s", id, path, result.getErrors());
+        } catch (final IllegalArgumentException e) {
+            LOG.warn("{}: Unable to read data: {}, errors: {}", id, path, result.getErrors());
+            throw e;
+        }
+    }
+
+    private CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> readOperationalData(
+            final YangInstanceIdentifier path) {
+        final ListenableFuture<DOMRpcResult> configCandidate = netconfOps.get(loggingCallback, Optional.fromNullable(path));
+
+        // Find data node and normalize its content
+        final ListenableFuture<Optional<NormalizedNode<?, ?>>> transformedFuture = Futures.transform(configCandidate, new Function<DOMRpcResult, Optional<NormalizedNode<?, ?>>>() {
+            @Override
+            public Optional<NormalizedNode<?, ?>> apply(final DOMRpcResult result) {
+                checkReadSuccess(result, path);
+
+                final DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?> dataNode = findDataNode(result);
+                return NormalizedNodes.findNode(dataNode, path.getPathArguments());
+            }
+        });
+
+        return MappingCheckedFuture.create(transformedFuture, ReadFailedException.MAPPER);
+    }
+
+    @Override
+    public void close() {
+        // NOOP
+    }
+
+    @Override
+    public CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> read(
+            final LogicalDatastoreType store, final YangInstanceIdentifier path) {
+        switch (store) {
+        case CONFIGURATION: {
+            return readConfigurationData(path);
+        }
+        case OPERATIONAL: {
+            return readOperationalData(path);
+        }
+        }
+
+        throw new IllegalArgumentException(String.format("%s, Cannot read data %s for %s datastore, unknown datastore type", id, path, store));
+    }
+
+    @Override
+    public CheckedFuture<Boolean, ReadFailedException> exists(final LogicalDatastoreType store, final YangInstanceIdentifier path) {
+        final CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> data = read(store, path);
+
+        try {
+            return Futures.immediateCheckedFuture(data.get().isPresent());
+        } catch (InterruptedException | ExecutionException e) {
+            return Futures.immediateFailedCheckedFuture(new ReadFailedException("Exists failed",e));
+        }
+    }
+
+    @Override
+    public Object getIdentifier() {
+        return this;
+    }
+}
diff --git a/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/ReadWriteTx.java b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/ReadWriteTx.java
new file mode 100644 (file)
index 0000000..54db24c
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.connect.netconf.sal.tx;
+
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import java.util.concurrent.ExecutionException;
+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.TransactionCommitFailedException;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataReadTransaction;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
+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 ReadWriteTx implements DOMDataReadWriteTransaction {
+
+    private final DOMDataReadTransaction delegateReadTx;
+    private final DOMDataWriteTransaction delegateWriteTx;
+
+    public ReadWriteTx(final DOMDataReadTransaction delegateReadTx, final DOMDataWriteTransaction delegateWriteTx) {
+        this.delegateReadTx = delegateReadTx;
+        this.delegateWriteTx = delegateWriteTx;
+    }
+
+    @Override
+    public boolean cancel() {
+        return delegateWriteTx.cancel();
+    }
+
+    @Override
+    public void put(final LogicalDatastoreType store, final YangInstanceIdentifier path, final NormalizedNode<?, ?> data) {
+        delegateWriteTx.put(store, path, data);
+    }
+
+    @Override
+    public void merge(final LogicalDatastoreType store, final YangInstanceIdentifier path, final NormalizedNode<?, ?> data) {
+        delegateWriteTx.merge(store, path, data);
+    }
+
+    @Override
+    public void delete(final LogicalDatastoreType store, final YangInstanceIdentifier path) {
+        delegateWriteTx.delete(store, path);
+    }
+
+    @Override
+    public CheckedFuture<Void, TransactionCommitFailedException> submit() {
+        return delegateWriteTx.submit();
+    }
+
+    @Override
+    public ListenableFuture<RpcResult<TransactionStatus>> commit() {
+        return delegateWriteTx.commit();
+    }
+
+    @Override
+    public CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> read(
+            final LogicalDatastoreType store, final YangInstanceIdentifier path) {
+        return delegateReadTx.read(store, path);
+    }
+
+    @Override public CheckedFuture<Boolean, ReadFailedException> exists(
+        final LogicalDatastoreType store,
+        final YangInstanceIdentifier path) {
+        final CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException>
+            data = read(store, path);
+
+        try {
+            return Futures.immediateCheckedFuture(data.get().isPresent());
+        } catch (InterruptedException | ExecutionException e) {
+            return Futures.immediateFailedCheckedFuture(new ReadFailedException("Exists failed",e));
+        }
+    }
+
+    @Override
+    public Object getIdentifier() {
+        return this;
+    }
+}
diff --git a/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/WriteCandidateRunningTx.java b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/WriteCandidateRunningTx.java
new file mode 100644 (file)
index 0000000..afd26ff
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.connect.netconf.sal.tx;
+
+import com.google.common.base.Function;
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.sal.connect.netconf.util.NetconfBaseOps;
+import org.opendaylight.controller.sal.connect.netconf.util.NetconfRpcFutureCallback;
+import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Tx implementation for netconf devices that support only candidate datastore and writable running
+ * The sequence goes exactly as with only candidate supported, with one addition:
+ * <ul>
+ *     <li>Running datastore is locked as the first thing and this lock has to succeed</li>
+ * </ul>
+ */
+public class WriteCandidateRunningTx extends WriteCandidateTx {
+
+    private static final Logger LOG  = LoggerFactory.getLogger(WriteCandidateRunningTx.class);
+
+    public WriteCandidateRunningTx(final RemoteDeviceId id, final NetconfBaseOps netOps, final boolean rollbackSupport, long requestTimeoutMillis) {
+        super(id, netOps, rollbackSupport, requestTimeoutMillis);
+    }
+
+    @Override
+    protected synchronized void init() {
+        lockRunning();
+        super.init();
+    }
+
+    @Override
+    protected void cleanupOnSuccess() {
+        super.cleanupOnSuccess();
+        unlockRunning();
+    }
+
+    private void lockRunning() {
+        try {
+            invokeBlocking("Lock running", new Function<NetconfBaseOps, ListenableFuture<DOMRpcResult>>() {
+                @Override
+                public ListenableFuture<DOMRpcResult> apply(final NetconfBaseOps input) {
+                    return input.lockRunning(new NetconfRpcFutureCallback("Lock running", id));
+                }
+            });
+        } catch (final NetconfDocumentedException e) {
+            LOG.warn("{}: Failed to lock running. Failed to initialize transaction", id, e);
+            finished = true;
+            throw new RuntimeException(id + ": Failed to lock running. Failed to initialize transaction", e);
+        }
+    }
+
+    /**
+     * This has to be non blocking since it is called from a callback on commit and its netty threadpool that is really sensitive to blocking calls
+     */
+    private void unlockRunning() {
+        netOps.unlockRunning(new NetconfRpcFutureCallback("Unlock running", id));
+    }
+}
diff --git a/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/WriteCandidateTx.java b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/WriteCandidateTx.java
new file mode 100644 (file)
index 0000000..5c83366
--- /dev/null
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.connect.netconf.sal.tx;
+
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.sal.connect.netconf.util.NetconfBaseOps;
+import org.opendaylight.controller.sal.connect.netconf.util.NetconfRpcFutureCallback;
+import org.opendaylight.controller.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;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Tx implementation for netconf devices that support only candidate datastore and no writable running
+ * The sequence goes as:
+ * <ol>
+ * <li/> Lock candidate datastore on tx construction
+ *  <ul>
+ * <li/> Lock has to succeed, if it does not, an attempt to discard changes is made
+ * <li/> Discard changes has to succeed
+ * <li/> If discard is successful, lock is reattempted
+ * <li/> Second lock attempt has to succeed
+ * </ul>
+ * <li/> Edit-config in candidate N times
+ * <ul>
+ * <li/> If any issue occurs during edit, datastore is discarded using discard-changes rpc, unlocked and an exception is thrown async
+ * </ul>
+ * <li/> Commit and Unlock candidate datastore async
+ * </ol>
+ */
+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, long requestTimeoutMillis) {
+        super(requestTimeoutMillis, rpc, id, rollbackSupport);
+    }
+
+    @Override
+    protected synchronized void init() {
+        LOG.trace("{}: Initializing {} transaction", id, getClass().getSimpleName());
+
+        try {
+            lock();
+        } catch (final NetconfDocumentedException e) {
+            try {
+                LOG.warn("{}: Failed to lock candidate, attempting discard changes", id);
+                discardChanges();
+                LOG.warn("{}: Changes discarded successfully, attempting lock", id);
+                lock();
+            } catch (final NetconfDocumentedException secondE) {
+                LOG.error("{}: Failed to prepare candidate. Failed to initialize transaction", id, secondE);
+                throw new RuntimeException(id + ": Failed to prepare candidate. Failed to initialize transaction", secondE);
+            }
+        }
+    }
+
+    private void lock() throws NetconfDocumentedException {
+        try {
+            invokeBlocking("Lock candidate", new Function<NetconfBaseOps, ListenableFuture<DOMRpcResult>>() {
+                @Override
+                public ListenableFuture<DOMRpcResult> apply(final NetconfBaseOps input) {
+                    return input.lockCandidate(new NetconfRpcFutureCallback("Lock candidate", id));
+                }
+            });
+        } catch (final NetconfDocumentedException e) {
+            LOG.warn("{}: Failed to lock candidate", id, e);
+            throw e;
+        }
+    }
+
+    @Override
+    protected void cleanup() {
+        discardChanges();
+        cleanupOnSuccess();
+    }
+
+    @Override
+    protected void handleEditException(final YangInstanceIdentifier path, final NormalizedNode<?, ?> data, final NetconfDocumentedException e, final String editType) {
+        LOG.warn("{}: Error {} data to (candidate){}, data: {}, canceling", id, editType, path, data, e);
+        cancel();
+        throw new RuntimeException(id + ": Error while " + editType + ": (candidate)" + path, e);
+    }
+
+    @Override
+    protected void handleDeleteException(final YangInstanceIdentifier path, final NetconfDocumentedException e) {
+        LOG.warn("{}: Error deleting data (candidate){}, canceling", id, path, e);
+        cancel();
+        throw new RuntimeException(id + ": Error while deleting (candidate)" + path, e);
+    }
+
+    @Override
+    public synchronized CheckedFuture<Void, TransactionCommitFailedException> submit() {
+        final ListenableFuture<Void> commitFutureAsVoid = Futures.transform(commit(), new Function<RpcResult<TransactionStatus>, Void>() {
+            @Override
+            public Void apply(final RpcResult<TransactionStatus> input) {
+                Preconditions.checkArgument(input.isSuccessful() && input.getErrors().isEmpty(), "Submit failed with errors: %s", input.getErrors());
+                return null;
+            }
+        });
+
+        return Futures.makeChecked(commitFutureAsVoid, new Function<Exception, TransactionCommitFailedException>() {
+            @Override
+            public TransactionCommitFailedException apply(final Exception input) {
+                return new TransactionCommitFailedException("Submit of transaction " + getIdentifier() + " failed", input);
+            }
+        });
+    }
+
+    /**
+     * This has to be non blocking since it is called from a callback on commit and its netty threadpool that is really sensitive to blocking calls
+     */
+    private void discardChanges() {
+        netOps.discardChanges(new NetconfRpcFutureCallback("Discarding candidate", id));
+    }
+
+    @Override
+    public synchronized ListenableFuture<RpcResult<TransactionStatus>> performCommit() {
+        final ListenableFuture<DOMRpcResult> rpcResult = netOps.commit(new NetconfRpcFutureCallback("Commit", id) {
+            @Override
+            public void onSuccess(final DOMRpcResult result) {
+                super.onSuccess(result);
+                LOG.debug("{}: Write successful, transaction: {}. Unlocking", id, getIdentifier());
+                cleanupOnSuccess();
+            }
+
+            @Override
+            protected void onUnsuccess(final DOMRpcResult result) {
+                LOG.error("{}: Write failed, transaction {}, discarding changes, unlocking: {}", id, getIdentifier(), result.getErrors());
+                cleanup();
+            }
+
+            @Override
+            public void onFailure(final Throwable t) {
+                LOG.error("{}: Write failed, transaction {}, discarding changes, unlocking", id, getIdentifier(), t);
+                cleanup();
+            }
+        });
+
+        return Futures.transform(rpcResult, RPC_RESULT_TO_TX_STATUS);
+    }
+
+    protected void cleanupOnSuccess() {
+        unlock();
+    }
+
+    @Override
+    protected void editConfig(final DataContainerChild<?, ?> editStructure, final Optional<ModifyAction> defaultOperation) throws NetconfDocumentedException {
+        invokeBlocking("Edit candidate", new Function<NetconfBaseOps, ListenableFuture<DOMRpcResult>>() {
+            @Override
+            public ListenableFuture<DOMRpcResult> apply(final NetconfBaseOps input) {
+                    return defaultOperation.isPresent()
+                            ? input.editConfigCandidate(new NetconfRpcFutureCallback("Edit candidate", id), editStructure, defaultOperation.get(),
+                            rollbackSupport)
+                            : input.editConfigCandidate(new NetconfRpcFutureCallback("Edit candidate", id), editStructure,
+                            rollbackSupport);
+            }
+        });
+    }
+
+    /**
+     * This has to be non blocking since it is called from a callback on commit and its netty threadpool that is really sensitive to blocking calls
+     */
+    private void unlock() {
+        netOps.unlockCandidate(new NetconfRpcFutureCallback("Unlock candidate", id));
+    }
+
+}
diff --git a/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/WriteRunningTx.java b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/WriteRunningTx.java
new file mode 100644 (file)
index 0000000..dc82e86
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.connect.netconf.sal.tx;
+
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.sal.connect.netconf.util.NetconfBaseOps;
+import org.opendaylight.controller.sal.connect.netconf.util.NetconfRpcFutureCallback;
+import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
+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;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Tx implementation for netconf devices that support only writable-running with no candidate
+ * The sequence goes as:
+ * <ol>
+ * <li/> Lock running datastore on tx construction
+ * <ul>
+ * <li/> Lock has to succeed, if it does not, transaction is failed
+ * </ul>
+ * <li/> Edit-config in running N times
+ * <ul>
+ * <li/> If any issue occurs during edit, datastore is unlocked and an exception is thrown
+ * </ul>
+ * <li/> Unlock running datastore on tx commit
+ * </ol>
+ */
+public class WriteRunningTx extends AbstractWriteTx {
+
+    private static final Logger LOG  = LoggerFactory.getLogger(WriteRunningTx.class);
+
+    public WriteRunningTx(final RemoteDeviceId id, final NetconfBaseOps netOps,
+                          final boolean rollbackSupport, long requestTimeoutMillis) {
+        super(requestTimeoutMillis, netOps, id, rollbackSupport);
+    }
+
+    @Override
+    protected synchronized void init() {
+        lock();
+    }
+
+    private void lock() {
+        try {
+            invokeBlocking("Lock running", new Function<NetconfBaseOps, ListenableFuture<DOMRpcResult>>() {
+                @Override
+                public ListenableFuture<DOMRpcResult> apply(final NetconfBaseOps input) {
+                    return input.lockRunning(new NetconfRpcFutureCallback("Lock running", id));
+                }
+            });
+        } catch (final NetconfDocumentedException e) {
+            LOG.warn("{}: Failed to initialize netconf transaction (lock running)", id, e);
+            finished = true;
+            throw new RuntimeException(id + ": Failed to initialize netconf transaction (lock running)", e);
+        }
+    }
+
+    @Override
+    protected void cleanup() {
+        unlock();
+    }
+
+    @Override
+    protected void handleEditException(final YangInstanceIdentifier path, final NormalizedNode<?, ?> data, final NetconfDocumentedException e, final String editType) {
+        LOG.warn("{}: Error {} data to (running){}, data: {}, canceling", id, editType, path, data, e);
+        cancel();
+        throw new RuntimeException(id + ": Error while " + editType + ": (running)" + path, e);
+    }
+
+    @Override
+    protected void handleDeleteException(final YangInstanceIdentifier path, final NetconfDocumentedException e) {
+        LOG.warn("{}: Error deleting data (running){}, canceling", id, path, e);
+        cancel();
+        throw new RuntimeException(id + ": Error while deleting (running)" + path, e);
+    }
+
+    @Override
+    public synchronized CheckedFuture<Void, TransactionCommitFailedException> submit() {
+        final ListenableFuture<Void> commmitFutureAsVoid = Futures.transform(commit(), new Function<RpcResult<TransactionStatus>, Void>() {
+            @Override
+            public Void apply(final RpcResult<TransactionStatus> input) {
+                return null;
+            }
+        });
+
+        return Futures.makeChecked(commmitFutureAsVoid, new Function<Exception, TransactionCommitFailedException>() {
+            @Override
+            public TransactionCommitFailedException apply(final Exception input) {
+                return new TransactionCommitFailedException("Submit of transaction " + getIdentifier() + " failed", input);
+            }
+        });
+    }
+
+    @Override
+    public synchronized ListenableFuture<RpcResult<TransactionStatus>> performCommit() {
+        unlock();
+        return Futures.immediateFuture(RpcResultBuilder.success(TransactionStatus.COMMITED).build());
+    }
+
+    @Override
+    protected void editConfig(final DataContainerChild<?, ?> editStructure, final Optional<ModifyAction> defaultOperation) throws NetconfDocumentedException {
+        invokeBlocking("Edit running", new Function<NetconfBaseOps, ListenableFuture<DOMRpcResult>>() {
+            @Override
+            public ListenableFuture<DOMRpcResult> apply(final NetconfBaseOps input) {
+                    return defaultOperation.isPresent()
+                            ? input.editConfigRunning(new NetconfRpcFutureCallback("Edit running", id), editStructure, defaultOperation.get(),
+                            rollbackSupport)
+                            : input.editConfigRunning(new NetconfRpcFutureCallback("Edit running", id), editStructure,
+                            rollbackSupport);
+            }
+        });
+    }
+
+    private void unlock() {
+        try {
+            invokeBlocking("Unlocking running", new Function<NetconfBaseOps, ListenableFuture<DOMRpcResult>>() {
+                @Override
+                public ListenableFuture<DOMRpcResult> apply(final NetconfBaseOps input) {
+                    return input.unlockRunning(new NetconfRpcFutureCallback("Unlock running", id));
+                }
+            });
+        } catch (final NetconfDocumentedException e) {
+            LOG.warn("{}: Failed to unlock running datastore", id, e);
+            throw new RuntimeException(id + ": Failed to unlock running datastore", e);
+        }
+    }
+}
diff --git a/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/schema/NetconfRemoteSchemaYangSourceProvider.java b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/schema/NetconfRemoteSchemaYangSourceProvider.java
new file mode 100644 (file)
index 0000000..4a7af82
--- /dev/null
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.connect.netconf.schema;
+
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.GET_SCHEMA_QNAME;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_DATA_QNAME;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.toId;
+import com.google.common.base.Charsets;
+import com.google.common.base.Function;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import javax.xml.transform.dom.DOMSource;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
+import org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil;
+import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.Yang;
+import org.opendaylight.yangtools.util.concurrent.ExceptionMapper;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.AnyXmlNode;
+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.LeafNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+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 org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Element;
+
+public final class NetconfRemoteSchemaYangSourceProvider implements SchemaSourceProvider<YangTextSchemaSource> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(NetconfRemoteSchemaYangSourceProvider.class);
+
+    private static final ExceptionMapper<SchemaSourceException> MAPPER = new ExceptionMapper<SchemaSourceException>(
+            "schemaDownload", SchemaSourceException.class) {
+        @Override
+        protected SchemaSourceException newWithCause(final String s, final Throwable throwable) {
+            return new SchemaSourceException(s, throwable);
+        }
+    };
+
+    private final DOMRpcService rpc;
+    private final RemoteDeviceId id;
+
+    public NetconfRemoteSchemaYangSourceProvider(final RemoteDeviceId id, final DOMRpcService rpc) {
+        this.id = id;
+        this.rpc = Preconditions.checkNotNull(rpc);
+    }
+
+    public static ContainerNode createGetSchemaRequest(final String moduleName, final Optional<String> revision) {
+        final QName identifierQName = QName.cachedReference(QName.create(NetconfMessageTransformUtil.GET_SCHEMA_QNAME, "identifier"));
+        final YangInstanceIdentifier.NodeIdentifier identifierId = new YangInstanceIdentifier.NodeIdentifier(identifierQName);
+        final LeafNode<String> identifier = Builders.<String>leafBuilder().withNodeIdentifier(identifierId).withValue(moduleName).build();
+
+        final QName formatQName = QName.cachedReference(QName.create(NetconfMessageTransformUtil.GET_SCHEMA_QNAME, "format"));
+        final YangInstanceIdentifier.NodeIdentifier formatId = new YangInstanceIdentifier.NodeIdentifier(formatQName);
+        final LeafNode<QName> format = Builders.<QName>leafBuilder().withNodeIdentifier(formatId).withValue(Yang.QNAME).build();
+
+        final DataContainerNodeAttrBuilder<YangInstanceIdentifier.NodeIdentifier, ContainerNode> builder = Builders.containerBuilder();
+
+        builder.withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(NetconfMessageTransformUtil.GET_SCHEMA_QNAME))
+                .withChild(identifier).withChild(format);
+
+        if(revision.isPresent()) {
+            final QName revisionQName = QName.cachedReference(QName.create(NetconfMessageTransformUtil.GET_SCHEMA_QNAME, "version"));
+            final YangInstanceIdentifier.NodeIdentifier revisionId = new YangInstanceIdentifier.NodeIdentifier(revisionQName);
+            final LeafNode<String> revisionNode = Builders.<String>leafBuilder().withNodeIdentifier(revisionId).withValue(revision.get()).build();
+
+            builder.withChild(revisionNode);
+        }
+
+        return builder.build();
+    }
+
+    private static Optional<String> getSchemaFromRpc(final RemoteDeviceId id, final NormalizedNode<?, ?> result) {
+        if (result == null) {
+            return Optional.absent();
+        }
+
+        final QName schemaWrapperNode = QName.cachedReference(QName.create(GET_SCHEMA_QNAME, NETCONF_DATA_QNAME.getLocalName()));
+        final Optional<DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?>> child = ((ContainerNode) result).getChild(toId(schemaWrapperNode));
+
+        Preconditions.checkState(child.isPresent() && child.get() instanceof AnyXmlNode,
+                "%s Unexpected response to get-schema, expected response with one child %s, but was %s", id,
+                schemaWrapperNode, result);
+
+        final DOMSource wrappedNode = ((AnyXmlNode) child.get()).getValue();
+        Preconditions.checkNotNull(wrappedNode.getNode());
+        final Element dataNode = (Element) wrappedNode.getNode();
+
+        return Optional.of(dataNode.getTextContent().trim());
+    }
+
+    @Override
+    public CheckedFuture<YangTextSchemaSource, SchemaSourceException> getSource(final SourceIdentifier sourceIdentifier) {
+        final String moduleName = sourceIdentifier.getName();
+
+        // If formatted revision is SourceIdentifier.NOT_PRESENT_FORMATTED_REVISION, we have to omit it from request
+        final String formattedRevision = sourceIdentifier.getRevision().equals(SourceIdentifier.NOT_PRESENT_FORMATTED_REVISION) ? null : sourceIdentifier.getRevision();
+        final Optional<String> revision = Optional.fromNullable(formattedRevision);
+        final NormalizedNode<?, ?> getSchemaRequest = createGetSchemaRequest(moduleName, revision);
+
+        LOG.trace("{}: Loading YANG schema source for {}:{}", id, moduleName,
+                revision);
+
+        final ListenableFuture<YangTextSchemaSource> transformed = Futures.transform(
+                rpc.invokeRpc(SchemaPath.create(true, NetconfMessageTransformUtil.GET_SCHEMA_QNAME), getSchemaRequest),
+                new ResultToYangSourceTransformer(id, sourceIdentifier, moduleName, revision));
+
+        final CheckedFuture<YangTextSchemaSource, SchemaSourceException> checked = Futures.makeChecked(transformed, MAPPER);
+
+        // / FIXME remove this get, it is only present to wait until source is retrieved
+        // (goal is to limit concurrent schema download, since NetconfDevice listener does not handle concurrent messages properly)
+        // TODO retest this
+        try {
+            LOG.trace("{}: Blocking for {}", id, sourceIdentifier);
+            checked.checkedGet();
+        } catch (final SchemaSourceException e) {
+            return Futures.immediateFailedCheckedFuture(e);
+        }
+
+        return checked;
+    }
+
+    /**
+     * Transform composite node to string schema representation and then to ASTSchemaSource
+     */
+    private static final class ResultToYangSourceTransformer implements
+            Function<DOMRpcResult, YangTextSchemaSource> {
+
+        private final RemoteDeviceId id;
+        private final SourceIdentifier sourceIdentifier;
+        private final String moduleName;
+        private final Optional<String> revision;
+
+        public ResultToYangSourceTransformer(final RemoteDeviceId id, final SourceIdentifier sourceIdentifier,
+                final String moduleName, final Optional<String> revision) {
+            this.id = id;
+            this.sourceIdentifier = sourceIdentifier;
+            this.moduleName = moduleName;
+            this.revision = revision;
+        }
+
+        @Override
+        public YangTextSchemaSource apply(final DOMRpcResult input) {
+
+            if (input.getErrors().isEmpty()) {
+
+                final Optional<String> schemaString = getSchemaFromRpc(id, input.getResult());
+
+                Preconditions.checkState(schemaString.isPresent(),
+                        "%s: Unexpected response to get-schema, schema not present in message for: %s", id, sourceIdentifier);
+
+                LOG.debug("{}: YANG Schema successfully retrieved for {}:{}",
+                        id, moduleName, revision);
+                return new NetconfYangTextSchemaSource(id, sourceIdentifier, schemaString);
+            }
+
+            LOG.warn(
+                    "{}: YANG schema was not successfully retrieved for {}. Errors: {}",
+                    id, sourceIdentifier, input.getErrors());
+
+            throw new IllegalStateException(String.format(
+                    "%s: YANG schema was not successfully retrieved for %s. Errors: %s", id, sourceIdentifier,
+                    input.getErrors()));
+        }
+
+    }
+
+    private static class NetconfYangTextSchemaSource extends YangTextSchemaSource {
+        private final RemoteDeviceId id;
+        private final Optional<String> schemaString;
+
+        public NetconfYangTextSchemaSource(final RemoteDeviceId id, final SourceIdentifier sId, final Optional<String> schemaString) {
+            super(sId);
+            this.id = id;
+            this.schemaString = schemaString;
+        }
+
+        @Override
+        protected MoreObjects.ToStringHelper addToStringAttributes(final MoreObjects.ToStringHelper toStringHelper) {
+            return toStringHelper.add("device", id);
+        }
+
+        @Override
+        public InputStream openStream() throws IOException {
+            return new ByteArrayInputStream(schemaString.get().getBytes(Charsets.UTF_8));
+        }
+    }
+}
diff --git a/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/schema/mapping/NetconfMessageTransformer.java b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/schema/mapping/NetconfMessageTransformer.java
new file mode 100644 (file)
index 0000000..d210a77
--- /dev/null
@@ -0,0 +1,331 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.connect.netconf.schema.mapping;
+
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.EVENT_TIME;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_RPC_QNAME;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_URI;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.toPath;
+
+import com.google.common.base.Function;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Multimaps;
+import java.io.IOException;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.AbstractMap;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.annotation.Nonnull;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+import javax.xml.transform.dom.DOMResult;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.config.util.xml.MissingNameSpaceException;
+import org.opendaylight.controller.config.util.xml.XmlElement;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
+import org.opendaylight.controller.md.sal.dom.api.DOMEvent;
+import org.opendaylight.controller.md.sal.dom.api.DOMNotification;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
+import org.opendaylight.controller.md.sal.dom.spi.DefaultDOMRpcResult;
+import org.opendaylight.controller.netconf.api.NetconfMessage;
+import org.opendaylight.controller.netconf.notifications.NetconfNotification;
+import org.opendaylight.controller.netconf.util.OrderedNormalizedNodeWriter;
+import org.opendaylight.controller.sal.connect.api.MessageTransformer;
+import org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil;
+import org.opendaylight.controller.sal.connect.util.MessageCounter;
+import org.opendaylight.yangtools.sal.binding.generator.impl.ModuleInfoBackedContext;
+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.DataContainerChild;
+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.impl.codec.xml.XMLStreamNormalizedNodeStreamWriter;
+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.dom.parser.DomToNormalizedNodeParserFactory;
+import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
+import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+public class NetconfMessageTransformer implements MessageTransformer<NetconfMessage> {
+
+    public static final String MESSAGE_ID_PREFIX = "m";
+
+    private static final Logger LOG= LoggerFactory.getLogger(NetconfMessageTransformer.class);
+
+
+    private static final Function<SchemaNode, QName> QNAME_FUNCTION = new Function<SchemaNode, QName>() {
+        @Override
+        public QName apply(final SchemaNode rpcDefinition) {
+            return rpcDefinition.getQName();
+        }
+    };
+
+    private static final Function<SchemaNode, QName> QNAME_NOREV_FUNCTION = new Function<SchemaNode, QName>() {
+        @Override
+        public QName apply(final SchemaNode notification) {
+            return QNAME_FUNCTION.apply(notification).withoutRevision();
+        }
+    };
+    private static final SchemaContext BASE_NETCONF_CTX;
+
+    static {
+        try {
+            final ModuleInfoBackedContext moduleInfoBackedContext = ModuleInfoBackedContext.create();
+            moduleInfoBackedContext.addModuleInfos(
+                    Lists.newArrayList(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.base._1._0.rev110601.$YangModuleInfoImpl.getInstance()));
+            BASE_NETCONF_CTX = moduleInfoBackedContext.tryToCreateSchemaContext().get();
+        } catch (final RuntimeException e) {
+            LOG.error("Unable to prepare schema context for base netconf ops", e);
+            throw new ExceptionInInitializerError(e);
+        }
+    }
+    private static final Map<QName, RpcDefinition> MAPPED_BASE_RPCS = Maps.uniqueIndex(BASE_NETCONF_CTX.getOperations(), QNAME_FUNCTION);
+
+    private final SchemaContext schemaContext;
+    private final MessageCounter counter;
+    private final Map<QName, RpcDefinition> mappedRpcs;
+    private final Multimap<QName, NotificationDefinition> mappedNotifications;
+    private final DomToNormalizedNodeParserFactory parserFactory;
+
+    public NetconfMessageTransformer(final SchemaContext schemaContext, final boolean strictParsing) {
+        this.counter = new MessageCounter();
+        this.schemaContext = schemaContext;
+        parserFactory = DomToNormalizedNodeParserFactory.getInstance(XmlUtils.DEFAULT_XML_CODEC_PROVIDER, schemaContext, strictParsing);
+
+        mappedRpcs = Maps.uniqueIndex(schemaContext.getOperations(), QNAME_FUNCTION);
+        mappedNotifications = Multimaps.index(schemaContext.getNotifications(), QNAME_NOREV_FUNCTION);
+    }
+
+    @Override
+    public synchronized DOMNotification toNotification(final NetconfMessage message) {
+        final Map.Entry<Date, XmlElement> stripped = stripNotification(message);
+        final QName notificationNoRev;
+        try {
+            notificationNoRev = QName.create(stripped.getValue().getNamespace(), stripped.getValue().getName()).withoutRevision();
+        } catch (final MissingNameSpaceException e) {
+            throw new IllegalArgumentException("Unable to parse notification " + message + ", cannot find namespace", e);
+        }
+
+        final Collection<NotificationDefinition> notificationDefinitions = mappedNotifications.get(notificationNoRev);
+        Preconditions.checkArgument(notificationDefinitions.size() > 0,
+                "Unable to parse notification %s, unknown notification. Available notifications: %s", notificationDefinitions, mappedNotifications.keySet());
+
+        // FIXME if multiple revisions for same notifications are present, we should pick the most recent. Or ?
+        // We should probably just put the most recent notification versions into our map. We can expect that the device sends the data according to the latest available revision of a model.
+        final NotificationDefinition next = notificationDefinitions.iterator().next();
+
+        // We wrap the notification as a container node in order to reuse the parsers and builders for container node
+        final ContainerSchemaNode notificationAsContainerSchemaNode = NetconfMessageTransformUtil.createSchemaForNotification(next);
+        final ContainerNode content = parserFactory.getContainerNodeParser().parse(Collections.singleton(stripped.getValue().getDomElement()),
+                notificationAsContainerSchemaNode);
+        return new NetconfDeviceNotification(content, stripped.getKey());
+    }
+
+    private static final ThreadLocal<SimpleDateFormat> EVENT_TIME_FORMAT = new ThreadLocal<SimpleDateFormat>() {
+        protected SimpleDateFormat initialValue() {
+            return new SimpleDateFormat(NetconfNotification.RFC3339_DATE_FORMAT_BLUEPRINT);
+        }
+
+        public void set(SimpleDateFormat value) {
+            throw new UnsupportedOperationException();
+        }
+    };
+
+    // FIXME move somewhere to util
+    private static Map.Entry<Date, XmlElement> stripNotification(final NetconfMessage message) {
+        final XmlElement xmlElement = XmlElement.fromDomDocument(message.getDocument());
+        final List<XmlElement> childElements = xmlElement.getChildElements();
+        Preconditions.checkArgument(childElements.size() == 2, "Unable to parse notification %s, unexpected format", message);
+
+        final XmlElement eventTimeElement;
+        final XmlElement notificationElement;
+
+        if (childElements.get(0).getName().equals(EVENT_TIME)) {
+            eventTimeElement = childElements.get(0);
+            notificationElement = childElements.get(1);
+        }
+        else if(childElements.get(1).getName().equals(EVENT_TIME)) {
+            eventTimeElement = childElements.get(1);
+            notificationElement = childElements.get(0);
+        } else {
+            throw new IllegalArgumentException("Notification payload does not contain " + EVENT_TIME + " " + message);
+        }
+
+        try {
+            return new AbstractMap.SimpleEntry<>(EVENT_TIME_FORMAT.get().parse(eventTimeElement.getTextContent()), notificationElement);
+        } catch (DocumentedException e) {
+            throw new IllegalArgumentException("Notification payload does not contain " + EVENT_TIME + " " + message);
+        } catch (ParseException e) {
+            throw new IllegalArgumentException("Unable to parse event time from " + eventTimeElement, e);
+        }
+    }
+
+    @Override
+    public NetconfMessage toRpcRequest(SchemaPath rpc, final NormalizedNode<?, ?> payload) {
+        // In case no input for rpc is defined, we can simply construct the payload here
+        final QName rpcQName = rpc.getLastComponent();
+        Map<QName, RpcDefinition> currentMappedRpcs = mappedRpcs;
+
+        // Determine whether a base netconf operation is being invoked and also check if the device exposed model for base netconf
+        // If no, use pre built base netconf operations model
+        final boolean needToUseBaseCtx = mappedRpcs.get(rpcQName) == null && isBaseRpc(rpcQName);
+        if(needToUseBaseCtx) {
+            currentMappedRpcs = MAPPED_BASE_RPCS;
+        }
+
+        Preconditions.checkNotNull(currentMappedRpcs.get(rpcQName), "Unknown rpc %s, available rpcs: %s", rpcQName, currentMappedRpcs.keySet());
+        if(currentMappedRpcs.get(rpcQName).getInput() == null) {
+            return new NetconfMessage(prepareDomResultForRpcRequest(rpcQName).getNode().getOwnerDocument());
+        }
+
+        Preconditions.checkNotNull(payload, "Transforming an rpc with input: %s, payload cannot be null", rpcQName);
+        Preconditions.checkArgument(payload instanceof ContainerNode,
+                "Transforming an rpc with input: %s, payload has to be a container, but was: %s", rpcQName, payload);
+
+        // Set the path to the input of rpc for the node stream writer
+        rpc = rpc.createChild(QName.cachedReference(QName.create(rpcQName, "input")));
+        final DOMResult result = prepareDomResultForRpcRequest(rpcQName);
+
+        try {
+            // If the schema context for netconf device does not contain model for base netconf operations, use default pre build context with just the base model
+            // This way operations like lock/unlock are supported even if the source for base model was not provided
+            writeNormalizedRpc(((ContainerNode) payload), result, rpc, needToUseBaseCtx ? BASE_NETCONF_CTX : schemaContext);
+        } catch (final XMLStreamException | IOException | IllegalStateException e) {
+            throw new IllegalStateException("Unable to serialize " + rpc, e);
+        }
+
+        final Document node = result.getNode().getOwnerDocument();
+
+        return new NetconfMessage(node);
+    }
+
+    private static boolean isBaseRpc(final QName rpc) {
+        return rpc.getNamespace().equals(NETCONF_URI);
+    }
+
+    private DOMResult prepareDomResultForRpcRequest(final QName rpcQName) {
+        final Document document = XmlUtil.newDocument();
+        final Element rpcNS = document.createElementNS(NETCONF_RPC_QNAME.getNamespace().toString(), NETCONF_RPC_QNAME.getLocalName());
+        // set msg id
+        rpcNS.setAttribute(NetconfMessageTransformUtil.MESSAGE_ID_ATTR, counter.getNewMessageId(MESSAGE_ID_PREFIX));
+        final Element elementNS = document.createElementNS(rpcQName.getNamespace().toString(), rpcQName.getLocalName());
+        rpcNS.appendChild(elementNS);
+        document.appendChild(rpcNS);
+        return new DOMResult(elementNS);
+    }
+
+    private void writeNormalizedRpc(final ContainerNode normalized, final DOMResult result, final SchemaPath schemaPath, final SchemaContext baseNetconfCtx) throws IOException, XMLStreamException {
+        final OrderedNormalizedNodeWriter normalizedNodeWriter;
+        NormalizedNodeStreamWriter normalizedNodeStreamWriter = null;
+        XMLStreamWriter writer = null;
+        try {
+            writer = NetconfMessageTransformUtil.XML_FACTORY.createXMLStreamWriter(result);
+            normalizedNodeStreamWriter = XMLStreamNormalizedNodeStreamWriter.create(writer, baseNetconfCtx, schemaPath);
+            normalizedNodeWriter = new OrderedNormalizedNodeWriter(normalizedNodeStreamWriter, baseNetconfCtx, schemaPath);
+            Collection<DataContainerChild<?, ?>> value = (Collection) normalized.getValue();
+            normalizedNodeWriter.write(value);
+            normalizedNodeWriter.flush();
+        } finally {
+            try {
+                if(normalizedNodeStreamWriter != null) {
+                    normalizedNodeStreamWriter.close();
+                }
+                if(writer != null) {
+                    writer.close();
+                }
+            } catch (final Exception e) {
+                LOG.warn("Unable to close resource properly", e);
+            }
+        }
+    }
+
+    @Override
+    public synchronized DOMRpcResult toRpcResult(final NetconfMessage message, final SchemaPath rpc) {
+        final NormalizedNode<?, ?> normalizedNode;
+        final QName rpcQName = rpc.getLastComponent();
+        if (NetconfMessageTransformUtil.isDataRetrievalOperation(rpcQName)) {
+            final Element xmlData = NetconfMessageTransformUtil.getDataSubtree(message.getDocument());
+            final ContainerSchemaNode schemaForDataRead = NetconfMessageTransformUtil.createSchemaForDataRead(schemaContext);
+            final ContainerNode dataNode = parserFactory.getContainerNodeParser().parse(Collections.singleton(xmlData), schemaForDataRead);
+
+            normalizedNode = Builders.containerBuilder().withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(NetconfMessageTransformUtil.NETCONF_RPC_REPLY_QNAME))
+                    .withChild(dataNode).build();
+        } else {
+            final Set<Element> documentElement = Collections.singleton(message.getDocument().getDocumentElement());
+
+            Map<QName, RpcDefinition> currentMappedRpcs = mappedRpcs;
+
+            // Determine whether a base netconf operation is being invoked and also check if the device exposed model for base netconf
+            // If no, use pre built base netconf operations model
+            final boolean needToUseBaseCtx = mappedRpcs.get(rpcQName) == null && isBaseRpc(rpcQName);
+            if(needToUseBaseCtx) {
+                currentMappedRpcs = MAPPED_BASE_RPCS;
+            }
+
+            final RpcDefinition rpcDefinition = currentMappedRpcs.get(rpcQName);
+            Preconditions.checkArgument(rpcDefinition != null, "Unable to parse response of %s, the rpc is unknown", rpcQName);
+
+            // In case no input for rpc is defined, we can simply construct the payload here
+            if (rpcDefinition.getOutput() == null) {
+                Preconditions.checkArgument(XmlElement.fromDomDocument(message.getDocument()).getOnlyChildElementWithSameNamespaceOptionally("ok").isPresent(),
+                        "Unexpected content in response of rpc: %s, %s", rpcDefinition.getQName(), message);
+                normalizedNode = null;
+            } else {
+                normalizedNode = parserFactory.getContainerNodeParser().parse(documentElement, rpcDefinition.getOutput());
+            }
+        }
+        return new DefaultDOMRpcResult(normalizedNode);
+    }
+
+    private static class NetconfDeviceNotification implements DOMNotification, DOMEvent {
+        private final ContainerNode content;
+        private final SchemaPath schemaPath;
+        private final Date eventTime;
+
+        NetconfDeviceNotification(final ContainerNode content, final Date eventTime) {
+            this.content = content;
+            this.eventTime = eventTime;
+            this.schemaPath = toPath(content.getNodeType());
+        }
+
+        @Nonnull
+        @Override
+        public SchemaPath getType() {
+            return schemaPath;
+
+        }
+
+        @Nonnull
+        @Override
+        public ContainerNode getBody() {
+            return content;
+        }
+
+        @Override
+        public Date getEventTime() {
+            return eventTime;
+        }
+    }
+}
diff --git a/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/util/NetconfBaseOps.java b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/util/NetconfBaseOps.java
new file mode 100644 (file)
index 0000000..9cf1d2c
--- /dev/null
@@ -0,0 +1,287 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.connect.netconf.util;
+
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_CANDIDATE_QNAME;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_COPY_CONFIG_QNAME;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_DEFAULT_OPERATION_QNAME;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_DISCARD_CHANGES_QNAME;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_EDIT_CONFIG_QNAME;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_ERROR_OPTION_QNAME;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_GET_CONFIG_QNAME;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_GET_QNAME;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_LOCK_QNAME;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_RUNNING_QNAME;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_SOURCE_QNAME;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_TARGET_QNAME;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_UNLOCK_QNAME;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_VALIDATE_QNAME;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.ROLLBACK_ON_ERROR_OPTION;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.toFilterStructure;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.toId;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.toPath;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.base._1._0.rev110601.copy.config.input.target.ConfigTarget;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.base._1._0.rev110601.get.config.input.source.ConfigSource;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.ModifyAction;
+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.DataContainerChild;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+/**
+ * Provides base operations for netconf e.g. get, get-config, edit-config, (un)lock, commit etc.
+ * According to RFC-6241
+ */
+public final class NetconfBaseOps {
+
+    private final DOMRpcService rpc;
+    private final SchemaContext schemaContext;
+
+    public NetconfBaseOps(final DOMRpcService rpc, final SchemaContext schemaContext) {
+        this.rpc = rpc;
+        this.schemaContext = schemaContext;
+    }
+
+    public ListenableFuture<DOMRpcResult> lock(final FutureCallback<DOMRpcResult> callback, final QName datastore) {
+        Preconditions.checkNotNull(callback);
+        Preconditions.checkNotNull(datastore);
+
+        final ListenableFuture<DOMRpcResult> future = rpc.invokeRpc(toPath(NETCONF_LOCK_QNAME), getLockContent(datastore));
+        Futures.addCallback(future, callback);
+        return future;
+    }
+
+    public ListenableFuture<DOMRpcResult> lockCandidate(final FutureCallback<DOMRpcResult> callback) {
+        final ListenableFuture<DOMRpcResult> future = rpc.invokeRpc(toPath(NETCONF_LOCK_QNAME), getLockContent(NETCONF_CANDIDATE_QNAME));
+        Futures.addCallback(future, callback);
+        return future;
+    }
+
+
+    public ListenableFuture<DOMRpcResult> lockRunning(final FutureCallback<DOMRpcResult> callback) {
+        final ListenableFuture<DOMRpcResult> future = rpc.invokeRpc(toPath(NETCONF_LOCK_QNAME), getLockContent(NETCONF_RUNNING_QNAME));
+        Futures.addCallback(future, callback);
+        return future;
+    }
+
+    public ListenableFuture<DOMRpcResult> unlock(final FutureCallback<DOMRpcResult> callback, final QName datastore) {
+        Preconditions.checkNotNull(callback);
+        Preconditions.checkNotNull(datastore);
+
+        final ListenableFuture<DOMRpcResult> future = rpc.invokeRpc(toPath(NETCONF_UNLOCK_QNAME), getUnLockContent(datastore));
+        Futures.addCallback(future, callback);
+        return future;
+    }
+
+    public ListenableFuture<DOMRpcResult> unlockRunning(final FutureCallback<DOMRpcResult> callback) {
+        final ListenableFuture<DOMRpcResult> future = rpc.invokeRpc(toPath(NETCONF_UNLOCK_QNAME), getUnLockContent(NETCONF_RUNNING_QNAME));
+        Futures.addCallback(future, callback);
+        return future;
+    }
+
+    public ListenableFuture<DOMRpcResult> unlockCandidate(final FutureCallback<DOMRpcResult> callback) {
+        final ListenableFuture<DOMRpcResult> future = rpc.invokeRpc(toPath(NETCONF_UNLOCK_QNAME), getUnLockContent(NETCONF_CANDIDATE_QNAME));
+        Futures.addCallback(future, callback);
+        return future;
+    }
+
+    public ListenableFuture<DOMRpcResult> discardChanges(final FutureCallback<DOMRpcResult> callback) {
+        Preconditions.checkNotNull(callback);
+
+        final ListenableFuture<DOMRpcResult> future = rpc.invokeRpc(toPath(NETCONF_DISCARD_CHANGES_QNAME), null);
+        Futures.addCallback(future, callback);
+        return future;
+    }
+
+    public ListenableFuture<DOMRpcResult> commit(final FutureCallback<DOMRpcResult> callback) {
+        Preconditions.checkNotNull(callback);
+
+        final ListenableFuture<DOMRpcResult> future = rpc.invokeRpc(toPath(NetconfMessageTransformUtil.NETCONF_COMMIT_QNAME), NetconfMessageTransformUtil.COMMIT_RPC_CONTENT);
+        Futures.addCallback(future, callback);
+        return future;
+    }
+
+    public ListenableFuture<DOMRpcResult> validate(final FutureCallback<DOMRpcResult> callback, final QName datastore) {
+        Preconditions.checkNotNull(callback);
+        Preconditions.checkNotNull(datastore);
+
+        final ListenableFuture<DOMRpcResult> future = rpc.invokeRpc(toPath(NetconfMessageTransformUtil.NETCONF_VALIDATE_QNAME), getValidateContent(datastore));
+        Futures.addCallback(future, callback);
+        return future;
+    }
+
+    public ListenableFuture<DOMRpcResult> validateCandidate(final FutureCallback<DOMRpcResult> callback) {
+        return validate(callback, NETCONF_CANDIDATE_QNAME);
+    }
+
+
+    public ListenableFuture<DOMRpcResult> validateRunning(final FutureCallback<DOMRpcResult> callback) {
+        return validate(callback, NETCONF_RUNNING_QNAME);
+    }
+
+    public ListenableFuture<DOMRpcResult> copyConfig(final FutureCallback<DOMRpcResult> callback, final QName source, final QName target) {
+        Preconditions.checkNotNull(callback);
+        Preconditions.checkNotNull(source);
+        Preconditions.checkNotNull(target);
+
+        final ListenableFuture<DOMRpcResult> future = rpc.invokeRpc(toPath(NetconfMessageTransformUtil.NETCONF_COPY_CONFIG_QNAME), getCopyConfigContent(source, target));
+        Futures.addCallback(future, callback);
+        return future;
+    }
+
+    public ListenableFuture<DOMRpcResult> copyRunningToCandidate(final FutureCallback<DOMRpcResult> callback) {
+        return copyConfig(callback, NETCONF_RUNNING_QNAME, NETCONF_CANDIDATE_QNAME);
+    }
+
+    public ListenableFuture<DOMRpcResult> getConfig(final FutureCallback<DOMRpcResult> callback, final QName datastore, final Optional<YangInstanceIdentifier> filterPath) {
+        Preconditions.checkNotNull(callback);
+        Preconditions.checkNotNull(datastore);
+
+        final ListenableFuture<DOMRpcResult> future;
+        if (isFilterPresent(filterPath)) {
+            // FIXME the source node has to be wrapped in a choice
+            final DataContainerChild<?, ?> node = toFilterStructure(filterPath.get(), schemaContext);
+            future = rpc.invokeRpc(toPath(NETCONF_GET_CONFIG_QNAME),
+                            NetconfMessageTransformUtil.wrap(NETCONF_GET_CONFIG_QNAME, getSourceNode(datastore), node));
+        } else {
+            future = rpc.invokeRpc(toPath(NETCONF_GET_CONFIG_QNAME),
+                            NetconfMessageTransformUtil.wrap(NETCONF_GET_CONFIG_QNAME, getSourceNode(datastore)));
+        }
+
+        Futures.addCallback(future, callback);
+        return future;
+    }
+
+    public ListenableFuture<DOMRpcResult> getConfigRunning(final FutureCallback<DOMRpcResult> callback, final Optional<YangInstanceIdentifier> filterPath) {
+        return getConfig(callback, NETCONF_RUNNING_QNAME, filterPath);
+    }
+
+    public ListenableFuture<DOMRpcResult> getConfigCandidate(final FutureCallback<DOMRpcResult> callback, final Optional<YangInstanceIdentifier> filterPath) {
+        return getConfig(callback, NETCONF_CANDIDATE_QNAME, filterPath);
+    }
+
+    public ListenableFuture<DOMRpcResult> get(final FutureCallback<DOMRpcResult> callback, final Optional<YangInstanceIdentifier> filterPath) {
+        Preconditions.checkNotNull(callback);
+
+        final ListenableFuture<DOMRpcResult> future;
+
+        future = isFilterPresent(filterPath) ?
+                rpc.invokeRpc(toPath(NETCONF_GET_QNAME), NetconfMessageTransformUtil.wrap(NETCONF_GET_QNAME, toFilterStructure(filterPath.get(), schemaContext))) :
+                rpc.invokeRpc(toPath(NETCONF_GET_QNAME), NetconfMessageTransformUtil.GET_RPC_CONTENT);
+
+        Futures.addCallback(future, callback);
+        return future;
+    }
+
+    private boolean isFilterPresent(final Optional<YangInstanceIdentifier> filterPath) {
+        return filterPath.isPresent() && !filterPath.get().isEmpty();
+    }
+
+    public ListenableFuture<DOMRpcResult> editConfigCandidate(final FutureCallback<? super DOMRpcResult> callback, final DataContainerChild<?, ?> editStructure, final ModifyAction modifyAction, final boolean rollback) {
+        return editConfig(callback, NETCONF_CANDIDATE_QNAME, editStructure, Optional.of(modifyAction), rollback);
+    }
+
+    public ListenableFuture<DOMRpcResult> editConfigCandidate(final FutureCallback<? super DOMRpcResult> callback, final DataContainerChild<?, ?> editStructure, final boolean rollback) {
+        return editConfig(callback, NETCONF_CANDIDATE_QNAME, editStructure, Optional.<ModifyAction>absent(), rollback);
+    }
+
+    public ListenableFuture<DOMRpcResult> editConfigRunning(final FutureCallback<? super DOMRpcResult> callback, final DataContainerChild<?, ?> editStructure, final ModifyAction modifyAction, final boolean rollback) {
+        return editConfig(callback, NETCONF_RUNNING_QNAME, editStructure, Optional.of(modifyAction), rollback);
+    }
+
+    public ListenableFuture<DOMRpcResult> editConfigRunning(final FutureCallback<? super DOMRpcResult> callback, final DataContainerChild<?, ?> editStructure, final boolean rollback) {
+        return editConfig(callback, NETCONF_RUNNING_QNAME, editStructure, Optional.<ModifyAction>absent(), rollback);
+    }
+
+    public ListenableFuture<DOMRpcResult> editConfig(final FutureCallback<? super DOMRpcResult> callback, final QName datastore, final DataContainerChild<?, ?> editStructure, final Optional<ModifyAction> modifyAction, final boolean rollback) {
+        Preconditions.checkNotNull(editStructure);
+        Preconditions.checkNotNull(callback);
+        Preconditions.checkNotNull(datastore);
+
+        final ListenableFuture<DOMRpcResult> future = rpc.invokeRpc(toPath(NETCONF_EDIT_CONFIG_QNAME), getEditConfigContent(datastore, editStructure, modifyAction, rollback));
+
+        Futures.addCallback(future, callback);
+        return future;
+    }
+
+    public DataContainerChild<?, ?> createEditConfigStrcture(final Optional<NormalizedNode<?, ?>> lastChild, final Optional<ModifyAction> operation, final YangInstanceIdentifier dataPath) {
+        return NetconfMessageTransformUtil.createEditConfigStructure(schemaContext, dataPath, operation, lastChild);
+    }
+
+    private ContainerNode getEditConfigContent(final QName datastore, final DataContainerChild<?, ?> editStructure, final Optional<ModifyAction> defaultOperation, final boolean rollback) {
+        final DataContainerNodeAttrBuilder<YangInstanceIdentifier.NodeIdentifier, ContainerNode> editBuilder = Builders.containerBuilder().withNodeIdentifier(toId(NETCONF_EDIT_CONFIG_QNAME));
+
+        // Target
+        editBuilder.withChild(getTargetNode(datastore));
+
+        // Default operation
+        if(defaultOperation.isPresent()) {
+            final String opString = defaultOperation.get().name().toLowerCase();
+            editBuilder.withChild(Builders.leafBuilder().withNodeIdentifier(toId(NETCONF_DEFAULT_OPERATION_QNAME)).withValue(opString).build());
+        }
+
+        // Error option
+        if(rollback) {
+            editBuilder.withChild(Builders.leafBuilder().withNodeIdentifier(toId(NETCONF_ERROR_OPTION_QNAME)).withValue(ROLLBACK_ON_ERROR_OPTION).build());
+        }
+
+        // Edit content
+        editBuilder.withChild(editStructure);
+        return editBuilder.build();
+    }
+
+    public static DataContainerChild<?, ?> getSourceNode(final QName datastore) {
+        return Builders.containerBuilder().withNodeIdentifier(toId(NETCONF_SOURCE_QNAME))
+                .withChild(
+                        Builders.choiceBuilder().withNodeIdentifier(toId(ConfigSource.QNAME)).withChild(
+                                Builders.leafBuilder().withNodeIdentifier(toId(datastore)).build()).build()
+                ).build();
+    }
+
+    public static ContainerNode getLockContent(final QName datastore) {
+        return Builders.containerBuilder().withNodeIdentifier(toId(NETCONF_LOCK_QNAME))
+                .withChild(getTargetNode(datastore)).build();
+    }
+
+    public static DataContainerChild<?, ?> getTargetNode(final QName datastore) {
+        return Builders.containerBuilder().withNodeIdentifier(toId(NETCONF_TARGET_QNAME))
+                .withChild(
+                        Builders.choiceBuilder().withNodeIdentifier(toId(ConfigTarget.QNAME)).withChild(
+                                Builders.leafBuilder().withNodeIdentifier(toId(datastore)).build()).build()
+                ).build();
+    }
+
+    public static NormalizedNode<?, ?> getCopyConfigContent(final QName source, final QName target) {
+        return Builders.containerBuilder().withNodeIdentifier(toId(NETCONF_COPY_CONFIG_QNAME))
+                .withChild(getTargetNode(target)).withChild(getSourceNode(source)).build();
+    }
+
+    public static NormalizedNode<?, ?> getValidateContent(final QName source) {
+        return Builders.containerBuilder().withNodeIdentifier(toId(NETCONF_VALIDATE_QNAME))
+                .withChild(getSourceNode(source)).build();
+    }
+
+    public static NormalizedNode<?, ?> getUnLockContent(final QName datastore) {
+        return Builders.containerBuilder().withNodeIdentifier(toId(NETCONF_UNLOCK_QNAME))
+                .withChild(getTargetNode(datastore)).build();
+    }
+
+}
diff --git a/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/util/NetconfMessageTransformUtil.java b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/util/NetconfMessageTransformUtil.java
new file mode 100644 (file)
index 0000000..c345580
--- /dev/null
@@ -0,0 +1,338 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.connect.netconf.util;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import java.io.IOException;
+import java.net.URI;
+import java.util.AbstractMap;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Map.Entry;
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+import javax.xml.transform.dom.DOMResult;
+import javax.xml.transform.dom.DOMSource;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.netconf.api.NetconfMessage;
+import org.opendaylight.controller.netconf.util.messages.NetconfMessageUtil;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.base._1._0.rev110601.edit.config.input.EditContent;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.CreateSubscriptionInput;
+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.notifications.rev120206.NetconfCapabilityChange;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.RpcError;
+import org.opendaylight.yangtools.yang.common.RpcError.ErrorSeverity;
+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.AnyXmlNode;
+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.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
+import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter;
+import org.opendaylight.yangtools.yang.data.impl.codec.xml.XMLStreamNormalizedNodeStreamWriter;
+import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeAttrBuilder;
+import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+public class NetconfMessageTransformUtil {
+
+    private static final Logger LOG= LoggerFactory.getLogger(NetconfMessageTransformUtil.class);
+
+    public static final String MESSAGE_ID_ATTR = "message-id";
+    public static final XMLOutputFactory XML_FACTORY;
+
+    static {
+        XML_FACTORY = XMLOutputFactory.newFactory();
+        XML_FACTORY.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, false);
+    }
+
+    public static final QName CREATE_SUBSCRIPTION_RPC_QNAME = QName.cachedReference(QName.create(CreateSubscriptionInput.QNAME, "create-subscription"));
+    private static final String SUBTREE = "subtree";
+
+    // Blank document used for creation of new DOM nodes
+    private static final Document BLANK_DOCUMENT = XmlUtil.newDocument();
+    public static final String EVENT_TIME = "eventTime";
+
+    private NetconfMessageTransformUtil() {}
+
+    public static final QName IETF_NETCONF_MONITORING = QName.create(NetconfState.QNAME, "ietf-netconf-monitoring");
+    public static final QName GET_DATA_QNAME = QName.create(IETF_NETCONF_MONITORING, "data");
+    public static final QName GET_SCHEMA_QNAME = QName.create(IETF_NETCONF_MONITORING, "get-schema");
+    public static final QName IETF_NETCONF_MONITORING_SCHEMA_FORMAT = QName.create(IETF_NETCONF_MONITORING, "format");
+    public static final QName IETF_NETCONF_MONITORING_SCHEMA_LOCATION = QName.create(IETF_NETCONF_MONITORING, "location");
+    public static final QName IETF_NETCONF_MONITORING_SCHEMA_IDENTIFIER = QName.create(IETF_NETCONF_MONITORING, "identifier");
+    public static final QName IETF_NETCONF_MONITORING_SCHEMA_VERSION = QName.create(IETF_NETCONF_MONITORING, "version");
+    public static final QName IETF_NETCONF_MONITORING_SCHEMA_NAMESPACE = QName.create(IETF_NETCONF_MONITORING, "namespace");
+
+    public static final QName IETF_NETCONF_NOTIFICATIONS = QName.create(NetconfCapabilityChange.QNAME, "ietf-netconf-notifications");
+
+    public static final QName NETCONF_QNAME = QName.cachedReference(QName.create("urn:ietf:params:xml:ns:netconf:base:1.0", "2011-06-01", "netconf"));
+    public static final URI NETCONF_URI = NETCONF_QNAME.getNamespace();
+
+    public static final QName NETCONF_DATA_QNAME = QName.create(NETCONF_QNAME, "data");
+    public static final QName NETCONF_RPC_REPLY_QNAME = QName.create(NETCONF_QNAME, "rpc-reply");
+    public static final QName NETCONF_OK_QNAME = QName.create(NETCONF_QNAME, "ok");
+    public static final QName NETCONF_ERROR_OPTION_QNAME = QName.create(NETCONF_QNAME, "error-option");
+    public static final QName NETCONF_RUNNING_QNAME = QName.create(NETCONF_QNAME, "running");
+    public static final QName NETCONF_SOURCE_QNAME = QName.create(NETCONF_QNAME, "source");
+    public static final QName NETCONF_CANDIDATE_QNAME = QName.create(NETCONF_QNAME, "candidate");
+    public static final QName NETCONF_TARGET_QNAME = QName.create(NETCONF_QNAME, "target");
+    public static final QName NETCONF_CONFIG_QNAME = QName.create(NETCONF_QNAME, "config");
+    public static final QName NETCONF_COMMIT_QNAME = QName.create(NETCONF_QNAME, "commit");
+    public static final QName NETCONF_VALIDATE_QNAME = QName.create(NETCONF_QNAME, "validate");
+    public static final QName NETCONF_COPY_CONFIG_QNAME = QName.create(NETCONF_QNAME, "copy-config");
+    public static final QName NETCONF_OPERATION_QNAME = QName.create(NETCONF_QNAME, "operation");
+    public static final QName NETCONF_DEFAULT_OPERATION_QNAME = QName.create(NETCONF_OPERATION_QNAME, "default-operation");
+    public static final QName NETCONF_EDIT_CONFIG_QNAME = QName.create(NETCONF_QNAME, "edit-config");
+    public static final QName NETCONF_GET_CONFIG_QNAME = QName.create(NETCONF_QNAME, "get-config");
+    public static final QName NETCONF_DISCARD_CHANGES_QNAME = QName.create(NETCONF_QNAME, "discard-changes");
+    public static final QName NETCONF_TYPE_QNAME = QName.create(NETCONF_QNAME, "type");
+    public static final QName NETCONF_FILTER_QNAME = QName.create(NETCONF_QNAME, "filter");
+    public static final QName NETCONF_GET_QNAME = QName.create(NETCONF_QNAME, "get");
+    public static final QName NETCONF_RPC_QNAME = QName.create(NETCONF_QNAME, "rpc");
+
+    public static final URI NETCONF_ROLLBACK_ON_ERROR_URI = URI
+            .create("urn:ietf:params:netconf:capability:rollback-on-error:1.0");
+    public static final String ROLLBACK_ON_ERROR_OPTION = "rollback-on-error";
+
+    public static final URI NETCONF_CANDIDATE_URI = URI
+            .create("urn:ietf:params:netconf:capability:candidate:1.0");
+
+    public static final URI NETCONF_NOTIFICATONS_URI = URI
+            .create("urn:ietf:params:netconf:capability:notification:1.0");
+
+    public static final URI NETCONF_RUNNING_WRITABLE_URI = URI
+            .create("urn:ietf:params:netconf:capability:writable-running:1.0");
+
+    public static final QName NETCONF_LOCK_QNAME = QName.create(NETCONF_QNAME, "lock");
+    public static final QName NETCONF_UNLOCK_QNAME = QName.create(NETCONF_QNAME, "unlock");
+
+    // Discard changes message
+    public static final ContainerNode DISCARD_CHANGES_RPC_CONTENT =
+            Builders.containerBuilder().withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(NETCONF_DISCARD_CHANGES_QNAME)).build();
+
+    // Commit changes message
+    public static final ContainerNode COMMIT_RPC_CONTENT =
+            Builders.containerBuilder().withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(NETCONF_COMMIT_QNAME)).build();
+
+    // Get message
+    public static final ContainerNode GET_RPC_CONTENT =
+            Builders.containerBuilder().withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(NETCONF_GET_QNAME)).build();
+
+    // Create-subscription changes message
+    public static final ContainerNode CREATE_SUBSCRIPTION_RPC_CONTENT =
+            Builders.containerBuilder().withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(CREATE_SUBSCRIPTION_RPC_QNAME)).build();
+
+    public static final DataContainerChild<?, ?> EMPTY_FILTER;
+
+    static {
+        final NormalizedNodeAttrBuilder<YangInstanceIdentifier.NodeIdentifier, DOMSource, AnyXmlNode> anyXmlBuilder = Builders.anyXmlBuilder().withNodeIdentifier(toId(NETCONF_FILTER_QNAME));
+        anyXmlBuilder.withAttributes(Collections.singletonMap(NETCONF_TYPE_QNAME, SUBTREE));
+
+        final Element element = XmlUtil.createElement(BLANK_DOCUMENT, NETCONF_FILTER_QNAME.getLocalName(), Optional.of(NETCONF_FILTER_QNAME.getNamespace().toString()));
+        element.setAttributeNS(NETCONF_FILTER_QNAME.getNamespace().toString(), NETCONF_TYPE_QNAME.getLocalName(), "subtree");
+
+        anyXmlBuilder.withValue(new DOMSource(element));
+
+        EMPTY_FILTER = anyXmlBuilder.build();
+    }
+
+    public static DataContainerChild<?, ?> toFilterStructure(final YangInstanceIdentifier identifier, final SchemaContext ctx) {
+        final NormalizedNodeAttrBuilder<YangInstanceIdentifier.NodeIdentifier, DOMSource, AnyXmlNode> anyXmlBuilder = Builders.anyXmlBuilder().withNodeIdentifier(toId(NETCONF_FILTER_QNAME));
+        anyXmlBuilder.withAttributes(Collections.singletonMap(NETCONF_TYPE_QNAME, SUBTREE));
+
+        final NormalizedNode<?, ?> filterContent = ImmutableNodes.fromInstanceId(ctx, identifier);
+
+        final Element element = XmlUtil.createElement(BLANK_DOCUMENT, NETCONF_FILTER_QNAME.getLocalName(), Optional.of(NETCONF_FILTER_QNAME.getNamespace().toString()));
+        element.setAttributeNS(NETCONF_FILTER_QNAME.getNamespace().toString(), NETCONF_TYPE_QNAME.getLocalName(), "subtree");
+
+        try {
+            writeNormalizedNode(filterContent, new DOMResult(element), SchemaPath.ROOT, ctx);
+        } catch (IOException | XMLStreamException e) {
+            throw new IllegalStateException("Unable to serialize filter element for path " + identifier, e);
+        }
+        anyXmlBuilder.withValue(new DOMSource(element));
+
+        return anyXmlBuilder.build();
+    }
+
+    public static void checkValidReply(final NetconfMessage input, final NetconfMessage output)
+            throws NetconfDocumentedException {
+        final String inputMsgId = input.getDocument().getDocumentElement().getAttribute(MESSAGE_ID_ATTR);
+        final String outputMsgId = output.getDocument().getDocumentElement().getAttribute(MESSAGE_ID_ATTR);
+
+        if(inputMsgId.equals(outputMsgId) == false) {
+            final Map<String,String> errorInfo = ImmutableMap.<String,String>builder()
+                    .put( "actual-message-id", outputMsgId )
+                    .put( "expected-message-id", inputMsgId )
+                    .build();
+
+            throw new NetconfDocumentedException( "Response message contained unknown \"message-id\"",
+                    null, NetconfDocumentedException.ErrorType.protocol,
+                    NetconfDocumentedException.ErrorTag.bad_attribute,
+                    NetconfDocumentedException.ErrorSeverity.error, errorInfo );
+        }
+    }
+
+    public static void checkSuccessReply(final NetconfMessage output) throws NetconfDocumentedException {
+        if(NetconfMessageUtil.isErrorMessage(output)) {
+            throw NetconfDocumentedException.fromXMLDocument(output.getDocument());
+        }
+    }
+
+    public static RpcError toRpcError( final NetconfDocumentedException ex ) {
+        final StringBuilder infoBuilder = new StringBuilder();
+        final Map<String, String> errorInfo = ex.getErrorInfo();
+        if(errorInfo != null) {
+            for( final Entry<String,String> e: errorInfo.entrySet() ) {
+                infoBuilder.append( '<' ).append( e.getKey() ).append( '>' ).append( e.getValue() )
+                .append( "</" ).append( e.getKey() ).append( '>' );
+
+            }
+        }
+
+        final ErrorSeverity severity = toRpcErrorSeverity( ex.getErrorSeverity() );
+        return severity == ErrorSeverity.ERROR ?
+                RpcResultBuilder.newError(
+                        toRpcErrorType( ex.getErrorType() ), ex.getErrorTag().getTagValue(),
+                        ex.getLocalizedMessage(), null, infoBuilder.toString(), ex.getCause() ) :
+                            RpcResultBuilder.newWarning(
+                                    toRpcErrorType( ex.getErrorType() ), ex.getErrorTag().getTagValue(),
+                                    ex.getLocalizedMessage(), null, infoBuilder.toString(), ex.getCause() );
+    }
+
+    private static ErrorSeverity toRpcErrorSeverity( final NetconfDocumentedException.ErrorSeverity severity ) {
+        switch (severity) {
+        case warning:
+            return RpcError.ErrorSeverity.WARNING;
+        default:
+            return RpcError.ErrorSeverity.ERROR;
+        }
+    }
+
+    private static RpcError.ErrorType toRpcErrorType(final NetconfDocumentedException.ErrorType type) {
+        switch (type) {
+        case protocol:
+            return RpcError.ErrorType.PROTOCOL;
+        case rpc:
+            return RpcError.ErrorType.RPC;
+        case transport:
+            return RpcError.ErrorType.TRANSPORT;
+        default:
+            return RpcError.ErrorType.APPLICATION;
+        }
+    }
+
+    public static YangInstanceIdentifier.NodeIdentifier toId(final YangInstanceIdentifier.PathArgument qname) {
+        return toId(qname.getNodeType());
+    }
+
+    public static YangInstanceIdentifier.NodeIdentifier toId(final QName nodeType) {
+        return new YangInstanceIdentifier.NodeIdentifier(nodeType);
+    }
+
+    public static Element getDataSubtree(final Document doc) {
+        return (Element) doc.getElementsByTagNameNS(NETCONF_URI.toString(), "data").item(0);
+    }
+
+    public static boolean isDataRetrievalOperation(final QName rpc) {
+        return NETCONF_URI.equals(rpc.getNamespace())
+                && (NETCONF_GET_CONFIG_QNAME.getLocalName().equals(rpc.getLocalName())
+                || NETCONF_GET_QNAME.getLocalName().equals(rpc.getLocalName()));
+    }
+
+    public static ContainerSchemaNode createSchemaForDataRead(final SchemaContext schemaContext) {
+        return new NodeContainerProxy(NETCONF_DATA_QNAME, schemaContext.getChildNodes());
+    }
+
+    public static ContainerSchemaNode createSchemaForNotification(final NotificationDefinition next) {
+        return new NodeContainerProxy(next.getQName(), next.getChildNodes(), next.getAvailableAugmentations());
+    }
+
+    public static ContainerNode wrap(final QName name, final DataContainerChild<?, ?>... node) {
+        return Builders.containerBuilder().withNodeIdentifier(toId(name)).withValue(ImmutableList.copyOf(node)).build();
+    }
+
+    public static DataContainerChild<?, ?> createEditConfigStructure(final SchemaContext ctx, final YangInstanceIdentifier dataPath,
+                                                                     final Optional<ModifyAction> operation, final Optional<NormalizedNode<?, ?>> lastChildOverride) {
+        final NormalizedNode<?, ?> configContent;
+
+        if (dataPath.isEmpty()) {
+            Preconditions.checkArgument(lastChildOverride.isPresent(), "Data has to be present when creating structure for top level element");
+            Preconditions.checkArgument(lastChildOverride.get() instanceof DataContainerChild<?, ?>,
+                    "Data has to be either container or a list node when creating structure for top level element, but was: %s", lastChildOverride.get());
+            configContent = lastChildOverride.get();
+        } else {
+            final Entry<QName, ModifyAction> modifyOperation =
+                    operation.isPresent() ? new AbstractMap.SimpleEntry<>(NETCONF_OPERATION_QNAME, operation.get()) : null;
+            configContent = ImmutableNodes.fromInstanceId(ctx, dataPath, lastChildOverride, Optional.fromNullable(modifyOperation));
+        }
+
+        final Element element = XmlUtil.createElement(BLANK_DOCUMENT, NETCONF_CONFIG_QNAME.getLocalName(), Optional.of(NETCONF_CONFIG_QNAME.getNamespace().toString()));
+        try {
+            writeNormalizedNode(configContent, new DOMResult(element), SchemaPath.ROOT, ctx);
+        } catch (IOException | XMLStreamException e) {
+            throw new IllegalStateException("Unable to serialize edit config content element for path " + dataPath, e);
+        }
+        final DOMSource value = new DOMSource(element);
+
+        return Builders.choiceBuilder().withNodeIdentifier(toId(EditContent.QNAME)).withChild(
+                Builders.anyXmlBuilder().withNodeIdentifier(toId(NETCONF_CONFIG_QNAME)).withValue(value).build()).build();
+    }
+
+    public static SchemaPath toPath(final QName rpc) {
+        return SchemaPath.create(true, rpc);
+    }
+
+    // FIXME similar code is in netconf-notifications-impl , DRY
+    public static void writeNormalizedNode(final NormalizedNode<?, ?> normalized, final DOMResult result, final SchemaPath schemaPath, final SchemaContext context)
+            throws IOException, XMLStreamException {
+        NormalizedNodeWriter normalizedNodeWriter = null;
+        NormalizedNodeStreamWriter normalizedNodeStreamWriter = null;
+        XMLStreamWriter writer = null;
+        try {
+            writer = XML_FACTORY.createXMLStreamWriter(result);
+            normalizedNodeStreamWriter = XMLStreamNormalizedNodeStreamWriter.create(writer, context, schemaPath);
+            normalizedNodeWriter = NormalizedNodeWriter.forStreamWriter(normalizedNodeStreamWriter);
+
+            normalizedNodeWriter.write(normalized);
+
+            normalizedNodeWriter.flush();
+        } finally {
+            try {
+                if(normalizedNodeWriter != null) {
+                    normalizedNodeWriter.close();
+                }
+                if(normalizedNodeStreamWriter != null) {
+                    normalizedNodeStreamWriter.close();
+                }
+                if(writer != null) {
+                    writer.close();
+                }
+            } catch (final Exception e) {
+                LOG.warn("Unable to close resource properly", e);
+            }
+        }
+    }
+}
diff --git a/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/util/NetconfRpcFutureCallback.java b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/util/NetconfRpcFutureCallback.java
new file mode 100644 (file)
index 0000000..48fd469
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.connect.netconf.util;
+
+import com.google.common.util.concurrent.FutureCallback;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
+import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Simple Netconf rpc logging callback
+ */
+public class NetconfRpcFutureCallback implements FutureCallback<DOMRpcResult> {
+    private static final Logger LOG  = LoggerFactory.getLogger(NetconfRpcFutureCallback.class);
+
+    private final String type;
+    private final RemoteDeviceId id;
+
+    public NetconfRpcFutureCallback(final String prefix, final RemoteDeviceId id) {
+        this.type = prefix;
+        this.id = id;
+    }
+
+    @Override
+    public void onSuccess(final DOMRpcResult result) {
+        if(result.getErrors().isEmpty()) {
+            LOG.trace("{}: {} invoked successfully", id, type);
+        } else {
+            onUnsuccess(result);
+        }
+    }
+
+    protected void onUnsuccess(final DOMRpcResult result) {
+        LOG.warn("{}: {} invoked unsuccessfully: {}", id, type, result.getErrors());
+    }
+
+    @Override
+    public void onFailure(final Throwable t) {
+        LOG.warn("{}: {} failed.", id, type, t);
+    }
+}
diff --git a/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/util/NodeContainerProxy.java b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/util/NodeContainerProxy.java
new file mode 100644 (file)
index 0000000..23e2137
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.connect.netconf.util;
+
+import com.google.common.base.Function;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
+import org.opendaylight.yangtools.yang.model.api.ConstraintDefinition;
+import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.opendaylight.yangtools.yang.model.api.Status;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.UsesNode;
+
+/**
+ * Simple proxy for container like schema nodes, where user provides a collection of children schema nodes
+ */
+public final class NodeContainerProxy implements ContainerSchemaNode {
+
+    private final Map<QName, DataSchemaNode> childNodes;
+    private final QName qName;
+    private final Set<AugmentationSchema> availableAugmentations;
+
+    public NodeContainerProxy(final QName qName, final Map<QName, DataSchemaNode> childNodes, final Set<AugmentationSchema> availableAugmentations) {
+        this.availableAugmentations = availableAugmentations;
+        this.childNodes = Preconditions.checkNotNull(childNodes, "childNodes");
+        this.qName = qName;
+    }
+
+    public NodeContainerProxy(final QName qName, final Collection<DataSchemaNode> childNodes) {
+        this(qName, asMap(childNodes), Collections.<AugmentationSchema>emptySet());
+    }
+
+    public NodeContainerProxy(final QName qName, final Collection<DataSchemaNode> childNodes, final Set<AugmentationSchema> availableAugmentations) {
+        this(qName, asMap(childNodes), availableAugmentations);
+    }
+
+    private static Map<QName, DataSchemaNode> asMap(final Collection<DataSchemaNode> childNodes) {
+        return Maps.uniqueIndex(childNodes, new Function<DataSchemaNode, QName>() {
+            @Override
+            public QName apply(final DataSchemaNode input) {
+                return input.getQName();
+            }
+        });
+    }
+
+    @Override
+    public Set<TypeDefinition<?>> getTypeDefinitions() {
+        return Collections.emptySet();
+    }
+
+    @Override
+    public Set<DataSchemaNode> getChildNodes() {
+        return Sets.newHashSet(childNodes.values());
+    }
+
+    @Override
+    public Set<GroupingDefinition> getGroupings() {
+        return Collections.emptySet();
+    }
+
+    @Override
+    public DataSchemaNode getDataChildByName(final QName qName) {
+        return childNodes.get(qName);
+    }
+
+    @Override
+    public DataSchemaNode getDataChildByName(final String s) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Set<UsesNode> getUses() {
+        return Collections.emptySet();
+    }
+
+    @Override
+    public boolean isPresenceContainer() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Set<AugmentationSchema> getAvailableAugmentations() {
+        return availableAugmentations;
+    }
+
+    @Override
+    public boolean isAugmenting() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isAddedByUses() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isConfiguration() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public ConstraintDefinition getConstraints() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public QName getQName() {
+        return qName;
+    }
+
+    @Override
+    public SchemaPath getPath() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String getDescription() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String getReference() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Status getStatus() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public List<UnknownSchemaNode> getUnknownSchemaNodes() {
+        return Collections.emptyList();
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/util/MessageCounter.java b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/util/MessageCounter.java
new file mode 100644 (file)
index 0000000..738682f
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2014, 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.sal.connect.util;
+
+import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class MessageCounter {
+    final AtomicInteger messageId = new AtomicInteger(0);
+
+    private static final String messageIdBlueprint = "%s-%s";
+
+    public String getNewMessageId(final String prefix) {
+        Preconditions.checkArgument(Strings.isNullOrEmpty(prefix) == false, "Null or empty prefix");
+        return String.format(messageIdBlueprint, prefix, getNewMessageId());
+    }
+
+    public String getNewMessageId() {
+        return Integer.toString(messageId.getAndIncrement());
+    }
+}
diff --git a/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/util/RemoteDeviceId.java b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/util/RemoteDeviceId.java
new file mode 100644 (file)
index 0000000..d5d9da1
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.connect.util;
+
+import com.google.common.base.Preconditions;
+import java.net.InetSocketAddress;
+import org.opendaylight.controller.config.api.ModuleIdentifier;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Host;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.HostBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+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.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.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+
+public final class RemoteDeviceId {
+
+    private final String name;
+    private final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier path;
+    private final InstanceIdentifier<Node> bindingPath;
+    private final NodeKey key;
+    private final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier topologyPath;
+    private final InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node> topologyBindingPath;
+    private InetSocketAddress address;
+    private Host host;
+
+    public RemoteDeviceId(final ModuleIdentifier identifier, InetSocketAddress address) {
+        this(Preconditions.checkNotNull(identifier).getInstanceName());
+        this.address = address;
+        this.host = buildHost();
+    }
+
+    private RemoteDeviceId(final String name) {
+        this.name = Preconditions.checkNotNull(name);
+        this.key = new NodeKey(new NodeId(name));
+        this.path = createBIPath(name);
+        this.bindingPath = createBindingPath(key);
+        this.topologyPath = createBIPathForTopology(name);
+        this.topologyBindingPath = createBindingPathForTopology(key);
+    }
+
+    public RemoteDeviceId(final String name, InetSocketAddress address) {
+        this(name);
+        this.address = address;
+        this.host = buildHost();
+    }
+
+    private static InstanceIdentifier<Node> createBindingPath(final NodeKey key) {
+        return InstanceIdentifier.builder(Nodes.class).child(Node.class, key).build();
+    }
+
+    private static org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier createBIPath(final String name) {
+        final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.InstanceIdentifierBuilder builder =
+                org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.builder();
+        builder.node(Nodes.QNAME).node(Node.QNAME).nodeWithKey(Node.QNAME, QName.create(Node.QNAME.getNamespace(), Node.QNAME.getRevision(), "id"), name);
+
+        return builder.build();
+    }
+
+    private static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node> createBindingPathForTopology(final NodeKey key) {
+        final InstanceIdentifier<NetworkTopology> networkTopology = InstanceIdentifier.builder(NetworkTopology.class).build();
+        final KeyedInstanceIdentifier<Topology, TopologyKey> topology = networkTopology.child(Topology.class, new TopologyKey(new TopologyId(TopologyNetconf.QNAME.getLocalName())));
+        return topology
+                .child(org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node.class,
+                        new org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey(
+                                new org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId(key.getId().getValue())));
+    }
+
+    private static org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier createBIPathForTopology(final String name) {
+        final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.InstanceIdentifierBuilder builder =
+                org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.builder();
+        builder
+                .node(NetworkTopology.QNAME)
+                .node(Topology.QNAME)
+                .nodeWithKey(Topology.QNAME, QName.create(Topology.QNAME, "topology-id"), TopologyNetconf.QNAME.getLocalName())
+                .node(org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node.QNAME)
+                .nodeWithKey(org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node.QNAME,
+                        QName.create(org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node.QNAME, "node-id"), name);
+        return builder.build();
+    }
+
+    private Host buildHost() {
+        return HostBuilder.getDefaultInstance(address.getHostString());
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public InstanceIdentifier<Node> getBindingPath() {
+        return bindingPath;
+    }
+
+    public org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier getPath() {
+        return path;
+    }
+
+    public NodeKey getBindingKey() {
+        return key;
+    }
+
+    public InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node> getTopologyBindingPath() {
+        return topologyBindingPath;
+    }
+
+    public YangInstanceIdentifier getTopologyPath() {
+        return topologyPath;
+    }
+
+    public InetSocketAddress getAddress() {
+        return address;
+    }
+
+    public Host getHost() {
+        return host;
+    }
+
+    @Override
+    public String toString() {
+        return "RemoteDevice{" + name +'}';
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (!(o instanceof RemoteDeviceId)) {
+            return false;
+        }
+
+        final RemoteDeviceId that = (RemoteDeviceId) o;
+
+        if (!name.equals(that.name)) {
+            return false;
+        }
+        if (!bindingPath.equals(that.bindingPath)) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = name.hashCode();
+        result = 31 * result + bindingPath.hashCode();
+        return result;
+    }
+}
diff --git a/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/util/package-info.java b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/util/package-info.java
new file mode 100644 (file)
index 0000000..57f4cbb
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2014, 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
+ */
+
+ /**
+ * Utility classes for remote connectors e.g. netconf connector
+ *
+ * TODO extract into separate bundle when another connector is implemented e.g. restconf connector
+ */
+package org.opendaylight.controller.sal.connect.util;
diff --git a/opendaylight/netconf/sal-netconf-connector/src/main/yang/netconf-node-topology.yang b/opendaylight/netconf/sal-netconf-connector/src/main/yang/netconf-node-topology.yang
new file mode 100644 (file)
index 0000000..11bf6a5
--- /dev/null
@@ -0,0 +1,75 @@
+module netconf-node-topology {
+    namespace "urn:opendaylight:netconf-node-topology";
+    prefix "nettop";
+
+    import network-topology { prefix nt; revision-date 2013-10-21; }
+    import yang-ext { prefix ext; revision-date "2013-07-09";}
+    import ietf-inet-types { prefix inet; revision-date "2010-09-24"; }
+
+    revision "2015-01-14" {
+        description "Initial revision of Topology model";
+    }
+
+    augment "/nt:network-topology/nt:topology/nt:topology-types" {
+        container topology-netconf {
+        }
+    }
+
+    grouping netconf-node-fields {
+        leaf connection-status {
+            type enumeration {
+                enum connecting;
+                enum connected;
+                enum unable-to-connect;
+            }
+        }
+
+        leaf host {
+            type inet:host;
+        }
+
+        leaf port {
+            type inet:port-number;
+        }
+
+        leaf connected-message {
+            type string;
+        }
+
+        container available-capabilities {
+            leaf-list available-capability {
+                type string;
+            }
+        }
+
+        container unavailable-capabilities {
+            list unavailable-capability {
+                leaf capability {
+                    type string;
+                }
+
+                leaf failure-reason {
+                    type enumeration {
+                        enum missing-source;
+                        enum unable-to-resolve;
+                    }
+                }
+            }
+        }
+
+        container pass-through {
+            when "../connection-status = connected";
+            description
+                "When the underlying node is connected, its NETCONF context
+                is available verbatim under this container through the
+                mount extension.";
+        }
+    }
+
+    augment "/nt:network-topology/nt:topology/nt:node" {
+        when "../../nt:topology-types/topology-netconf";
+        ext:augment-identifier "netconf-node";
+
+        uses netconf-node-fields;
+    }
+}
diff --git a/opendaylight/netconf/sal-netconf-connector/src/main/yang/odl-sal-netconf-connector-cfg.yang b/opendaylight/netconf/sal-netconf-connector/src/main/yang/odl-sal-netconf-connector-cfg.yang
new file mode 100644 (file)
index 0000000..799c9c8
--- /dev/null
@@ -0,0 +1,174 @@
+module odl-sal-netconf-connector-cfg {
+    yang-version 1;
+    namespace "urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf";
+    prefix "sal-netconf";
+
+    import config { prefix config; revision-date 2013-04-05; }
+    import threadpool {prefix th;}
+    import netty {prefix netty;}
+    import 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 ietf-inet-types {prefix inet; revision-date "2010-09-24";}
+
+    description
+        "Service definition for Binding Aware MD-SAL.";
+
+    revision "2013-10-28" {
+        description
+            "Initial revision";
+    }
+
+    identity sal-netconf-connector {
+        base config:module-type;
+        config:java-name-prefix NetconfConnector;
+    }
+
+    grouping server {
+        leaf address {
+            type string;
+        }
+
+        leaf port {
+            type uint32;
+        }
+    }
+
+    augment "/config:modules/config:module/config:configuration" {
+        case sal-netconf-connector {
+            when "/config:modules/config:module/config:type = 'sal-netconf-connector'";
+
+            leaf address {
+                type inet:host;
+            }
+
+            leaf port {
+                type inet:port-number;
+            }
+
+            leaf tcp-only {
+                type boolean;
+            }
+
+            leaf username {
+                type string;
+            }
+
+            leaf password {
+                type string;
+            }
+
+            container yang-module-capabilities {
+                leaf-list capability {
+                    type string;
+                    description "Set a list of capabilities to override capabilities provided in device's hello message.
+                                 Can be used for devices that do not report any yang modules in their hello message";
+                }
+            }
+
+            leaf reconnect-on-changed-schema {
+                type boolean;
+                default false;
+                description "If true, the connector would auto disconnect/reconnect when schemas are changed in the remote device.
+                             The connector subscribes (right after connect) to base netconf notifications and listens for netconf-capability-change notification";
+            }
+
+            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;
+                    }
+                }
+            }
+
+            leaf connection-timeout-millis {
+                description "Specifies timeout in milliseconds after which connection must be established.";
+                type uint32;
+                default 20000;
+            }
+
+            leaf default-request-timeout-millis {
+                description "Timeout for blocking operations within transactions.";
+                type uint32;
+                default 60000;
+            }
+
+            leaf max-connection-attempts {
+                description "Maximum number of connection retries. Non positive value or null is interpreted as infinity.";
+                type uint32;
+                default 0; // retry forever
+            }
+
+            leaf between-attempts-timeout-millis {
+                description "Initial timeout in milliseconds to wait between connection attempts. Will be multiplied by sleep-factor with every additional attempt";
+                type uint16;
+                default 2000;
+            }
+
+            leaf sleep-factor {
+                type decimal64 {
+                    fraction-digits 1;
+                }
+                default 1.5;
+            }
+
+            // Keepalive configuration
+            leaf keepalive-delay {
+                type uint32;
+                default 120;
+                description "Netconf connector sends keepalive RPCs while the session is idle, this delay specifies the delay between keepalive RPC in seconds
+                             If a value <1 is provided, no keepalives will be sent";
+            }
+
+            container keepalive-executor {
+                uses config:service-ref {
+                    refine type {
+                        mandatory false;
+                        config:required-identity th:scheduled-threadpool;
+                    }
+                }
+
+                description "Dedicated solely to keepalive execution";
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/netconf/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceTest.java b/opendaylight/netconf/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceTest.java
new file mode 100644 (file)
index 0000000..9c15b60
--- /dev/null
@@ -0,0 +1,313 @@
+/*
+ * Copyright (c) 2014, 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.sal.connect.netconf;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyCollectionOf;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import com.google.common.util.concurrent.Futures;
+import java.io.InputStream;
+import java.net.InetSocketAddress;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
+import org.opendaylight.controller.md.sal.dom.api.DOMNotification;
+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.controller.netconf.api.NetconfMessage;
+import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
+import org.opendaylight.controller.sal.connect.api.MessageTransformer;
+import org.opendaylight.controller.sal.connect.api.RemoteDeviceHandler;
+import org.opendaylight.controller.sal.connect.netconf.listener.NetconfDeviceCommunicator;
+import org.opendaylight.controller.sal.connect.netconf.listener.NetconfSessionPreferences;
+import org.opendaylight.controller.sal.connect.netconf.sal.NetconfDeviceRpc;
+import org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil;
+import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
+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;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.ModuleImport;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.opendaylight.yangtools.yang.model.repo.api.MissingSchemaSourceException;
+import org.opendaylight.yangtools.yang.model.repo.api.SchemaContextFactory;
+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.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.parser.impl.YangParserImpl;
+
+public class NetconfDeviceTest {
+
+    private static final NetconfMessage notification;
+
+    private static final ContainerNode compositeNode;
+
+    static {
+        try {
+            compositeNode = mockClass(ContainerNode.class);
+        } catch (final Exception e) {
+            throw new RuntimeException(e);
+        }
+        try {
+            notification = new NetconfMessage(XmlUtil.readXmlToDocument(NetconfDeviceTest.class.getResourceAsStream("/notification-payload.xml")));
+        } catch (Exception e) {
+            throw new ExceptionInInitializerError(e);
+        }
+    }
+
+    private static final DOMRpcResult rpcResultC = new DefaultDOMRpcResult(compositeNode);
+
+    public static final String TEST_NAMESPACE = "test:namespace";
+    public static final String TEST_MODULE = "test-module";
+    public static final String TEST_REVISION = "2013-07-22";
+    public static final SourceIdentifier TEST_SID = new SourceIdentifier(TEST_MODULE, Optional.of(TEST_REVISION));
+    public static final String TEST_CAPABILITY = TEST_NAMESPACE + "?module=" + TEST_MODULE + "&amp;revision=" + TEST_REVISION;
+
+    public static final SourceIdentifier TEST_SID2 = new SourceIdentifier(TEST_MODULE + "2", Optional.of(TEST_REVISION));
+    public static final String TEST_CAPABILITY2 = TEST_NAMESPACE + "?module=" + TEST_MODULE + "2" + "&amp;revision=" + TEST_REVISION;
+
+    private static final NetconfStateSchemas.NetconfStateSchemasResolver stateSchemasResolver = new NetconfStateSchemas.NetconfStateSchemasResolver() {
+
+        @Override
+        public NetconfStateSchemas resolve(final NetconfDeviceRpc deviceRpc, final NetconfSessionPreferences remoteSessionCapabilities, final RemoteDeviceId id) {
+            return NetconfStateSchemas.EMPTY;
+        }
+    };
+
+    @Test
+    public void testNetconfDeviceFailFirstSchemaFailSecondEmpty() throws Exception {
+        final ArrayList<String> capList = Lists.newArrayList(TEST_CAPABILITY);
+
+        final RemoteDeviceHandler<NetconfSessionPreferences> facade = getFacade();
+        final NetconfDeviceCommunicator listener = getListener();
+
+        final SchemaContextFactory schemaFactory = getSchemaFactory();
+
+        // Make fallback attempt to fail due to empty resolved sources
+        final SchemaResolutionException schemaResolutionException
+                = new SchemaResolutionException("fail first",
+                Collections.<SourceIdentifier>emptyList(), HashMultimap.<SourceIdentifier, ModuleImport>create());
+        doReturn(Futures.immediateFailedCheckedFuture(
+                schemaResolutionException))
+                .when(schemaFactory).createSchemaContext(anyCollectionOf(SourceIdentifier.class));
+
+        final NetconfDevice.SchemaResourcesDTO schemaResourcesDTO
+                = new NetconfDevice.SchemaResourcesDTO(getSchemaRegistry(), schemaFactory, stateSchemasResolver);
+        final NetconfDevice device = new NetconfDevice(schemaResourcesDTO, getId(), facade, getExecutor(),true);
+        // Monitoring not supported
+        final NetconfSessionPreferences sessionCaps = getSessionCaps(false, capList);
+        device.onRemoteSessionUp(sessionCaps, listener);
+
+        Mockito.verify(facade, Mockito.timeout(5000)).onDeviceDisconnected();
+        Mockito.verify(listener, Mockito.timeout(5000)).close();
+        Mockito.verify(schemaFactory, times(1)).createSchemaContext(anyCollectionOf(SourceIdentifier.class));
+    }
+
+    @Test
+    public void testNetconfDeviceMissingSource() throws Exception {
+        final RemoteDeviceHandler<NetconfSessionPreferences> facade = getFacade();
+        final NetconfDeviceCommunicator listener = getListener();
+        final SchemaContext schema = getSchema();
+
+        final SchemaContextFactory schemaFactory = getSchemaFactory();
+
+        // Make fallback attempt to fail due to empty resolved sources
+        final MissingSchemaSourceException schemaResolutionException = new MissingSchemaSourceException("fail first", TEST_SID);
+        doAnswer(new Answer<Object>() {
+            @Override
+            public Object answer(final InvocationOnMock invocation) throws Throwable {
+                if(((Collection<?>) invocation.getArguments()[0]).size() == 2) {
+                    return Futures.immediateFailedCheckedFuture(schemaResolutionException);
+                } else {
+                    return Futures.immediateCheckedFuture(schema);
+                }
+            }
+        }).when(schemaFactory).createSchemaContext(anyCollectionOf(SourceIdentifier.class));
+
+        final NetconfStateSchemas.NetconfStateSchemasResolver stateSchemasResolver = new NetconfStateSchemas.NetconfStateSchemasResolver() {
+            @Override
+            public NetconfStateSchemas resolve(final NetconfDeviceRpc deviceRpc, final NetconfSessionPreferences remoteSessionCapabilities, final RemoteDeviceId id) {
+                final Module first = Iterables.getFirst(schema.getModules(), null);
+                final QName qName = QName.create(first.getQNameModule(), first.getName());
+                final NetconfStateSchemas.RemoteYangSchema source1 = new NetconfStateSchemas.RemoteYangSchema(qName);
+                final NetconfStateSchemas.RemoteYangSchema source2 = new NetconfStateSchemas.RemoteYangSchema(QName.create(first.getQNameModule(), "test-module2"));
+                return new NetconfStateSchemas(Sets.newHashSet(source1, source2));
+            }
+        };
+
+        final NetconfDevice.SchemaResourcesDTO schemaResourcesDTO
+                = new NetconfDevice.SchemaResourcesDTO(getSchemaRegistry(), schemaFactory, stateSchemasResolver);
+
+        final NetconfDevice device = new NetconfDevice(schemaResourcesDTO, getId(), facade, getExecutor(), true);
+        // Monitoring supported
+        final NetconfSessionPreferences sessionCaps = getSessionCaps(true, Lists.newArrayList(TEST_CAPABILITY, TEST_CAPABILITY2));
+        device.onRemoteSessionUp(sessionCaps, listener);
+
+        Mockito.verify(facade, Mockito.timeout(5000)).onDeviceConnected(any(SchemaContext.class), any(NetconfSessionPreferences.class), any(NetconfDeviceRpc.class));
+        Mockito.verify(schemaFactory, times(2)).createSchemaContext(anyCollectionOf(SourceIdentifier.class));
+    }
+
+    private SchemaSourceRegistry getSchemaRegistry() {
+        final SchemaSourceRegistry mock = mock(SchemaSourceRegistry.class);
+        final SchemaSourceRegistration<?> mockReg = mock(SchemaSourceRegistration.class);
+        doNothing().when(mockReg).close();
+        doReturn(mockReg).when(mock).registerSchemaSource(any(org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceProvider.class), any(PotentialSchemaSource.class));
+        return mock;
+    }
+
+    @Test
+    public void testNotificationBeforeSchema() throws Exception {
+        final RemoteDeviceHandler<NetconfSessionPreferences> facade = getFacade();
+        final NetconfDeviceCommunicator listener = getListener();
+
+        final NetconfDevice.SchemaResourcesDTO schemaResourcesDTO
+                = new NetconfDevice.SchemaResourcesDTO(getSchemaRegistry(), getSchemaFactory(), stateSchemasResolver);
+        final NetconfDevice device = new NetconfDevice(schemaResourcesDTO, getId(), facade, getExecutor(), true);
+
+        device.onNotification(notification);
+        device.onNotification(notification);
+
+        verify(facade, times(0)).onNotification(any(DOMNotification.class));
+
+        final NetconfSessionPreferences sessionCaps = getSessionCaps(true,
+                Lists.newArrayList(TEST_CAPABILITY));
+
+        final DOMRpcService deviceRpc = mock(DOMRpcService.class);
+
+        device.handleSalInitializationSuccess(NetconfToNotificationTest.getNotificationSchemaContext(getClass()), sessionCaps, deviceRpc);
+
+        verify(facade, timeout(10000).times(2)).onNotification(any(DOMNotification.class));
+
+        device.onNotification(notification);
+        verify(facade, timeout(10000).times(3)).onNotification(any(DOMNotification.class));
+    }
+
+    @Test
+    public void testNetconfDeviceReconnect() throws Exception {
+        final RemoteDeviceHandler<NetconfSessionPreferences> facade = getFacade();
+        final NetconfDeviceCommunicator listener = getListener();
+
+        final SchemaContextFactory schemaContextProviderFactory = getSchemaFactory();
+
+        final NetconfDevice.SchemaResourcesDTO schemaResourcesDTO
+                = new NetconfDevice.SchemaResourcesDTO(getSchemaRegistry(), schemaContextProviderFactory, stateSchemasResolver);
+        final NetconfDevice device = new NetconfDevice(schemaResourcesDTO, getId(), facade, getExecutor(), true);
+        final NetconfSessionPreferences sessionCaps = getSessionCaps(true,
+                Lists.newArrayList(TEST_NAMESPACE + "?module=" + TEST_MODULE + "&amp;revision=" + TEST_REVISION));
+        device.onRemoteSessionUp(sessionCaps, listener);
+
+        verify(schemaContextProviderFactory, timeout(5000)).createSchemaContext(any(Collection.class));
+        verify(facade, timeout(5000)).onDeviceConnected(any(SchemaContext.class), any(NetconfSessionPreferences.class), any(DOMRpcService.class));
+
+        device.onRemoteSessionDown();
+        verify(facade, timeout(5000)).onDeviceDisconnected();
+
+        device.onRemoteSessionUp(sessionCaps, listener);
+
+        verify(schemaContextProviderFactory, timeout(5000).times(2)).createSchemaContext(any(Collection.class));
+        verify(facade, timeout(5000).times(2)).onDeviceConnected(any(SchemaContext.class), any(NetconfSessionPreferences.class), any(DOMRpcService.class));
+    }
+
+    private SchemaContextFactory getSchemaFactory() {
+        final SchemaContextFactory schemaFactory = mockClass(SchemaContextFactory.class);
+        doReturn(Futures.immediateCheckedFuture(getSchema())).when(schemaFactory).createSchemaContext(any(Collection.class));
+        return schemaFactory;
+    }
+
+    public static SchemaContext getSchema() {
+        final YangParserImpl parser = new YangParserImpl();
+        final List<InputStream> modelsToParse = Lists.newArrayList(
+                NetconfDeviceTest.class.getResourceAsStream("/schemas/test-module.yang")
+        );
+        final Set<Module> models = parser.parseYangModelsFromStreams(modelsToParse);
+        return parser.resolveSchemaContext(models);
+    }
+
+    private RemoteDeviceHandler<NetconfSessionPreferences> getFacade() throws Exception {
+        final RemoteDeviceHandler<NetconfSessionPreferences> remoteDeviceHandler = mockCloseableClass(RemoteDeviceHandler.class);
+        doNothing().when(remoteDeviceHandler).onDeviceConnected(any(SchemaContext.class), any(NetconfSessionPreferences.class), any(NetconfDeviceRpc.class));
+        doNothing().when(remoteDeviceHandler).onDeviceDisconnected();
+        doNothing().when(remoteDeviceHandler).onNotification(any(DOMNotification.class));
+        return remoteDeviceHandler;
+    }
+
+    private <T extends AutoCloseable> T mockCloseableClass(final Class<T> remoteDeviceHandlerClass) throws Exception {
+        final T mock = mockClass(remoteDeviceHandlerClass);
+        doNothing().when(mock).close();
+        return mock;
+    }
+
+    private static <T> T mockClass(final Class<T> remoteDeviceHandlerClass) {
+        final T mock = mock(remoteDeviceHandlerClass);
+        Mockito.doReturn(remoteDeviceHandlerClass.getSimpleName()).when(mock).toString();
+        return mock;
+    }
+
+    public RemoteDeviceId getId() {
+        return new RemoteDeviceId("test-D", InetSocketAddress.createUnresolved("localhost", 22));
+    }
+
+    public ExecutorService getExecutor() {
+        return Executors.newSingleThreadExecutor();
+    }
+
+    public MessageTransformer<NetconfMessage> getMessageTransformer() throws Exception {
+        final MessageTransformer<NetconfMessage> messageTransformer = mockClass(MessageTransformer.class);
+        doReturn(notification).when(messageTransformer).toRpcRequest(any(SchemaPath.class), any(NormalizedNode.class));
+        doReturn(rpcResultC).when(messageTransformer).toRpcResult(any(NetconfMessage.class), any(SchemaPath.class));
+        doReturn(compositeNode).when(messageTransformer).toNotification(any(NetconfMessage.class));
+        return messageTransformer;
+    }
+
+    public NetconfSessionPreferences getSessionCaps(final boolean addMonitor, final Collection<String> additionalCapabilities) {
+        final ArrayList<String> capabilities = Lists.newArrayList(
+                XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_BASE_1_0,
+                XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_BASE_1_1);
+
+        if(addMonitor) {
+            capabilities.add(NetconfMessageTransformUtil.IETF_NETCONF_MONITORING.getNamespace().toString());
+        }
+
+        capabilities.addAll(additionalCapabilities);
+
+        return NetconfSessionPreferences.fromStrings(
+                capabilities);
+    }
+
+    public NetconfDeviceCommunicator getListener() throws Exception {
+        final NetconfDeviceCommunicator remoteDeviceCommunicator = mockCloseableClass(NetconfDeviceCommunicator.class);
+//        doReturn(Futures.immediateFuture(rpcResult)).when(remoteDeviceCommunicator).sendRequest(any(NetconfMessage.class), any(QName.class));
+        return remoteDeviceCommunicator;
+    }
+}
diff --git a/opendaylight/netconf/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/NetconfStateSchemasTest.java b/opendaylight/netconf/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/NetconfStateSchemasTest.java
new file mode 100644 (file)
index 0000000..768b59a
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2014, 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.sal.connect.netconf;
+
+import static org.hamcrest.CoreMatchers.hasItem;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+
+import java.net.InetSocketAddress;
+import java.util.Collections;
+import java.util.Set;
+import org.junit.Test;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
+import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
+import org.opendaylight.yangtools.yang.common.QName;
+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.transform.ToNormalizedNodeParser;
+import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser.DomToNormalizedNodeParserFactory;
+import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+public class NetconfStateSchemasTest {
+
+    @Test
+    public void testCreate() throws Exception {
+        final DataSchemaNode schemasNode = ((ContainerSchemaNode) NetconfDevice.INIT_SCHEMA_CTX.getDataChildByName("netconf-state")).getDataChildByName("schemas");
+
+        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, NetconfDevice.INIT_SCHEMA_CTX, 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);
+
+        final Set<QName> availableYangSchemasQNames = schemas.getAvailableYangSchemasQNames();
+        assertEquals(73, availableYangSchemasQNames.size());
+
+        assertThat(availableYangSchemasQNames,
+                hasItem(QName.create("urn:TBD:params:xml:ns:yang:network-topology", "2013-07-12", "network-topology")));
+    }
+}
diff --git a/opendaylight/netconf/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/NetconfToNotificationTest.java b/opendaylight/netconf/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/NetconfToNotificationTest.java
new file mode 100644 (file)
index 0000000..2b876d2
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2014, 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.sal.connect.netconf;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import com.google.common.collect.Iterables;
+import java.io.InputStream;
+import java.text.SimpleDateFormat;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import javax.xml.parsers.DocumentBuilderFactory;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
+import org.opendaylight.controller.md.sal.dom.api.DOMEvent;
+import org.opendaylight.controller.md.sal.dom.api.DOMNotification;
+import org.opendaylight.controller.netconf.api.NetconfMessage;
+import org.opendaylight.controller.netconf.notifications.NetconfNotification;
+import org.opendaylight.controller.sal.connect.netconf.schema.mapping.NetconfMessageTransformer;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.parser.api.YangContextParser;
+import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
+import org.w3c.dom.Document;
+
+public class NetconfToNotificationTest {
+
+    NetconfMessageTransformer messageTransformer;
+
+    NetconfMessage userNotification;
+
+    @SuppressWarnings("deprecation")
+    @Before
+    public void setup() throws Exception {
+        final SchemaContext schemaContext = getNotificationSchemaContext(getClass());
+
+        messageTransformer = new NetconfMessageTransformer(schemaContext, true);
+
+        final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        InputStream notifyPayloadStream = getClass().getResourceAsStream("/notification-payload.xml");
+        assertNotNull(notifyPayloadStream);
+
+        final Document doc = XmlUtil.readXmlToDocument(notifyPayloadStream);
+        assertNotNull(doc);
+        userNotification = new NetconfMessage(doc);
+    }
+
+    static SchemaContext getNotificationSchemaContext(Class<?> loadClass) {
+        final List<InputStream> modelsToParse = Collections.singletonList(loadClass.getResourceAsStream("/schemas/user-notification.yang"));
+        final YangContextParser parser = new YangParserImpl();
+        final Set<Module> modules = parser.parseYangModelsFromStreams(modelsToParse);
+        assertTrue(!modules.isEmpty());
+        final SchemaContext schemaContext = parser.resolveSchemaContext(modules);
+        assertNotNull(schemaContext);
+        return schemaContext;
+    }
+
+    @Test
+    public void test() throws Exception {
+        final DOMNotification domNotification = messageTransformer.toNotification(userNotification);
+        final ContainerNode root = domNotification.getBody();
+        assertNotNull(root);
+        assertEquals(6, Iterables.size(root.getValue()));
+        assertEquals("user-visited-page", root.getNodeType().getLocalName());
+        assertEquals(new SimpleDateFormat(NetconfNotification.RFC3339_DATE_FORMAT_BLUEPRINT).parse("2007-07-08T00:01:00Z"),
+                ((DOMEvent) domNotification).getEventTime());
+    }
+}
diff --git a/opendaylight/netconf/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/NetconfToRpcRequestTest.java b/opendaylight/netconf/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/NetconfToRpcRequestTest.java
new file mode 100644 (file)
index 0000000..afc5a5f
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2014, 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.sal.connect.netconf;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.toId;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.toPath;
+
+import com.google.common.collect.Sets;
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
+import org.opendaylight.controller.netconf.api.NetconfMessage;
+import org.opendaylight.controller.sal.connect.netconf.schema.mapping.NetconfMessageTransformer;
+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.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.parser.api.YangContextParser;
+import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
+import org.w3c.dom.Document;
+
+public class NetconfToRpcRequestTest {
+
+    private final static String TEST_MODEL_NAMESPACE = "urn:opendaylight:params:xml:ns:yang:controller:md:sal:rpc-test";
+    private final static String REVISION = "2014-07-14";
+    private final static QName INPUT_QNAME = QName.create(TEST_MODEL_NAMESPACE, REVISION, "input");
+    private final static QName STREAM_NAME = QName.create(TEST_MODEL_NAMESPACE, REVISION, "stream-name");
+    private final static QName SUBSCRIBE_RPC_NAME = QName.create(TEST_MODEL_NAMESPACE, REVISION, "subscribe");
+
+    private final static String CONFIG_TEST_NAMESPACE = "urn:opendaylight:params:xml:ns:yang:controller:md:sal:test:rpc:config:defs";
+    private final static String CONFIG_TEST_REVISION = "2014-07-21";
+    private final static QName EDIT_CONFIG_QNAME = QName.create(CONFIG_TEST_NAMESPACE, CONFIG_TEST_REVISION, "edit-config");
+    private final static QName GET_QNAME = QName.create(CONFIG_TEST_NAMESPACE, CONFIG_TEST_REVISION, "get");
+    private final static QName GET_CONFIG_QNAME = QName.create(CONFIG_TEST_NAMESPACE, CONFIG_TEST_REVISION, "get-config");
+
+    static SchemaContext cfgCtx;
+    static NetconfMessageTransformer messageTransformer;
+
+    @SuppressWarnings("deprecation")
+    @BeforeClass
+    public static void setup() throws Exception {
+        List<InputStream> modelsToParse = Collections
+            .singletonList(NetconfToRpcRequestTest.class.getResourceAsStream("/schemas/rpc-notification-subscription.yang"));
+        YangContextParser parser = new YangParserImpl();
+        final Set<Module> notifModules = parser.parseYangModelsFromStreams(modelsToParse);
+        assertTrue(!notifModules.isEmpty());
+
+        modelsToParse = Collections
+            .singletonList(NetconfToRpcRequestTest.class.getResourceAsStream("/schemas/config-test-rpc.yang"));
+        parser = new YangParserImpl();
+        final Set<Module> configModules = parser.parseYangModelsFromStreams(modelsToParse);
+        cfgCtx = parser.resolveSchemaContext(Sets.union(configModules, notifModules));
+        assertNotNull(cfgCtx);
+
+        messageTransformer = new NetconfMessageTransformer(cfgCtx, true);
+    }
+
+    private LeafNode<Object> buildLeaf(final QName running, final Object value) {
+        return Builders.leafBuilder().withNodeIdentifier(toId(running)).withValue(value).build();
+    }
+
+    @Test
+    public void testUserDefinedRpcCall() throws Exception {
+        final DataContainerNodeAttrBuilder<YangInstanceIdentifier.NodeIdentifier, ContainerNode> rootBuilder = Builders.containerBuilder();
+        rootBuilder.withNodeIdentifier(toId(SUBSCRIBE_RPC_NAME));
+
+        rootBuilder.withChild(buildLeaf(STREAM_NAME, "NETCONF"));
+        final ContainerNode root = rootBuilder.build();
+
+        final NetconfMessage message = messageTransformer.toRpcRequest(toPath(SUBSCRIBE_RPC_NAME), root);
+        assertNotNull(message);
+
+        final Document xmlDoc = message.getDocument();
+        final org.w3c.dom.Node rpcChild = xmlDoc.getFirstChild();
+        assertEquals(rpcChild.getLocalName(), "rpc");
+
+        final org.w3c.dom.Node subscribeName = rpcChild.getFirstChild();
+        assertEquals(subscribeName.getLocalName(), "subscribe");
+
+        final org.w3c.dom.Node streamName = subscribeName.getFirstChild();
+        assertEquals(streamName.getLocalName(), "stream-name");
+
+    }
+
+    // The edit config defined in yang has no output
+    @Test(expected = IllegalArgumentException.class)
+    public void testRpcResponse() throws Exception {
+        final NetconfMessage response = new NetconfMessage(XmlUtil.readXmlToDocument(
+                "<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\"m-5\">\n" +
+                "<data xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring\">" +
+                "module schema" +
+                "</data>\n" +
+                "</rpc-reply>\n"
+        ));
+
+        messageTransformer.toRpcResult(response, toPath(EDIT_CONFIG_QNAME));
+    }
+
+}
diff --git a/opendaylight/netconf/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/listener/NetconfDeviceCommunicatorTest.java b/opendaylight/netconf/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/listener/NetconfDeviceCommunicatorTest.java
new file mode 100644 (file)
index 0000000..0447535
--- /dev/null
@@ -0,0 +1,479 @@
+/*
+ * Copyright (c) 2014 Brocade Communications Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.connect.netconf.listener;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Matchers.same;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.verify;
+import static org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0;
+
+import com.google.common.base.Strings;
+import com.google.common.collect.Sets;
+import com.google.common.util.concurrent.ListenableFuture;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.EventLoopGroup;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.util.HashedWheelTimer;
+import io.netty.util.Timer;
+import io.netty.util.concurrent.Future;
+import io.netty.util.concurrent.GenericFutureListener;
+import io.netty.util.concurrent.GlobalEventExecutor;
+import java.io.ByteArrayInputStream;
+import java.net.InetSocketAddress;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import org.apache.commons.lang3.StringUtils;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.opendaylight.controller.config.util.xml.XmlMappingConstants;
+import org.opendaylight.controller.netconf.api.NetconfMessage;
+import org.opendaylight.controller.netconf.api.NetconfTerminationReason;
+import org.opendaylight.controller.netconf.client.NetconfClientDispatcherImpl;
+import org.opendaylight.controller.netconf.client.NetconfClientSession;
+import org.opendaylight.controller.netconf.client.conf.NetconfClientConfiguration;
+import org.opendaylight.controller.netconf.client.conf.NetconfReconnectingClientConfiguration;
+import org.opendaylight.controller.netconf.client.conf.NetconfReconnectingClientConfigurationBuilder;
+import org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication.LoginPassword;
+import org.opendaylight.controller.sal.connect.api.RemoteDevice;
+import org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil;
+import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
+import org.opendaylight.protocol.framework.ReconnectStrategy;
+import org.opendaylight.protocol.framework.ReconnectStrategyFactory;
+import org.opendaylight.protocol.framework.TimedReconnectStrategy;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.RpcError;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+public class NetconfDeviceCommunicatorTest {
+
+    @Mock
+    NetconfClientSession mockSession;
+
+    @Mock
+    RemoteDevice<NetconfSessionPreferences, NetconfMessage, NetconfDeviceCommunicator> mockDevice;
+
+    NetconfDeviceCommunicator communicator;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks( this );
+
+        communicator = new NetconfDeviceCommunicator( new RemoteDeviceId( "test", InetSocketAddress.createUnresolved("localhost", 22)), mockDevice);
+    }
+
+    @SuppressWarnings("unchecked")
+    void setupSession() {
+        doReturn(Collections.<String>emptySet()).when(mockSession).getServerCapabilities();
+        doNothing().when(mockDevice).onRemoteSessionUp(any(NetconfSessionPreferences.class),
+                any(NetconfDeviceCommunicator.class));
+        communicator.onSessionUp(mockSession);
+    }
+
+    private ListenableFuture<RpcResult<NetconfMessage>> sendRequest() throws Exception {
+        return sendRequest( UUID.randomUUID().toString() );
+    }
+
+    @SuppressWarnings("unchecked")
+    private ListenableFuture<RpcResult<NetconfMessage>> sendRequest( String messageID ) throws Exception {
+        Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
+        Element element = doc.createElement( "request" );
+        element.setAttribute( "message-id", messageID );
+        doc.appendChild( element );
+        NetconfMessage message = new NetconfMessage( doc );
+
+        ChannelFuture mockChannelFuture = mock( ChannelFuture.class );
+        doReturn( mockChannelFuture ).when( mockChannelFuture )
+            .addListener( any( (GenericFutureListener.class ) ) );
+        doReturn( mockChannelFuture ).when( mockSession ).sendMessage( same( message ) );
+
+        ListenableFuture<RpcResult<NetconfMessage>> resultFuture =
+                                      communicator.sendRequest( message, QName.create( "mock rpc" ) );
+
+        assertNotNull( "ListenableFuture is null", resultFuture );
+        return resultFuture;
+    }
+
+    @Test
+    public void testOnSessionUp() {
+        String testCapability = "urn:opendaylight:params:xml:ns:test?module=test-module&revision=2014-06-02";
+        Collection<String> serverCapabilities =
+                Sets.newHashSet( NetconfMessageTransformUtil.NETCONF_ROLLBACK_ON_ERROR_URI.toString(),
+                                 NetconfMessageTransformUtil.IETF_NETCONF_MONITORING.getNamespace().toString(),
+                                 testCapability );
+        doReturn( serverCapabilities ).when( mockSession ).getServerCapabilities();
+
+        ArgumentCaptor<NetconfSessionPreferences> NetconfSessionPreferences =
+                                              ArgumentCaptor.forClass( NetconfSessionPreferences.class );
+        doNothing().when( mockDevice ).onRemoteSessionUp( NetconfSessionPreferences.capture(), eq( communicator ) );
+
+        communicator.onSessionUp( mockSession );
+
+        verify( mockSession ).getServerCapabilities();
+        verify( mockDevice ).onRemoteSessionUp( NetconfSessionPreferences.capture(), eq( communicator ) );
+
+        NetconfSessionPreferences actualCapabilites = NetconfSessionPreferences.getValue();
+        assertEquals( "containsModuleCapability", true, actualCapabilites.containsNonModuleCapability(
+                NetconfMessageTransformUtil.NETCONF_ROLLBACK_ON_ERROR_URI.toString()) );
+        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() );
+        assertEquals( "isRollbackSupported", true, actualCapabilites.isRollbackSupported() );
+        assertEquals( "isMonitoringSupported", true, actualCapabilites.isMonitoringSupported() );
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test(timeout=5000)
+    public void testOnSessionDown() throws Exception {
+        setupSession();
+
+        ListenableFuture<RpcResult<NetconfMessage>> resultFuture1 = sendRequest();
+        ListenableFuture<RpcResult<NetconfMessage>> resultFuture2 = sendRequest();
+
+        doNothing().when( mockDevice ).onRemoteSessionDown();
+
+        communicator.onSessionDown( mockSession, new Exception( "mock ex" ) );
+
+        verifyErrorRpcResult( resultFuture1.get(), RpcError.ErrorType.TRANSPORT, "operation-failed" );
+        verifyErrorRpcResult( resultFuture2.get(), RpcError.ErrorType.TRANSPORT, "operation-failed" );
+
+        verify( mockDevice ).onRemoteSessionDown();
+
+        reset( mockDevice );
+
+        communicator.onSessionDown( mockSession, new Exception( "mock ex" ) );
+
+        verify( mockDevice, never() ).onRemoteSessionDown();
+    }
+
+    @Test
+    public void testOnSessionTerminated() throws Exception {
+        setupSession();
+
+        ListenableFuture<RpcResult<NetconfMessage>> resultFuture = sendRequest();
+
+        doNothing().when( mockDevice ).onRemoteSessionDown();
+
+        String reasonText = "testing terminate";
+        NetconfTerminationReason reason = new NetconfTerminationReason( reasonText );
+        communicator.onSessionTerminated( mockSession, reason );
+
+        RpcError rpcError = verifyErrorRpcResult( resultFuture.get(), RpcError.ErrorType.TRANSPORT,
+                                                  "operation-failed" );
+        assertEquals( "RpcError message", reasonText, rpcError.getMessage() );
+
+        verify( mockDevice ).onRemoteSessionDown();
+    }
+
+    @Test
+    public void testClose() throws Exception {
+        communicator.close();
+        verify( mockDevice, never() ).onRemoteSessionDown();
+    }
+
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    @Test
+    public void testSendRequest() throws Exception {
+        setupSession();
+
+        NetconfMessage message = new NetconfMessage(
+                              DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument() );
+        QName rpc = QName.create( "mock rpc" );
+
+        ArgumentCaptor<GenericFutureListener> futureListener =
+                                            ArgumentCaptor.forClass( GenericFutureListener.class );
+
+        ChannelFuture mockChannelFuture = mock( ChannelFuture.class );
+        doReturn( mockChannelFuture ).when( mockChannelFuture ).addListener( futureListener.capture() );
+        doReturn( mockChannelFuture ).when( mockSession ).sendMessage( same( message ) );
+
+        ListenableFuture<RpcResult<NetconfMessage>> resultFuture = communicator.sendRequest( message, rpc );
+
+        verify( mockSession ).sendMessage( same( message ) );
+
+        assertNotNull( "ListenableFuture is null", resultFuture );
+
+        verify( mockChannelFuture ).addListener( futureListener.capture() );
+        Future<Void> operationFuture = mock( Future.class );
+        doReturn( true ).when( operationFuture ).isSuccess();
+        doReturn( true ).when( operationFuture ).isDone();
+        futureListener.getValue().operationComplete( operationFuture );
+
+        try {
+            resultFuture.get( 1, TimeUnit.MILLISECONDS ); // verify it's not cancelled or has an error set
+        }
+        catch( TimeoutException e ) {} // expected
+    }
+
+    @Test
+    public void testSendRequestWithNoSession() throws Exception {
+        NetconfMessage message = new NetconfMessage(
+                              DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument() );
+        QName rpc = QName.create( "mock rpc" );
+
+        ListenableFuture<RpcResult<NetconfMessage>> resultFuture = communicator.sendRequest( message, rpc );
+
+        assertNotNull( "ListenableFuture is null", resultFuture );
+
+        // Should have an immediate result
+        RpcResult<NetconfMessage> rpcResult = resultFuture.get( 3, TimeUnit.MILLISECONDS );
+
+        verifyErrorRpcResult( rpcResult, RpcError.ErrorType.TRANSPORT, "operation-failed" );
+    }
+
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    @Test
+    public void testSendRequestWithWithSendFailure() throws Exception {
+        setupSession();
+
+        NetconfMessage message = new NetconfMessage(
+                              DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument() );
+        QName rpc = QName.create( "mock rpc" );
+
+        ArgumentCaptor<GenericFutureListener> futureListener =
+                                            ArgumentCaptor.forClass( GenericFutureListener.class );
+
+        ChannelFuture mockChannelFuture = mock( ChannelFuture.class );
+        doReturn( mockChannelFuture ).when( mockChannelFuture ).addListener( futureListener.capture() );
+        doReturn( mockChannelFuture ).when( mockSession ).sendMessage( same( message ) );
+
+        ListenableFuture<RpcResult<NetconfMessage>> resultFuture = communicator.sendRequest( message, rpc );
+
+        assertNotNull( "ListenableFuture is null", resultFuture );
+
+        verify( mockChannelFuture ).addListener( futureListener.capture() );
+
+        Future<Void> operationFuture = mock( Future.class );
+        doReturn( false ).when( operationFuture ).isSuccess();
+        doReturn( true ).when( operationFuture ).isDone();
+        doReturn( new Exception( "mock error" ) ).when( operationFuture ).cause();
+        futureListener.getValue().operationComplete( operationFuture );
+
+        // Should have an immediate result
+        RpcResult<NetconfMessage> rpcResult = resultFuture.get( 3, TimeUnit.MILLISECONDS );
+
+        RpcError rpcError = verifyErrorRpcResult( rpcResult, RpcError.ErrorType.TRANSPORT, "operation-failed" );
+        assertEquals( "RpcError message contains \"mock error\"", true,
+                    rpcError.getMessage().contains( "mock error" ) );
+    }
+
+    private NetconfMessage createSuccessResponseMessage( String messageID ) throws ParserConfigurationException {
+        Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
+        Element rpcReply = doc.createElementNS( URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0, XmlMappingConstants.RPC_REPLY_KEY);
+        rpcReply.setAttribute( "message-id", messageID );
+        Element element = doc.createElementNS( "ns", "data" );
+        element.setTextContent( messageID );
+        rpcReply.appendChild( element );
+        doc.appendChild( rpcReply );
+
+        return new NetconfMessage( doc );
+    }
+
+    //Test scenario verifying whether missing message is handled
+    @Test
+    public void testOnMissingResponseMessage() throws Exception {
+
+        setupSession();
+
+        String messageID1 = UUID.randomUUID().toString();
+        ListenableFuture<RpcResult<NetconfMessage>> resultFuture1 = sendRequest( messageID1 );
+
+        String messageID2 = UUID.randomUUID().toString();
+        ListenableFuture<RpcResult<NetconfMessage>> resultFuture2 = sendRequest( messageID2 );
+
+        String messageID3 = UUID.randomUUID().toString();
+        ListenableFuture<RpcResult<NetconfMessage>> resultFuture3 = sendRequest( messageID3 );
+
+        //response messages 1,2 are omitted
+        communicator.onMessage( mockSession, createSuccessResponseMessage( messageID3 ) );
+
+        verifyResponseMessage( resultFuture3.get(), messageID3 );
+    }
+
+    @Test
+    public void testOnSuccessfulResponseMessage() throws Exception {
+        setupSession();
+
+        String messageID1 = UUID.randomUUID().toString();
+        ListenableFuture<RpcResult<NetconfMessage>> resultFuture1 = sendRequest( messageID1 );
+
+        String messageID2 = UUID.randomUUID().toString();
+        ListenableFuture<RpcResult<NetconfMessage>> resultFuture2 = sendRequest( messageID2 );
+
+        communicator.onMessage( mockSession, createSuccessResponseMessage( messageID1 ) );
+        communicator.onMessage( mockSession, createSuccessResponseMessage( messageID2 ) );
+
+        verifyResponseMessage( resultFuture1.get(), messageID1 );
+        verifyResponseMessage( resultFuture2.get(), messageID2 );
+    }
+
+    @Test
+    public void testOnResponseMessageWithError() throws Exception {
+        setupSession();
+
+        String messageID = UUID.randomUUID().toString();
+        ListenableFuture<RpcResult<NetconfMessage>> resultFuture = sendRequest( messageID );
+
+        communicator.onMessage( mockSession, createErrorResponseMessage( messageID ) );
+
+        RpcError rpcError = verifyErrorRpcResult( resultFuture.get(), RpcError.ErrorType.RPC,
+                                                  "missing-attribute" );
+        assertEquals( "RpcError message", "Missing attribute", rpcError.getMessage() );
+
+        String errorInfo = rpcError.getInfo();
+        assertNotNull( "RpcError info is null", errorInfo );
+        assertEquals( "Error info contains \"foo\"", true,
+                      errorInfo.contains( "<bad-attribute>foo</bad-attribute>" ) );
+        assertEquals( "Error info contains \"bar\"", true,
+                      errorInfo.contains( "<bad-element>bar</bad-element>" ) );
+    }
+
+    /**
+     * Test whether reconnect is scheduled properly
+     */
+    @Test
+    public void testNetconfDeviceReconnectInCommunicator() throws Exception {
+        final RemoteDevice<NetconfSessionPreferences, NetconfMessage, NetconfDeviceCommunicator> device = mock(RemoteDevice.class);
+
+        final TimedReconnectStrategy timedReconnectStrategy = new TimedReconnectStrategy(GlobalEventExecutor.INSTANCE, 10000, 0, 1.0, null, 100L, null);
+        final ReconnectStrategy reconnectStrategy = spy(new ReconnectStrategy() {
+            @Override
+            public int getConnectTimeout() throws Exception {
+                return timedReconnectStrategy.getConnectTimeout();
+            }
+
+            @Override
+            public Future<Void> scheduleReconnect(final Throwable cause) {
+                return timedReconnectStrategy.scheduleReconnect(cause);
+            }
+
+            @Override
+            public void reconnectSuccessful() {
+                timedReconnectStrategy.reconnectSuccessful();
+            }
+        });
+
+        final EventLoopGroup group = new NioEventLoopGroup();
+        final Timer time = new HashedWheelTimer();
+        try {
+            final NetconfDeviceCommunicator listener = new NetconfDeviceCommunicator(new RemoteDeviceId("test", InetSocketAddress.createUnresolved("localhost", 22)), device);
+            final NetconfReconnectingClientConfiguration cfg = NetconfReconnectingClientConfigurationBuilder.create()
+                    .withAddress(new InetSocketAddress("localhost", 65000))
+                    .withReconnectStrategy(reconnectStrategy)
+                    .withConnectStrategyFactory(new ReconnectStrategyFactory() {
+                        @Override
+                        public ReconnectStrategy createReconnectStrategy() {
+                            return reconnectStrategy;
+                        }
+                    })
+                    .withAuthHandler(new LoginPassword("admin", "admin"))
+                    .withConnectionTimeoutMillis(10000)
+                    .withProtocol(NetconfClientConfiguration.NetconfClientProtocol.SSH)
+                    .withSessionListener(listener)
+                    .build();
+
+            listener.initializeRemoteConnection(new NetconfClientDispatcherImpl(group, group, time), cfg);
+
+            verify(reconnectStrategy, timeout((int) TimeUnit.MINUTES.toMillis(3)).times(101)).scheduleReconnect(any(Throwable.class));
+        } finally {
+            time.stop();
+            group.shutdownGracefully();
+        }
+    }
+
+    @Test
+    public void testOnResponseMessageWithWrongMessageID() throws Exception {
+        setupSession();
+
+        String messageID = UUID.randomUUID().toString();
+        ListenableFuture<RpcResult<NetconfMessage>> resultFuture = sendRequest( messageID );
+
+        communicator.onMessage( mockSession, createSuccessResponseMessage( UUID.randomUUID().toString() ) );
+
+        RpcError rpcError = verifyErrorRpcResult( resultFuture.get(), RpcError.ErrorType.PROTOCOL,
+                                                  "bad-attribute" );
+        assertEquals( "RpcError message non-empty", true,
+                      !Strings.isNullOrEmpty( rpcError.getMessage() ) );
+
+        String errorInfo = rpcError.getInfo();
+        assertNotNull( "RpcError info is null", errorInfo );
+        assertEquals( "Error info contains \"actual-message-id\"", true,
+                      errorInfo.contains( "actual-message-id" ) );
+        assertEquals( "Error info contains \"expected-message-id\"", true,
+                      errorInfo.contains( "expected-message-id" ) );
+    }
+
+    private NetconfMessage createErrorResponseMessage( String messageID ) throws Exception {
+        String xmlStr =
+            "<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"" +
+            "           message-id=\"" + messageID + "\">" +
+            "  <rpc-error>" +
+            "    <error-type>rpc</error-type>" +
+            "    <error-tag>missing-attribute</error-tag>" +
+            "    <error-severity>error</error-severity>" +
+            "    <error-message>Missing attribute</error-message>" +
+            "    <error-info>" +
+            "      <bad-attribute>foo</bad-attribute>" +
+            "      <bad-element>bar</bad-element>" +
+            "    </error-info>" +
+            "  </rpc-error>" +
+            "</rpc-reply>";
+
+        ByteArrayInputStream bis = new ByteArrayInputStream( xmlStr.getBytes() );
+        Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse( bis );
+        return new NetconfMessage( doc );
+    }
+
+    private void verifyResponseMessage( RpcResult<NetconfMessage> rpcResult, String dataText ) {
+        assertNotNull( "RpcResult is null", rpcResult );
+        assertEquals( "isSuccessful", true, rpcResult.isSuccessful() );
+        NetconfMessage messageResult = rpcResult.getResult();
+        assertNotNull( "getResult", messageResult );
+//        List<SimpleNode<?>> nodes = messageResult.getSimpleNodesByName(
+//                                         QName.create( URI.create( "ns" ), null, "data" ) );
+//        assertNotNull( "getSimpleNodesByName", nodes );
+//        assertEquals( "List<SimpleNode<?>> size", 1, nodes.size() );
+//        assertEquals( "SimpleNode value", dataText, nodes.iterator().next().getValue() );
+    }
+
+    private RpcError verifyErrorRpcResult( RpcResult<NetconfMessage> rpcResult,
+                                           RpcError.ErrorType expErrorType, String expErrorTag ) {
+        assertNotNull( "RpcResult is null", rpcResult );
+        assertEquals( "isSuccessful", false, rpcResult.isSuccessful() );
+        assertNotNull( "RpcResult errors is null", rpcResult.getErrors() );
+        assertEquals( "Errors size", 1, rpcResult.getErrors().size() );
+        RpcError rpcError = rpcResult.getErrors().iterator().next();
+        assertEquals( "getErrorSeverity", RpcError.ErrorSeverity.ERROR, rpcError.getSeverity() );
+        assertEquals( "getErrorType", expErrorType, rpcError.getErrorType() );
+        assertEquals( "getErrorTag", expErrorTag, rpcError.getTag() );
+        assertTrue( "getMessage is empty", StringUtils.isNotEmpty( rpcError.getMessage() ) );
+        return rpcError;
+    }
+}
diff --git a/opendaylight/netconf/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/listener/NetconfSessionPreferencesTest.java b/opendaylight/netconf/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/listener/NetconfSessionPreferencesTest.java
new file mode 100644 (file)
index 0000000..fcee141
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2014, 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.sal.connect.netconf.listener;
+
+import static org.hamcrest.CoreMatchers.hasItem;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+
+import com.google.common.collect.Lists;
+import java.util.List;
+import org.junit.Test;
+import org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil;
+import org.opendaylight.yangtools.yang.common.QName;
+
+public class NetconfSessionPreferencesTest {
+
+    @Test
+    public void testMerge() throws Exception {
+        final List<String> caps1 = Lists.newArrayList(
+                "namespace:1?module=module1&revision=2012-12-12",
+                "namespace:2?module=module2&amp;revision=2012-12-12",
+                "urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring?module=ietf-netconf-monitoring&amp;revision=2010-10-04",
+                "urn:ietf:params:netconf:base:1.0",
+                "urn:ietf:params:netconf:capability:rollback-on-error:1.0"
+        );
+        final NetconfSessionPreferences sessionCaps1 = NetconfSessionPreferences.fromStrings(caps1);
+        assertCaps(sessionCaps1, 2, 3);
+
+        final List<String> caps2 = Lists.newArrayList(
+                "namespace:3?module=module3&revision=2012-12-12",
+                "namespace:4?module=module4&revision=2012-12-12",
+                "randomNonModuleCap"
+        );
+        final NetconfSessionPreferences sessionCaps2 = NetconfSessionPreferences.fromStrings(caps2);
+        assertCaps(sessionCaps2, 1, 2);
+
+        final NetconfSessionPreferences merged = sessionCaps1.addModuleCaps(sessionCaps2);
+        assertCaps(merged, 2, 2 + 1 /*Preserved monitoring*/ + 2 /*already present*/);
+        for (final QName qName : sessionCaps2.getModuleBasedCaps()) {
+            assertThat(merged.getModuleBasedCaps(), hasItem(qName));
+        }
+        assertThat(merged.getModuleBasedCaps(), hasItem(NetconfMessageTransformUtil.IETF_NETCONF_MONITORING));
+
+        assertThat(merged.getNonModuleCaps(), hasItem("urn:ietf:params:netconf:base:1.0"));
+        assertThat(merged.getNonModuleCaps(), hasItem("urn:ietf:params:netconf:capability:rollback-on-error:1.0"));
+    }
+
+    @Test
+    public void testCapabilityNoRevision() throws Exception {
+        final List<String> caps1 = Lists.newArrayList(
+                "namespace:2?module=module2",
+                "namespace:2?module=module2&amp;revision=2012-12-12",
+                "namespace:2?module=module1&amp;RANDOMSTRING;revision=2013-12-12",
+                "namespace:2?module=module2&amp;RANDOMSTRING;revision=2013-12-12" // This one should be ignored(same as first), since revision is in wrong format
+        );
+
+        final NetconfSessionPreferences sessionCaps1 = NetconfSessionPreferences.fromStrings(caps1);
+        assertCaps(sessionCaps1, 0, 3);
+    }
+
+    private void assertCaps(final NetconfSessionPreferences sessionCaps1, final int nonModuleCaps, final int moduleCaps) {
+        assertEquals(nonModuleCaps, sessionCaps1.getNonModuleCaps().size());
+        assertEquals(moduleCaps, sessionCaps1.getModuleBasedCaps().size());
+    }
+}
diff --git a/opendaylight/netconf/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/sal/KeepaliveSalFacadeTest.java b/opendaylight/netconf/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/sal/KeepaliveSalFacadeTest.java
new file mode 100644 (file)
index 0000000..71d1b83
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+ * 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.sal.connect.netconf.sal;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import com.google.common.util.concurrent.Futures;
+import java.net.InetSocketAddress;
+import java.util.concurrent.Executors;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+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.controller.sal.connect.api.RemoteDeviceHandler;
+import org.opendaylight.controller.sal.connect.netconf.listener.NetconfDeviceCommunicator;
+import org.opendaylight.controller.sal.connect.netconf.listener.NetconfSessionPreferences;
+import org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil;
+import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
+import org.opendaylight.yangtools.yang.common.RpcError;
+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.Builders;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+
+public class KeepaliveSalFacadeTest {
+
+    private static final RemoteDeviceId REMOTE_DEVICE_ID = new RemoteDeviceId("test", new InetSocketAddress("localhost", 22));
+
+    @Mock
+    private RemoteDeviceHandler<NetconfSessionPreferences> underlyingSalFacade;
+
+    private static java.util.concurrent.ScheduledExecutorService executorService;
+
+    @Mock
+    private NetconfDeviceCommunicator listener;
+    @Mock
+    private DOMRpcService deviceRpc;
+
+    private DOMRpcService proxyRpc;
+
+    @Before
+    public void setUp() throws Exception {
+        executorService = Executors.newScheduledThreadPool(1);
+
+        MockitoAnnotations.initMocks(this);
+
+        doNothing().when(listener).disconnect();
+        doReturn("mockedRpc").when(deviceRpc).toString();
+        doNothing().when(underlyingSalFacade).onDeviceConnected(
+                any(SchemaContext.class), any(NetconfSessionPreferences.class), any(DOMRpcService.class));
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        executorService.shutdownNow();
+    }
+
+    @Test
+    public void testKeepaliveSuccess() throws Exception {
+        final DOMRpcResult result = new DefaultDOMRpcResult(Builders.containerBuilder().withNodeIdentifier(
+                new YangInstanceIdentifier.NodeIdentifier(NetconfMessageTransformUtil.NETCONF_RUNNING_QNAME)).build());
+
+        doReturn(Futures.immediateCheckedFuture(result)).when(deviceRpc).invokeRpc(any(SchemaPath.class), any(NormalizedNode.class));
+
+        final KeepaliveSalFacade keepaliveSalFacade =
+                new KeepaliveSalFacade(REMOTE_DEVICE_ID, underlyingSalFacade, executorService, 1L);
+        keepaliveSalFacade.setListener(listener);
+
+        keepaliveSalFacade.onDeviceConnected(null, null, deviceRpc);
+
+        verify(underlyingSalFacade).onDeviceConnected(
+                any(SchemaContext.class), any(NetconfSessionPreferences.class), any(DOMRpcService.class));
+
+        verify(deviceRpc, timeout(15000).times(5)).invokeRpc(any(SchemaPath.class), any(NormalizedNode.class));
+    }
+
+    @Test
+    public void testKeepaliveFail() throws Exception {
+        final DOMRpcResult result = new DefaultDOMRpcResult(Builders.containerBuilder().withNodeIdentifier(
+                new YangInstanceIdentifier.NodeIdentifier(NetconfMessageTransformUtil.NETCONF_RUNNING_QNAME)).build());
+
+        final DOMRpcResult resultFail = new DefaultDOMRpcResult(mock(RpcError.class));
+
+        doReturn(Futures.immediateCheckedFuture(result))
+                .doReturn(Futures.immediateCheckedFuture(resultFail))
+                .doReturn(Futures.immediateFailedCheckedFuture(new IllegalStateException("illegal-state")))
+                .when(deviceRpc).invokeRpc(any(SchemaPath.class), any(NormalizedNode.class));
+
+        final KeepaliveSalFacade keepaliveSalFacade =
+                new KeepaliveSalFacade(REMOTE_DEVICE_ID, underlyingSalFacade, executorService, 1L);
+        keepaliveSalFacade.setListener(listener);
+
+        keepaliveSalFacade.onDeviceConnected(null, null, deviceRpc);
+
+        verify(underlyingSalFacade).onDeviceConnected(
+                any(SchemaContext.class), any(NetconfSessionPreferences.class), any(DOMRpcService.class));
+
+        // 1 failed that results in disconnect
+        verify(listener, timeout(15000).times(1)).disconnect();
+        // 3 attempts total
+        verify(deviceRpc, times(3)).invokeRpc(any(SchemaPath.class), any(NormalizedNode.class));
+
+        // Reconnect with same keepalive responses
+        doReturn(Futures.immediateCheckedFuture(result))
+                .doReturn(Futures.immediateCheckedFuture(resultFail))
+                .doReturn(Futures.immediateFailedCheckedFuture(new IllegalStateException("illegal-state")))
+                .when(deviceRpc).invokeRpc(any(SchemaPath.class), any(NormalizedNode.class));
+
+        keepaliveSalFacade.onDeviceConnected(null, null, deviceRpc);
+
+        // 1 failed that results in disconnect, 2 total with previous fail
+        verify(listener, timeout(15000).times(2)).disconnect();
+        // 6 attempts now total
+        verify(deviceRpc, times(3 * 2)).invokeRpc(any(SchemaPath.class), any(NormalizedNode.class));
+    }
+
+    @Test
+    public void testNonKeepaliveRpcFailure() throws Exception {
+        doAnswer(new Answer() {
+            @Override
+            public Object answer(final InvocationOnMock invocationOnMock) throws Throwable {
+                proxyRpc = (DOMRpcService) invocationOnMock.getArguments()[2];
+                return null;
+            }
+        }).when(underlyingSalFacade).onDeviceConnected(any(SchemaContext.class), any(NetconfSessionPreferences.class), any(DOMRpcService.class));
+
+        doReturn(Futures.immediateFailedCheckedFuture(new IllegalStateException("illegal-state")))
+                .when(deviceRpc).invokeRpc(any(SchemaPath.class), any(NormalizedNode.class));
+
+        final KeepaliveSalFacade keepaliveSalFacade =
+                new KeepaliveSalFacade(REMOTE_DEVICE_ID, underlyingSalFacade, executorService, 100L);
+        keepaliveSalFacade.setListener(listener);
+
+        keepaliveSalFacade.onDeviceConnected(null, null, deviceRpc);
+
+        proxyRpc.invokeRpc(mock(SchemaPath.class), mock(NormalizedNode.class));
+
+        verify(listener, times(1)).disconnect();
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/netconf/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceTopologyAdapterTest.java b/opendaylight/netconf/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceTopologyAdapterTest.java
new file mode 100644 (file)
index 0000000..158c4c4
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * 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.sal.connect.netconf.sal;
+
+import static org.mockito.Matchers.any;
+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 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.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.controller.sal.connect.netconf.listener.NetconfDeviceCapabilities;
+import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
+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 NetconfDeviceTopologyAdapterTest {
+
+    private RemoteDeviceId id = new RemoteDeviceId("test", new InetSocketAddress("localhost", 22));
+
+    @Mock
+    private DataBroker broker;
+    @Mock
+    private WriteTransaction writeTx;
+    @Mock
+    private BindingTransactionChain txChain;
+    @Mock
+    private Node data;
+
+    private String txIdent = "test transaction";
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        doReturn(txChain).when(broker).createTransactionChain(any(TransactionChainListener.class));
+        doReturn(writeTx).when(txChain).newWriteOnlyTransaction();
+        doNothing().when(writeTx).put(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(Node.class));
+        doNothing().when(writeTx).merge(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(Node.class));
+
+        doReturn(txIdent).when(writeTx).getIdentifier();
+    }
+
+    @Test
+    public void testFailedDevice() throws Exception {
+        doReturn(Futures.immediateCheckedFuture(null)).when(writeTx).submit();
+
+        NetconfDeviceTopologyAdapter adapter = new NetconfDeviceTopologyAdapter(id, broker);
+        adapter.setDeviceAsFailed(null);
+
+        verify(txChain, times(2)).newWriteOnlyTransaction();
+        verify(writeTx, times(3)).put(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(Node.class));
+    }
+
+    @Test
+    public void testDeviceUpdate() throws Exception {
+        doReturn(Futures.immediateCheckedFuture(null)).when(writeTx).submit();
+
+        NetconfDeviceTopologyAdapter adapter = new NetconfDeviceTopologyAdapter(id, broker);
+        adapter.updateDeviceData(true, new NetconfDeviceCapabilities());
+
+        verify(txChain, times(2)).newWriteOnlyTransaction();
+        verify(writeTx, times(3)).put(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(Node.class));
+    }
+
+}
\ No newline at end of file
diff --git a/opendaylight/netconf/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/NetconfDeviceWriteOnlyTxTest.java b/opendaylight/netconf/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/NetconfDeviceWriteOnlyTxTest.java
new file mode 100644 (file)
index 0000000..f6a7e6a
--- /dev/null
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2014, 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.sal.connect.netconf.sal.tx;
+
+import static org.junit.Assert.fail;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.atMost;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_CANDIDATE_QNAME;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_FILTER_QNAME;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_RUNNING_QNAME;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.toPath;
+
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.Futures;
+import java.net.InetSocketAddress;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.InOrder;
+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.TransactionCommitFailedException;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
+import org.opendaylight.controller.md.sal.dom.spi.DefaultDOMRpcResult;
+import org.opendaylight.controller.sal.connect.netconf.NetconfDevice;
+import org.opendaylight.controller.sal.connect.netconf.util.NetconfBaseOps;
+import org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil;
+import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.NetconfState;
+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.MapNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+
+public class NetconfDeviceWriteOnlyTxTest {
+
+    private final RemoteDeviceId id = new RemoteDeviceId("test-mount", new InetSocketAddress(99));
+
+    @Mock
+    private DOMRpcService rpc;
+    private YangInstanceIdentifier yangIId;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+
+        final CheckedFuture<DefaultDOMRpcResult, Exception> successFuture =
+                Futures.immediateCheckedFuture(new DefaultDOMRpcResult(((NormalizedNode<?, ?>) null)));
+
+        doReturn(successFuture)
+                .doReturn(Futures.immediateFailedCheckedFuture(new IllegalStateException("Failed tx")))
+                .doReturn(successFuture)
+                .when(rpc).invokeRpc(any(SchemaPath.class), any(NormalizedNode.class));
+
+        yangIId = YangInstanceIdentifier.builder().node(NetconfState.QNAME).build();
+    }
+
+    @Test
+    public void testIgnoreNonVisibleData() {
+        final WriteCandidateTx tx = new WriteCandidateTx(id, new NetconfBaseOps(rpc, mock(SchemaContext.class)),
+                false, 60000L);
+        final MapNode emptyList = ImmutableNodes.mapNodeBuilder(NETCONF_FILTER_QNAME).build();
+        tx.merge(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.create(new YangInstanceIdentifier.NodeIdentifier(NETCONF_FILTER_QNAME)), emptyList);
+        tx.put(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.create(new YangInstanceIdentifier.NodeIdentifier(NETCONF_FILTER_QNAME)), emptyList);
+
+        verify(rpc, atMost(1)).invokeRpc(any(SchemaPath.class), any(NormalizedNode.class));
+    }
+
+    @Test
+    public void testDiscardChanges() {
+        final WriteCandidateTx tx = new WriteCandidateTx(id, new NetconfBaseOps(rpc, mock(SchemaContext.class)),
+                false, 60000L);
+        final CheckedFuture<Void, TransactionCommitFailedException> submitFuture = tx.submit();
+        try {
+            submitFuture.checkedGet();
+        } catch (final TransactionCommitFailedException e) {
+            // verify discard changes was sent
+            final InOrder inOrder = inOrder(rpc);
+            inOrder.verify(rpc).invokeRpc(toPath(NetconfMessageTransformUtil.NETCONF_LOCK_QNAME), NetconfBaseOps.getLockContent(NETCONF_CANDIDATE_QNAME));
+            inOrder.verify(rpc).invokeRpc(toPath(NetconfMessageTransformUtil.NETCONF_COMMIT_QNAME), NetconfMessageTransformUtil.COMMIT_RPC_CONTENT);
+            inOrder.verify(rpc).invokeRpc(eq(toPath(NetconfMessageTransformUtil.NETCONF_DISCARD_CHANGES_QNAME)), any(NormalizedNode.class));
+            inOrder.verify(rpc).invokeRpc(toPath(NetconfMessageTransformUtil.NETCONF_UNLOCK_QNAME), NetconfBaseOps.getUnLockContent(NETCONF_CANDIDATE_QNAME));
+            return;
+        }
+
+        fail("Submit should fail");
+    }
+
+    @Test
+    public void testFailedCommit() throws Exception {
+        final CheckedFuture<DefaultDOMRpcResult, Exception> rpcErrorFuture =
+                Futures.immediateCheckedFuture(new DefaultDOMRpcResult(RpcResultBuilder.newError(RpcError.ErrorType.APPLICATION, "a", "m")));
+
+        doReturn(Futures.immediateCheckedFuture(new DefaultDOMRpcResult(((NormalizedNode<?, ?>) null))))
+        .doReturn(rpcErrorFuture).when(rpc).invokeRpc(any(SchemaPath.class), any(NormalizedNode.class));
+
+        final WriteCandidateTx tx = new WriteCandidateTx(id, new NetconfBaseOps(rpc, mock(SchemaContext.class)),
+                false, 60000L);
+
+        final CheckedFuture<Void, TransactionCommitFailedException> submitFuture = tx.submit();
+        try {
+            submitFuture.checkedGet();
+        } catch (final TransactionCommitFailedException e) {
+            return;
+        }
+
+        fail("Submit should fail");
+    }
+
+    @Test
+    public void testDiscardChangesNotSentWithoutCandidate() {
+        doReturn(Futures.immediateCheckedFuture(new DefaultDOMRpcResult(((NormalizedNode<?, ?>) null))))
+                .doReturn(Futures.immediateFailedCheckedFuture(new IllegalStateException("Failed tx")))
+                .when(rpc).invokeRpc(any(SchemaPath.class), any(NormalizedNode.class));
+
+        final WriteRunningTx tx = new WriteRunningTx(id, new NetconfBaseOps(rpc, NetconfDevice.INIT_SCHEMA_CTX),
+                false, 60000L);
+        try {
+            tx.delete(LogicalDatastoreType.CONFIGURATION, yangIId);
+        } catch (final Exception e) {
+            // verify discard changes was sent
+            final InOrder inOrder = inOrder(rpc);
+            inOrder.verify(rpc).invokeRpc(toPath(NetconfMessageTransformUtil.NETCONF_LOCK_QNAME), NetconfBaseOps.getLockContent(NETCONF_RUNNING_QNAME));
+            inOrder.verify(rpc).invokeRpc(eq(toPath(NetconfMessageTransformUtil.NETCONF_EDIT_CONFIG_QNAME)), any(NormalizedNode.class));
+            inOrder.verify(rpc).invokeRpc(toPath(NetconfMessageTransformUtil.NETCONF_UNLOCK_QNAME), NetconfBaseOps.getUnLockContent(NETCONF_RUNNING_QNAME));
+            return;
+        }
+
+        fail("Delete should fail");
+    }
+
+}
diff --git a/opendaylight/netconf/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/ReadOnlyTxTest.java b/opendaylight/netconf/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/ReadOnlyTxTest.java
new file mode 100644 (file)
index 0000000..e8587d6
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * 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.sal.connect.netconf.sal.tx;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doReturn;
+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.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationException;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
+import org.opendaylight.controller.md.sal.dom.spi.DefaultDOMRpcResult;
+import org.opendaylight.controller.sal.connect.netconf.util.NetconfBaseOps;
+import org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil;
+import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
+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.opendaylight.yangtools.yang.model.api.SchemaPath;
+
+public class ReadOnlyTxTest {
+
+    private static final YangInstanceIdentifier path = YangInstanceIdentifier.create();
+
+    @Mock
+    private DOMRpcService rpc;
+    @Mock
+    private NormalizedNode<?, ?> mockedNode;
+
+    @Before
+    public void setUp() throws DataNormalizationException {
+        MockitoAnnotations.initMocks(this);
+        doReturn(Futures.immediateCheckedFuture(new DefaultDOMRpcResult(mockedNode))).when(rpc)
+                .invokeRpc(any(SchemaPath.class), any(NormalizedNode.class));
+        doReturn("node").when(mockedNode).toString();
+    }
+
+    @Test
+    public void testRead() 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.read(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.create());
+        verify(rpc).invokeRpc(Mockito.eq(NetconfMessageTransformUtil.toPath(NetconfMessageTransformUtil.NETCONF_GET_CONFIG_QNAME)), any(NormalizedNode.class));
+        readOnlyTx.read(LogicalDatastoreType.OPERATIONAL, path);
+        verify(rpc).invokeRpc(Mockito.eq(NetconfMessageTransformUtil.toPath(NetconfMessageTransformUtil.NETCONF_GET_QNAME)), any(NormalizedNode.class));
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/netconf/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/schema/mapping/NetconfMessageTransformerTest.java b/opendaylight/netconf/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/schema/mapping/NetconfMessageTransformerTest.java
new file mode 100644 (file)
index 0000000..b1e7477
--- /dev/null
@@ -0,0 +1,309 @@
+/*
+ * Copyright (c) 2014, 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.sal.connect.netconf.schema.mapping;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.GET_SCHEMA_QNAME;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_CANDIDATE_QNAME;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_COMMIT_QNAME;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_DATA_QNAME;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_DISCARD_CHANGES_QNAME;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_EDIT_CONFIG_QNAME;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_GET_CONFIG_QNAME;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_GET_QNAME;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_LOCK_QNAME;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_RUNNING_QNAME;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.createEditConfigStructure;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.toFilterStructure;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.toId;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.toPath;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import javax.xml.transform.dom.DOMSource;
+import org.custommonkey.xmlunit.Diff;
+import org.custommonkey.xmlunit.ElementNameAndAttributeQualifier;
+import org.custommonkey.xmlunit.XMLUnit;
+import org.hamcrest.CoreMatchers;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
+import org.opendaylight.controller.netconf.api.NetconfMessage;
+import org.opendaylight.controller.sal.connect.netconf.NetconfDevice;
+import org.opendaylight.controller.sal.connect.netconf.schema.NetconfRemoteSchemaYangSourceProvider;
+import org.opendaylight.controller.sal.connect.netconf.util.NetconfBaseOps;
+import org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.base._1._0.rev110601.$YangModuleInfoImpl;
+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.Capabilities;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.Schemas;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.schemas.Schema;
+import org.opendaylight.yangtools.sal.binding.generator.impl.ModuleInfoBackedContext;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.ModifyAction;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.AnyXmlNode;
+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.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.w3c.dom.Element;
+import org.xml.sax.SAXException;
+
+public class NetconfMessageTransformerTest {
+
+    private NetconfMessageTransformer netconfMessageTransformer;
+    private SchemaContext schema;
+
+    @Before
+    public void setUp() throws Exception {
+        XMLUnit.setIgnoreWhitespace(true);
+        XMLUnit.setIgnoreAttributeOrder(true);
+        XMLUnit.setIgnoreComments(true);
+
+        schema = getSchema(true);
+        netconfMessageTransformer = getTransformer(schema);
+
+    }
+
+    @Test
+    public void testLockRequestBaseSchemaNotPresent() throws Exception {
+        final SchemaContext partialSchema = getSchema(false);
+        final NetconfMessageTransformer transformer = getTransformer(partialSchema);
+        final NetconfMessage netconfMessage = transformer.toRpcRequest(toPath(NETCONF_LOCK_QNAME),
+                NetconfBaseOps.getLockContent(NETCONF_CANDIDATE_QNAME));
+
+        assertThat(XmlUtil.toString(netconfMessage.getDocument()), CoreMatchers.containsString("<lock"));
+        assertThat(XmlUtil.toString(netconfMessage.getDocument()), CoreMatchers.containsString("<rpc"));
+    }
+
+    @Test
+    public void tesLockSchemaRequest() throws Exception {
+        final SchemaContext partialSchema = getSchema(false);
+        final NetconfMessageTransformer transformer = getTransformer(partialSchema);
+        final String result = "<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"><ok/></rpc-reply>";
+
+        transformer.toRpcResult(new NetconfMessage(XmlUtil.readXmlToDocument(result)), toPath(NETCONF_LOCK_QNAME));
+    }
+
+    @Test
+    public void testDiscardChangesRequest() throws Exception {
+        final NetconfMessage netconfMessage = netconfMessageTransformer.toRpcRequest(toPath(NETCONF_DISCARD_CHANGES_QNAME), null);
+        assertThat(XmlUtil.toString(netconfMessage.getDocument()), CoreMatchers.containsString("<discard"));
+        assertThat(XmlUtil.toString(netconfMessage.getDocument()), CoreMatchers.containsString("<rpc"));
+        assertThat(XmlUtil.toString(netconfMessage.getDocument()), CoreMatchers.containsString("message-id"));
+    }
+
+    @Test
+    public void tesGetSchemaRequest() throws Exception {
+        final NetconfMessage netconfMessage = netconfMessageTransformer.toRpcRequest(toPath(GET_SCHEMA_QNAME),
+                NetconfRemoteSchemaYangSourceProvider.createGetSchemaRequest("module", Optional.of("2012-12-12")));
+        assertSimilarXml(netconfMessage, "<rpc message-id=\"m-0\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n" +
+                "<get-schema xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring\">\n" +
+                "<format>yang</format>\n" +
+                "<identifier>module</identifier>\n" +
+                "<version>2012-12-12</version>\n" +
+                "</get-schema>\n" +
+                "</rpc>");
+    }
+
+    @Test
+    public void tesGetSchemaResponse() throws Exception {
+        final NetconfMessageTransformer netconfMessageTransformer = getTransformer(getSchema(true));
+        final NetconfMessage response = new NetconfMessage(XmlUtil.readXmlToDocument(
+                "<rpc-reply message-id=\"101\"\n" +
+                        "xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n" +
+                        "<data\n" +
+                        "xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring\">\n" +
+                        "<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">\n" +
+                        "Random YANG SCHEMA\n" +
+                        "</xs:schema>\n" +
+                        "</data>\n" +
+                        "</rpc-reply>"
+        ));
+        final DOMRpcResult compositeNodeRpcResult = netconfMessageTransformer.toRpcResult(response, toPath(GET_SCHEMA_QNAME));
+        assertTrue(compositeNodeRpcResult.getErrors().isEmpty());
+        assertNotNull(compositeNodeRpcResult.getResult());
+        final DOMSource schemaContent = ((AnyXmlNode) ((ContainerNode) compositeNodeRpcResult.getResult()).getValue().iterator().next()).getValue();
+        assertThat(((Element) schemaContent.getNode()).getTextContent(), CoreMatchers.containsString("Random YANG SCHEMA"));
+    }
+
+    @Test
+    public void testGetConfigResponse() throws Exception {
+        final NetconfMessage response = new NetconfMessage(XmlUtil.readXmlToDocument("<rpc-reply message-id=\"101\"\n" +
+                "xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n" +
+                "<data>\n" +
+                "<netconf-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring\">\n" +
+                "<schemas>\n" +
+                "<schema>\n" +
+                "<identifier>module</identifier>\n" +
+                "<version>2012-12-12</version>\n" +
+                "<format xmlns:x=\"urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring\">x:yang</format>\n" +
+                "</schema>\n" +
+                "</schemas>\n" +
+                "</netconf-state>\n" +
+                "</data>\n" +
+                "</rpc-reply>"));
+
+        final NetconfMessageTransformer netconfMessageTransformer = getTransformer(getSchema(true));
+        final DOMRpcResult compositeNodeRpcResult = netconfMessageTransformer.toRpcResult(response, toPath(NETCONF_GET_CONFIG_QNAME));
+        assertTrue(compositeNodeRpcResult.getErrors().isEmpty());
+        assertNotNull(compositeNodeRpcResult.getResult());
+
+        final List<DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?>> values = Lists.newArrayList(
+                NetconfRemoteSchemaYangSourceProvider.createGetSchemaRequest("module", Optional.of("2012-12-12")).getValue());
+
+        final Map<QName, Object> keys = Maps.newHashMap();
+        for (final DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?> value : values) {
+            keys.put(value.getNodeType(), value.getValue());
+        }
+
+        final YangInstanceIdentifier.NodeIdentifierWithPredicates identifierWithPredicates = new YangInstanceIdentifier.NodeIdentifierWithPredicates(Schema.QNAME, keys);
+        final MapEntryNode schemaNode = Builders.mapEntryBuilder().withNodeIdentifier(identifierWithPredicates).withValue(values).build();
+
+        final ContainerNode data = (ContainerNode) ((ContainerNode) compositeNodeRpcResult.getResult()).getChild(toId(NETCONF_DATA_QNAME)).get();
+        final ContainerNode state = (ContainerNode) data.getChild(toId(NetconfState.QNAME)).get();
+        final ContainerNode schemas = (ContainerNode) state.getChild(toId(Schemas.QNAME)).get();
+        final MapNode schemaParent = (MapNode) schemas.getChild(toId(Schema.QNAME)).get();
+        assertEquals(1, Iterables.size(schemaParent.getValue()));
+
+        assertEquals(schemaNode, schemaParent.getValue().iterator().next());
+    }
+
+    @Test
+    public void testGetConfigRequest() throws Exception {
+        final DataContainerChild<?, ?> filter = toFilterStructure(
+                YangInstanceIdentifier.create(toId(NetconfState.QNAME), toId(Schemas.QNAME)), schema);
+
+        final DataContainerChild<?, ?> source = NetconfBaseOps.getSourceNode(NETCONF_RUNNING_QNAME);
+
+        final NetconfMessage netconfMessage = netconfMessageTransformer.toRpcRequest(toPath(NETCONF_GET_CONFIG_QNAME),
+                NetconfMessageTransformUtil.wrap(NETCONF_GET_CONFIG_QNAME, source, filter));
+
+        assertSimilarXml(netconfMessage, "<rpc message-id=\"m-0\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n" +
+                "<get-config xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n" +
+                "<filter xmlns:ns0=\"urn:ietf:params:xml:ns:netconf:base:1.0\" ns0:type=\"subtree\">\n" +
+                "<netconf-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring\">\n" +
+                "<schemas/>\n" +
+                "</netconf-state>" +
+                "</filter>\n" +
+                "<source>\n" +
+                "<running/>\n" +
+                "</source>\n" +
+                "</get-config>" +
+                "</rpc>");
+    }
+
+    @Test
+    public void testEditConfigRequest() throws Exception {
+        final List<DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?>> values = Lists.newArrayList(
+            NetconfRemoteSchemaYangSourceProvider.createGetSchemaRequest("module", Optional.of("2012-12-12")).getValue());
+
+        final Map<QName, Object> keys = Maps.newHashMap();
+        for (final DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?> value : values) {
+            keys.put(value.getNodeType(), value.getValue());
+        }
+
+        final YangInstanceIdentifier.NodeIdentifierWithPredicates identifierWithPredicates = new YangInstanceIdentifier.NodeIdentifierWithPredicates(Schema.QNAME, keys);
+        final MapEntryNode schemaNode = Builders.mapEntryBuilder().withNodeIdentifier(identifierWithPredicates).withValue(values).build();
+
+        final YangInstanceIdentifier id = YangInstanceIdentifier.builder().node(NetconfState.QNAME).node(Schemas.QNAME).node(Schema.QNAME).nodeWithKey(Schema.QNAME, keys).build();
+        final DataContainerChild<?, ?> editConfigStructure = createEditConfigStructure(NetconfDevice.INIT_SCHEMA_CTX, id, Optional.<ModifyAction>absent(), Optional.<NormalizedNode<?, ?>>fromNullable(schemaNode));
+
+        final DataContainerChild<?, ?> target = NetconfBaseOps.getTargetNode(NETCONF_CANDIDATE_QNAME);
+
+        final ContainerNode wrap = NetconfMessageTransformUtil.wrap(NETCONF_EDIT_CONFIG_QNAME, editConfigStructure, target);
+        final NetconfMessage netconfMessage = netconfMessageTransformer.toRpcRequest(toPath(NETCONF_EDIT_CONFIG_QNAME), wrap);
+
+        assertSimilarXml(netconfMessage, "<rpc message-id=\"m-0\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n" +
+                "<edit-config>\n" +
+                "<target>\n" +
+                "<candidate/>\n" +
+                "</target>\n" +
+                "<config>\n" +
+                "<netconf-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring\">\n" +
+                "<schemas>\n" +
+                "<schema>\n" +
+                "<identifier>module</identifier>\n" +
+                "<version>2012-12-12</version>\n" +
+                "<format>yang</format>\n" +
+                "</schema>\n" +
+                "</schemas>\n" +
+                "</netconf-state>\n" +
+                "</config>\n" +
+                "</edit-config>\n" +
+                "</rpc>");
+    }
+
+    private void assertSimilarXml(final NetconfMessage netconfMessage, final String xmlContent) throws SAXException, IOException {
+        final Diff diff = XMLUnit.compareXML(netconfMessage.getDocument(), XmlUtil.readXmlToDocument(xmlContent));
+        diff.overrideElementQualifier(new ElementNameAndAttributeQualifier());
+        assertTrue(diff.toString(), diff.similar());
+    }
+
+    @Test
+    public void testGetRequest() throws Exception {
+
+        final QName capability = QName.create(Capabilities.QNAME, "capability");
+        final DataContainerChild<?, ?> filter = toFilterStructure(
+                YangInstanceIdentifier.create(toId(NetconfState.QNAME), toId(Capabilities.QNAME), toId(capability), new YangInstanceIdentifier.NodeWithValue(capability, "a:b:c")), schema);
+
+        final NetconfMessage netconfMessage = netconfMessageTransformer.toRpcRequest(toPath(NETCONF_GET_QNAME),
+                NetconfMessageTransformUtil.wrap(NETCONF_GET_QNAME, filter));
+
+        assertSimilarXml(netconfMessage, "<rpc message-id=\"m-0\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">" +
+                "<get xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n" +
+                "<filter xmlns:ns0=\"urn:ietf:params:xml:ns:netconf:base:1.0\" ns0:type=\"subtree\">\n" +
+                "<netconf-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring\">\n" +
+                "<capabilities>\n" +
+                "<capability>a:b:c</capability>\n" +
+                "</capabilities>\n" +
+                "</netconf-state>" +
+                "</filter>\n" +
+                "</get>" +
+                "</rpc>");
+    }
+
+    private NetconfMessageTransformer getTransformer(final SchemaContext schema) {
+        return new NetconfMessageTransformer(schema, true);
+    }
+
+    @Test
+    public void testCommitResponse() throws Exception {
+        final NetconfMessage response = new NetconfMessage(XmlUtil.readXmlToDocument(
+                "<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"><ok/></rpc-reply>"
+        ));
+        final DOMRpcResult compositeNodeRpcResult = netconfMessageTransformer.toRpcResult(response, toPath(NETCONF_COMMIT_QNAME));
+        assertTrue(compositeNodeRpcResult.getErrors().isEmpty());
+        assertNull(compositeNodeRpcResult.getResult());
+    }
+
+    public SchemaContext getSchema(boolean addBase) {
+        final ModuleInfoBackedContext moduleInfoBackedContext = ModuleInfoBackedContext.create();
+        if(addBase) {
+            moduleInfoBackedContext.addModuleInfos(Collections.singleton($YangModuleInfoImpl.getInstance()));
+        }
+        moduleInfoBackedContext.addModuleInfos(Collections.singleton(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.$YangModuleInfoImpl.getInstance()));
+        return moduleInfoBackedContext.tryToCreateSchemaContext().get();
+    }
+}
diff --git a/opendaylight/netconf/sal-netconf-connector/src/test/resources/netconf-state.schemas.payload.xml b/opendaylight/netconf/sal-netconf-connector/src/test/resources/netconf-state.schemas.payload.xml
new file mode 100644 (file)
index 0000000..0213415
--- /dev/null
@@ -0,0 +1,514 @@
+<ncm:schemas xmlns:ncm="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:threadpool</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>threadpool</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2013-04-09</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:logback:config</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>config-logging</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2013-07-16</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:model:statistics:types</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-statistics-types</ncm:identifier>
+        <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2013-09-25</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:md:sal:core:spi:config-dom-store</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-config-dom-datastore</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2014-06-17</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:flow:table:statistics</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-flow-table-statistics</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2013-12-15</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:meter:service</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>sal-meter</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2013-09-18</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:config:toaster-provider:impl</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>toaster-provider-impl</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2014-01-31</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:table:types</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-table-types</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2013-10-26</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:table:service</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>sal-table</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2013-10-26</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:shutdown</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>shutdown</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2013-12-18</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:port:service</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>sal-port</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2013-11-07</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:netty:eventexecutor</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>netty-event-executor</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2013-11-12</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>sal-remote</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2014-01-14</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:model:topology:view</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-topology-view</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2013-10-30</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:netty:threadgroup</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>threadgroup</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2013-11-07</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:TBD:params:xml:ns:yang:network-topology</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>network-topology</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2013-07-12</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:fixed</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>threadpool-impl-fixed</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2013-12-01</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-sal-binding-broker-impl</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2013-10-28</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:ietf:params:xml:ns:yang:ietf-restconf</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>ietf-restconf</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2013-10-19</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:node:error:service</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>node-error</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2014-04-10</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:flow:errors</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>flow-errors</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2013-11-16</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:flow:service</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>sal-flow</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2013-08-19</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:ietf:params:xml:ns:yang:rpc-context</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>rpc-context</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2013-06-17</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:md:sal:core:spi:operational-dom-store
+        </ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-operational-dom-datastore</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2014-06-17</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:flow:types:queue</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-queue-types</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2013-09-25</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>ietf-netconf-monitoring</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2010-10-04</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:netconf-node-inventory</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>netconf-node-inventory</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2014-01-08</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:ietf:params:xml:ns:yang:ietf-yang-types</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>ietf-yang-types</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2013-07-15</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:meter:statistics</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-meter-statistics</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2013-11-11</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:flow:inventory</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>flow-node-inventory</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2013-08-19</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>odl-sal-netconf-connector-cfg</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2013-10-28</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:scheduled</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>threadpool-impl-scheduled</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2013-12-01</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:TBD:params:xml:ns:yang:network-topology</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>network-topology</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2013-10-21</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>http://netconfcentral.org/ns/toaster</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>toaster</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2009-11-20</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:config:netconf</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>odl-netconf-cfg</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2014-04-08</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:meter:types</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-meter-types</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2013-09-18</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-sal-dom-broker-impl</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2013-10-28</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:flow:topology:discovery</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>flow-topology-discovery</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2013-08-19</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:yang:extension:yang-ext</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>yang-ext</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2013-07-09</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>threadpool-impl</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2013-04-05</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:flow:types:port</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-port-types</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2013-09-25</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-md-sal-binding</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2013-10-28</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:packet:service</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>packet-processing</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2013-07-09</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:flexible</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>threadpool-impl-flexible</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2013-12-01</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:queue:service</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>sal-queue</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2013-11-07</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:ietf:params:xml:ns:yang:ietf-inet-types</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>ietf-inet-types</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2010-09-24</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:md:sal:rest:connector</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-rest-connector</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2014-07-24</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:flow:transaction</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>flow-capable-transaction</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2013-11-03</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:flow:statistics</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-flow-statistics</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2013-08-19</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:protocol:framework</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>protocol-framework</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2014-03-13</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:model:match:types</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-match-types</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2013-10-26</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:ietf:params:xml:ns:yang:ietf-yang-types</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>ietf-yang-types</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2010-09-24</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:group:service</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>sal-group</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2013-09-18</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:inmemory-datastore-provider</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-inmemory-datastore-provider</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2014-06-17</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:netty:timer</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>netty-timer</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2013-11-19</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:group:statistics</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-group-statistics</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2013-11-11</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:config</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>config</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2013-04-05</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:config:netconf:client:dispatcher</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>odl-netconfig-client-cfg</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2014-04-08</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:l2:types</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-l2-types</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2013-08-27</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:action:types</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-action-types</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2013-11-12</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-md-sal-dom</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2013-10-28</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:md:sal:common</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-md-sal-common</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2013-10-28</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:group:types</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-group-types</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2013-10-18</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring-extension</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>ietf-netconf-monitoring-extension</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2013-12-10</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:inventory</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-inventory</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2013-08-19</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:netty</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>netty</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2013-11-19</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:model:topology:general</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-topology</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2013-10-30</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:port:statistics</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-port-statistics</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version></ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:queue:statistics</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-queue-statistics</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2013-12-16</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:config:kitchen-service:impl</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>kitchen-service-impl</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2014-01-31</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:flow:types</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-flow-types</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2013-10-26</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:shutdown:impl</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>shutdown-impl</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2013-12-18</ncm:version>
+    </ncm:schema>
+    <ncm:schema>
+        <ncm:namespace>urn:opendaylight:model:topology:inventory</ncm:namespace>
+        <ncm:location>NETCONF</ncm:location>
+        <ncm:identifier>opendaylight-topology-inventory</ncm:identifier>
+                <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
+        <ncm:version>2013-10-30</ncm:version>
+    </ncm:schema>
+</ncm:schemas>
\ No newline at end of file
diff --git a/opendaylight/netconf/sal-netconf-connector/src/test/resources/notification-payload.xml b/opendaylight/netconf/sal-netconf-connector/src/test/resources/notification-payload.xml
new file mode 100644 (file)
index 0000000..431787d
--- /dev/null
@@ -0,0 +1,14 @@
+<notification xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0">
+<eventTime>2007-07-08T00:01:00Z</eventTime>
+<user-visited-page xmlns="org:opendaylight:notification:test:ns:yang:user-notification">
+  <ui:incoming-user xmlns:ui="org:opendaylight:notification:test:ns:yang:user-notification">ui:public-user</ui:incoming-user>
+  <ip-address>172.23.29.104</ip-address>
+  <mac>00:11:00:ff:dd:02</mac>
+  <browser-id>Chrome 35.0.1916.153 m</browser-id>
+  <region>
+    <name>Slovakia</name>
+    <time-zone>UTC/GMT+2</time-zone>
+  </region>
+  <visiting-date>2014-07-08 11:20:48</visiting-date>
+</user-visited-page>
+</notification>
\ No newline at end of file
diff --git a/opendaylight/netconf/sal-netconf-connector/src/test/resources/schemas/config-test-rpc.yang b/opendaylight/netconf/sal-netconf-connector/src/test/resources/schemas/config-test-rpc.yang
new file mode 100644 (file)
index 0000000..18a4ead
--- /dev/null
@@ -0,0 +1,176 @@
+module config-test-rpc {
+    namespace "urn:opendaylight:params:xml:ns:yang:controller:md:sal:test:rpc:config:defs";
+    prefix "rpc";
+
+    organization
+    "Cisco Systems, Inc.";
+
+    contact
+    "lsedlak@cisco.com";
+
+    description "Test model containing hacked definition of rpc edit-config and definitions for
+        get and get-config rpc operations.
+        The rpc definition is copied from rfc 6241 Appendix C: http://tools.ietf.org/html/rfc6241#appendix-C";
+
+    revision 2014-07-21 {
+        description "Initial revision.";
+    }
+
+    extension get-filter-element-attributes {
+          description
+            "If this extension is present within an 'anyxml'
+             statement named 'filter', which must be conceptually
+             defined within the RPC input section for the <get>
+             and <get-config> protocol operations, then the
+             following unqualified XML attribute is supported
+             within the <filter> element, within a <get> or
+             <get-config> protocol operation:
+
+               type : optional attribute with allowed
+                      value strings 'subtree' and 'xpath'.
+                      If missing, the default value is 'subtree'.
+
+             If the 'xpath' feature is supported, then the
+             following unqualified XML attribute is
+             also supported:
+
+               select: optional attribute containing a
+                       string representing an XPath expression.
+                       The 'type' attribute must be equal to 'xpath'
+                       if this attribute is present.";
+    }
+
+    rpc edit-config {
+        description "The <edit-config> operation loads all or part of a specified
+             configuration to the specified target configuration.";
+
+        reference "RFC 6241, Section 7.2";
+
+        input {
+            container target {
+                description "Particular configuration to edit.";
+
+                choice config-target {
+                    mandatory true;
+                    description "The configuration target.";
+
+                    leaf candidate {
+                        if-feature candidate;
+                        type empty;
+                        description "The candidate configuration is the config target.";
+                    }
+
+                    leaf running {
+                        if-feature writable-running;
+                        type empty;
+                        description "The running configuration is the config source.";
+                    }
+                }
+            }
+
+            choice edit-content {
+                mandatory true;
+                description "The content for the edit operation.";
+
+                anyxml config {
+                    description
+                      "Inline Config content.";
+                }
+
+                leaf url {
+                    if-feature url;
+                    type string;
+                    description
+                      "URL-based config content.";
+                }
+            }
+        }
+    }
+
+    rpc get-config {
+      description
+        "Retrieve all or part of a specified configuration.";
+
+      reference "RFC 6241, Section 7.1";
+
+      input {
+        container source {
+          description "Particular configuration to retrieve.";
+
+            choice config-source {
+                mandatory true;
+                description
+                  "The configuration to retrieve.";
+                leaf candidate {
+                  if-feature candidate;
+                  type empty;
+                  description
+                    "The candidate configuration is the config source.";
+                }
+                leaf running {
+                  type empty;
+                  description
+                    "The running configuration is the config source.";
+                }
+                leaf startup {
+                  if-feature startup;
+                  type empty;
+                  description
+                    "The startup configuration is the config source.
+                     This is optional-to-implement on the server because
+                     not all servers will support filtering for this
+                     datastore.";
+                }
+            }
+        }
+
+        anyxml filter {
+            description "Subtree or XPath filter to use.";
+                get-filter-element-attributes;
+            }
+        }
+
+        output {
+            anyxml data {
+              description
+                "Copy of the source datastore subset that matched
+                 the filter criteria (if any).  An empty data container
+                 indicates that the request did not produce any results.";
+            }
+        }
+    }
+
+    rpc get {
+        description "Retrieve running configuration and device state information.";
+
+        reference "RFC 6241, Section 7.7";
+
+        input {
+            anyxml filter {
+              description
+                "This parameter specifies the portion of the system
+                 configuration and state data to retrieve.";
+              get-filter-element-attributes;
+            }
+        }
+
+        output {
+            anyxml data {
+              description
+                "Copy of the running datastore subset and/or state
+                 data that matched the filter criteria (if any).
+                 An empty data container indicates that the request did not
+                 produce any results.";
+            }
+        }
+    }
+
+      rpc discard-changes {
+        if-feature candidate;
+
+        description
+          "Revert the candidate configuration to the current
+           running configuration.";
+        reference "RFC 6241, Section 8.3.4.2";
+      }
+}
diff --git a/opendaylight/netconf/sal-netconf-connector/src/test/resources/schemas/rpc-notification-subscription.yang b/opendaylight/netconf/sal-netconf-connector/src/test/resources/schemas/rpc-notification-subscription.yang
new file mode 100644 (file)
index 0000000..b13d90f
--- /dev/null
@@ -0,0 +1,38 @@
+module rpc-notification-subscription {
+
+  namespace "urn:opendaylight:params:xml:ns:yang:controller:md:sal:rpc-test";
+  prefix "rpc";
+
+  organization
+    "Cisco Systems, Inc.";
+
+  contact
+    "lsedlak@cisco.com";
+
+  description
+    "Test model for testing of rpc INPUT parameter during subscription call.";
+
+  revision 2014-07-14 {
+    description
+      "Initial revision.";
+  }
+
+  rpc subscribe {
+    description
+      "Test rpc to init subscription";
+
+    input {
+      leaf stream-name {
+        type string;
+        default "NETCONF";
+        description
+          "Optional stream name param.";
+      }
+
+      anyxml data {
+        description
+          "Optional additional data.";
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/opendaylight/netconf/sal-netconf-connector/src/test/resources/schemas/test-module.yang b/opendaylight/netconf/sal-netconf-connector/src/test/resources/schemas/test-module.yang
new file mode 100644 (file)
index 0000000..cd732fc
--- /dev/null
@@ -0,0 +1,18 @@
+module test-module {
+    yang-version 1;
+    namespace "test:namespace";
+    prefix "tt";
+
+    description
+        "Types for testing";
+
+    revision "2013-07-22";
+
+
+    container c {
+        leaf a {
+            type string;
+        }
+    }
+
+}
diff --git a/opendaylight/netconf/sal-netconf-connector/src/test/resources/schemas/user-notification.yang b/opendaylight/netconf/sal-netconf-connector/src/test/resources/schemas/user-notification.yang
new file mode 100644 (file)
index 0000000..50d2206
--- /dev/null
@@ -0,0 +1,56 @@
+module user-notification {
+    yang-version 1;
+    namespace "org:opendaylight:notification:test:ns:yang:user-notification";
+    prefix "user";
+
+    organization "Cisco Systems";
+    contact "Lukas Sedlak";
+    description "Test model for testing notifications";
+
+    revision "2014-07-08" {
+        description "Initial revision";
+    }
+
+    identity user-identity {
+        description "Identity of user incoming to Web Page";
+    }
+
+    identity public-user {
+        base user-identity;
+        description "Identity of random public non-registered user";
+    }
+
+    notification user-visited-page {
+        leaf incoming-user {
+            type identityref {
+                base "user-identity";
+            }
+        }
+
+        leaf ip-address {
+            type string;
+        }
+
+        leaf mac {
+            type string;
+        }
+
+        leaf browser-id {
+            type string;
+        }
+
+        container region {
+            leaf name {
+                type string;
+            }
+
+            leaf time-zone {
+                type string;
+            }
+        }
+
+        leaf visiting-date {
+            type string;
+        }
+    }
+}
\ No newline at end of file
similarity index 98%
rename from opendaylight/netconf/netconf-cli/pom.xml
rename to opendaylight/netconf/tools/netconf-cli/pom.xml
index 2d47df078e89de3a2ecdc6727cb4e37483aab09a..14de621b6886d62ef1686c714cb960ca58e9c925 100644 (file)
@@ -9,7 +9,7 @@
 
   <parent>
     <groupId>org.opendaylight.controller</groupId>
-    <artifactId>netconf-subsystem</artifactId>
+    <artifactId>netconf-tools</artifactId>
     <version>0.4.0-SNAPSHOT</version>
   </parent>
   <artifactId>netconf-cli</artifactId>
@@ -15,12 +15,12 @@ import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.netconf.cli.io.BaseConsoleContext;
 import org.opendaylight.controller.netconf.cli.io.ConsoleContext;
 import org.opendaylight.controller.netconf.cli.io.ConsoleIO;
 import org.opendaylight.controller.netconf.cli.reader.AbstractReader;
 import org.opendaylight.controller.netconf.cli.reader.ReadingException;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
similarity index 99%
rename from opendaylight/netconf/netconf-testtool/pom.xml
rename to opendaylight/netconf/tools/netconf-testtool/pom.xml
index bce0db04e0ca28bd62072f59a6084fb772231b2e..36063c054fa1cb583b8b728a55dda426ca9160cc 100644 (file)
@@ -13,7 +13,7 @@
 
     <parent>
         <groupId>org.opendaylight.controller</groupId>
-        <artifactId>netconf-subsystem</artifactId>
+        <artifactId>netconf-tools</artifactId>
         <version>0.4.0-SNAPSHOT</version>
     </parent>
 
@@ -16,7 +16,7 @@ import com.google.common.collect.Lists;
 import java.util.Collections;
 import java.util.Set;
 import javax.annotation.Nullable;
-import org.opendaylight.controller.netconf.api.Capability;
+import org.opendaylight.controller.config.util.capability.Capability;
 import org.opendaylight.controller.netconf.api.monitoring.NetconfManagementSession;
 import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
@@ -108,22 +108,17 @@ public class DummyMonitoringService implements NetconfMonitoringService {
     }
 
     @Override
-    public void onCapabilitiesAdded(Set<Capability> addedCaps) {
-
-    }
-
-    @Override
-    public void onCapabilitiesRemoved(Set<Capability> removedCaps) {
+    public void onSessionUp(NetconfManagementSession session) {
 
     }
 
     @Override
-    public void onSessionUp(NetconfManagementSession session) {
+    public void onSessionDown(NetconfManagementSession session) {
 
     }
 
     @Override
-    public void onSessionDown(NetconfManagementSession session) {
+    public void onCapabilitiesChanged(Set<Capability> added, Set<Capability> removed) {
 
     }
 }
similarity index 99%
rename from opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/Main.java
rename to opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/Main.java
index e273254e0ed3bc8520cdcaf910957b982958f3b9..c6004835f6858190fc7aba211b7afce5b193390e 100644 (file)
@@ -31,8 +31,8 @@ import net.sourceforge.argparse4j.ArgumentParsers;
 import net.sourceforge.argparse4j.annotation.Arg;
 import net.sourceforge.argparse4j.inf.ArgumentParser;
 import net.sourceforge.argparse4j.inf.ArgumentParserException;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
+import org.opendaylight.controller.config.util.xml.XmlElement;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
@@ -12,8 +12,8 @@ import com.google.common.base.Optional;
 import java.util.Collections;
 import java.util.Date;
 import java.util.List;
-import org.opendaylight.controller.netconf.api.Capability;
-import org.opendaylight.controller.netconf.confignetconfconnector.util.Util;
+import org.opendaylight.controller.config.facade.xml.util.Util;
+import org.opendaylight.controller.config.util.capability.Capability;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.parser.builder.impl.ModuleBuilder;
 
@@ -30,7 +30,6 @@ import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
-import java.lang.management.ManagementFactory;
 import java.net.BindException;
 import java.net.Inet4Address;
 import java.net.InetSocketAddress;
@@ -39,6 +38,7 @@ import java.net.UnknownHostException;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.util.AbstractMap;
+import java.util.Collections;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
@@ -55,11 +55,10 @@ import org.apache.sshd.common.util.ThreadUtils;
 import org.apache.sshd.server.PasswordAuthenticator;
 import org.apache.sshd.server.keyprovider.PEMGeneratorHostKeyProvider;
 import org.apache.sshd.server.session.ServerSession;
-import org.opendaylight.controller.netconf.api.Capability;
+import org.opendaylight.controller.config.util.capability.Capability;
 import org.opendaylight.controller.netconf.api.monitoring.CapabilityListener;
 import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService;
 import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.impl.DefaultCommitNotificationProducer;
 import org.opendaylight.controller.netconf.impl.NetconfServerDispatcherImpl;
 import org.opendaylight.controller.netconf.impl.NetconfServerSessionNegotiatorFactory;
 import org.opendaylight.controller.netconf.impl.SessionIdProvider;
@@ -152,14 +151,12 @@ public class NetconfDeviceSimulator implements Closeable {
         aggregatedNetconfOperationServiceFactory.onAddNetconfOperationServiceFactory(simulatedOperationProvider);
         aggregatedNetconfOperationServiceFactory.onAddNetconfOperationServiceFactory(monitoringService);
 
-        final DefaultCommitNotificationProducer commitNotifier = new DefaultCommitNotificationProducer(ManagementFactory.getPlatformMBeanServer());
-
         final Set<String> serverCapabilities = exi
                 ? NetconfServerSessionNegotiatorFactory.DEFAULT_BASE_CAPABILITIES
                 : Sets.newHashSet(XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_BASE_1_0, XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_BASE_1_1);
 
         final NetconfServerSessionNegotiatorFactory serverNegotiatorFactory = new NetconfServerSessionNegotiatorFactory(
-                hashedWheelTimer, aggregatedNetconfOperationServiceFactory, idProvider, generateConfigsTimeout, commitNotifier, monitoringService1, serverCapabilities);
+                hashedWheelTimer, aggregatedNetconfOperationServiceFactory, idProvider, generateConfigsTimeout, monitoringService1, serverCapabilities);
 
         final NetconfServerDispatcherImpl.ServerChannelInitializer serverChannelInitializer = new NetconfServerDispatcherImpl.ServerChannelInitializer(
                 serverNegotiatorFactory);
@@ -423,7 +420,7 @@ public class NetconfDeviceSimulator implements Closeable {
 
         @Override
         public AutoCloseable registerCapabilityListener(final CapabilityListener listener) {
-            listener.onCapabilitiesAdded(caps);
+            listener.onCapabilitiesChanged(caps, Collections.<Capability>emptySet());
             return new AutoCloseable() {
                 @Override
                 public void close() throws Exception {}
@@ -16,8 +16,8 @@ import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 import java.util.concurrent.atomic.AtomicInteger;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.opendaylight.controller.sal.connect.netconf.listener.NetconfDeviceCommunicator;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.slf4j.Logger;
@@ -33,7 +33,7 @@ import org.opendaylight.controller.netconf.api.NetconfMessage;
 import org.opendaylight.controller.netconf.client.NetconfClientDispatcherImpl;
 import org.opendaylight.controller.netconf.nettyutil.handler.ssh.client.AsyncSshHandler;
 import org.opendaylight.controller.netconf.test.tool.TestToolUtils;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.sal.connect.api.RemoteDevice;
 import org.opendaylight.controller.sal.connect.netconf.listener.NetconfDeviceCommunicator;
 import org.opendaylight.controller.sal.connect.netconf.listener.NetconfSessionPreferences;
@@ -16,8 +16,8 @@ import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 import java.util.concurrent.atomic.AtomicInteger;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.opendaylight.controller.sal.connect.netconf.listener.NetconfDeviceCommunicator;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.slf4j.Logger;
@@ -9,11 +9,11 @@
 package org.opendaylight.controller.netconf.test.tool.rpc;
 
 import com.google.common.base.Optional;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.config.util.xml.XmlElement;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.AbstractConfigNetconfOperation;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
@@ -24,7 +24,7 @@ public class SimulatedCommit extends AbstractConfigNetconfOperation {
     }
 
     @Override
-    protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement operationElement) throws NetconfDocumentedException {
+    protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement operationElement) throws DocumentedException {
         return XmlUtil.createElement(document, XmlNetconfConstants.OK, Optional.<String>absent());
     }
 
@@ -25,14 +25,14 @@ import javax.xml.bind.JAXBContext;
 import javax.xml.bind.JAXBException;
 import javax.xml.bind.Unmarshaller;
 import javax.xml.bind.annotation.XmlRootElement;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.config.util.xml.XmlElement;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.netconf.api.NetconfMessage;
 import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
 import org.opendaylight.controller.netconf.impl.NetconfServerSession;
 import org.opendaylight.controller.netconf.impl.mapping.operations.DefaultNetconfOperation;
 import org.opendaylight.controller.netconf.util.mapping.AbstractLastNetconfOperation;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.xml.sax.SAXException;
@@ -89,7 +89,7 @@ public class SimulatedCreateSubscription extends AbstractLastNetconfOperation im
     }
 
     @Override
-    protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement operationElement) throws NetconfDocumentedException {
+    protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement operationElement) throws DocumentedException {
         long delayAggregator = 0;
 
         for (final Map.Entry<Notification, NetconfMessage> notification : notifications.entrySet()) {
@@ -9,12 +9,12 @@
 package org.opendaylight.controller.netconf.test.tool.rpc;
 
 import com.google.common.base.Optional;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.config.util.xml.XmlElement;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.AbstractConfigNetconfOperation;
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfigXmlParser;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.w3c.dom.Attr;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
@@ -31,7 +31,7 @@ public class SimulatedEditConfig extends AbstractConfigNetconfOperation {
     }
 
     @Override
-    protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement operationElement) throws NetconfDocumentedException {
+    protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement operationElement) throws DocumentedException {
         final XmlElement configElementData = operationElement.getOnlyChildElement(XmlNetconfConstants.CONFIG_KEY);
 
         containsDelete(configElementData);
@@ -9,11 +9,11 @@
 package org.opendaylight.controller.netconf.test.tool.rpc;
 
 import com.google.common.base.Optional;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.config.util.xml.XmlElement;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.AbstractConfigNetconfOperation;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
@@ -27,7 +27,7 @@ public class SimulatedGet extends AbstractConfigNetconfOperation {
     }
 
     @Override
-    protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement operationElement) throws NetconfDocumentedException {
+    protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement operationElement) throws DocumentedException {
         final Element element = XmlUtil.createElement(document, XmlNetconfConstants.DATA_KEY, Optional.<String>absent());
 
         for(final XmlElement e : storage.getConfigList()) {
@@ -9,11 +9,11 @@
 package org.opendaylight.controller.netconf.test.tool.rpc;
 
 import com.google.common.base.Optional;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.config.util.xml.XmlElement;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.AbstractConfigNetconfOperation;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
@@ -27,7 +27,7 @@ public class SimulatedGetConfig extends AbstractConfigNetconfOperation {
     }
 
     @Override
-    protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement operationElement) throws NetconfDocumentedException {
+    protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement operationElement) throws DocumentedException {
         final Element element = XmlUtil.createElement(document, XmlNetconfConstants.DATA_KEY, Optional.<String>absent());
 
         for(final XmlElement e : storage.getConfigList()) {
@@ -9,11 +9,11 @@
 package org.opendaylight.controller.netconf.test.tool.rpc;
 
 import com.google.common.base.Optional;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.config.util.xml.XmlElement;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.AbstractConfigNetconfOperation;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
@@ -24,7 +24,7 @@ public class SimulatedLock extends AbstractConfigNetconfOperation {
     }
 
     @Override
-    protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement operationElement) throws NetconfDocumentedException {
+    protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement operationElement) throws DocumentedException {
         return XmlUtil.createElement(document, XmlNetconfConstants.OK, Optional.<String>absent());
     }
 
@@ -9,11 +9,11 @@
 package org.opendaylight.controller.netconf.test.tool.rpc;
 
 import com.google.common.base.Optional;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.config.util.xml.DocumentedException;
+import org.opendaylight.controller.config.util.xml.XmlElement;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.AbstractConfigNetconfOperation;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
@@ -24,7 +24,7 @@ public class SimulatedUnLock extends AbstractConfigNetconfOperation {
     }
 
     @Override
-    protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement operationElement) throws NetconfDocumentedException {
+    protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement operationElement) throws DocumentedException {
         return XmlUtil.createElement(document, XmlNetconfConstants.OK, Optional.<String>absent());
     }
 
diff --git a/opendaylight/netconf/tools/pom.xml b/opendaylight/netconf/tools/pom.xml
new file mode 100644 (file)
index 0000000..a8bdd24
--- /dev/null
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.opendaylight.controller</groupId>
+    <artifactId>netconf-subsystem</artifactId>
+    <version>0.4.0-SNAPSHOT</version>
+    <relativePath>../</relativePath>
+  </parent>
+  <artifactId>netconf-tools</artifactId>
+
+  <version>0.4.0-SNAPSHOT</version>
+  <packaging>pom</packaging>
+  <name>${project.artifactId}</name>
+
+  <modules>
+    <module>netconf-cli</module>
+    <module>netconf-testtool</module>
+  </modules>
+
+  <build>
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <groupId>org.apache.felix</groupId>
+          <artifactId>maven-bundle-plugin</artifactId>
+          <extensions>true</extensions>
+          <configuration>
+            <instructions>
+              <Bundle-Name>${project.groupId}.${project.artifactId}</Bundle-Name>
+            </instructions>
+          </configuration>
+        </plugin>
+        <plugin>
+          <groupId>org.opendaylight.yangtools</groupId>
+          <artifactId>yang-maven-plugin</artifactId>
+          <version>${yangtools.version}</version>
+          <dependencies>
+            <dependency>
+              <groupId>org.opendaylight.yangtools</groupId>
+              <artifactId>maven-sal-api-gen-plugin</artifactId>
+              <version>${yangtools.version}</version>
+            </dependency>
+          </dependencies>
+          <executions>
+            <execution>
+              <goals>
+                <goal>generate-sources</goal>
+              </goals>
+              <configuration>
+                <yangFilesRootDir>src/main/yang</yangFilesRootDir>
+                <codeGenerators>
+                  <generator>
+                    <codeGeneratorClass>org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl</codeGeneratorClass>
+                    <outputBaseDir>${salGeneratorPath}</outputBaseDir>
+                  </generator>
+                  <generator>
+                    <codeGeneratorClass>org.opendaylight.yangtools.yang.unified.doc.generator.maven.DocumentationGeneratorImpl</codeGeneratorClass>
+                    <outputBaseDir>${project.build.directory}/site/models</outputBaseDir>
+                  </generator>
+                </codeGenerators>
+                <inspectDependencies>true</inspectDependencies>
+              </configuration>
+            </execution>
+          </executions>
+        </plugin>
+      </plugins>
+
+    </pluginManagement>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-checkstyle-plugin</artifactId>
+        <configuration>
+          <failsOnError>false</failsOnError>
+          <failOnViolation>true</failOnViolation>
+          <configLocation>checkstyle-logging.xml</configLocation>
+          <consoleOutput>true</consoleOutput>
+          <includeTestSourceDirectory>true</includeTestSourceDirectory>
+          <sourceDirectory>${project.basedir}</sourceDirectory>
+          <includes>**\/*.java,**\/*.xml,**\/*.ini,**\/*.sh,**\/*.bat,**\/*.yang</includes>
+          <excludes>**\/target\/,**\/bin\/,**\/target-ide\/,**\/${jmxGeneratorPath}\/,**\/${salGeneratorPath}\/,**\/netconf\/test\/tool\/Main.java, **\/netconf\/test\/tool\/client\/stress\/StressClient.java</excludes>
+        </configuration>
+        <dependencies>
+          <dependency>
+            <groupId>org.opendaylight.yangtools</groupId>
+            <artifactId>checkstyle-logging</artifactId>
+            <version>${yangtools.version}</version>
+          </dependency>
+        </dependencies>
+        <executions>
+          <execution>
+            <goals>
+              <goal>check</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+      </plugin>
+    </plugins>
+  </build>
+</project>