From 0b54f2e1cd2dd3a666ee2881ef2e8f4efd5e1bd4 Mon Sep 17 00:00:00 2001 From: Tomas Cere Date: Thu, 13 Aug 2015 11:06:54 +0200 Subject: [PATCH] Decouple config and netconf subsystems. 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 Signed-off-by: Maros Marsalek Signed-off-by: Ed Warnicke --- .../netconf/config-netconf-connector/pom.xml | 26 +- .../NetconfConfigHandlingException.java | 26 - .../NoTransactionFoundException.java | 27 - .../OperationNotPermittedException.java | 26 - .../AttributeIfcSwitchStatement.java | 121 ---- .../AbstractAttributeReadingStrategy.java | 40 -- .../ArrayAttributeReadingStrategy.java | 46 -- .../fromxml/AttributeConfigElement.java | 88 --- .../fromxml/AttributeReadingStrategy.java | 19 - .../CompositeAttributeReadingStrategy.java | 67 --- .../ObjectNameAttributeReadingStrategy.java | 66 --- .../attributes/fromxml/ObjectXmlReader.java | 126 ---- .../SimpleAttributeReadingStrategy.java | 45 -- .../SimpleBinaryAttributeReadingStrategy.java | 36 -- ...mpleCompositeAttributeReadingStrategy.java | 34 -- ...leIdentityRefAttributeReadingStrategy.java | 79 --- .../SimpleUnionAttributeReadingStrategy.java | 43 -- .../AbstractAttributeMappingStrategy.java | 27 - .../ArrayAttributeMappingStrategy.java | 51 -- .../mapping/AttributeMappingStrategy.java | 20 - .../CompositeAttributeMappingStrategy.java | 73 --- .../mapping/EnumAttributeMappingStrategy.java | 34 -- .../attributes/mapping/ObjectMapper.java | 147 ----- .../ObjectNameAttributeMappingStrategy.java | 82 --- .../SimpleAttributeMappingStrategy.java | 72 --- ...nionCompositeAttributeMappingStrategy.java | 33 -- .../AbstractAttributeResolvingStrategy.java | 31 - .../ArrayAttributeResolvingStrategy.java | 117 ---- .../resolving/AttributeResolvingStrategy.java | 22 - .../CompositeAttributeResolvingStrategy.java | 115 ---- .../EnumAttributeResolvingStrategy.java | 55 -- .../ObjectNameAttributeResolvingStrategy.java | 50 -- .../attributes/resolving/ObjectResolver.java | 144 ----- .../SimpleAttributeResolvingStrategy.java | 154 ----- ...onCompositeAttributeResolvingStrategy.java | 44 -- .../toxml/ArrayAttributeWritingStrategy.java | 33 -- .../toxml/AttributeWritingStrategy.java | 17 - .../CompositeAttributeWritingStrategy.java | 62 -- .../ObjectNameAttributeWritingStrategy.java | 53 -- .../attributes/toxml/ObjectXmlWriter.java | 127 ---- .../RuntimeBeanEntryWritingStrategy.java | 65 --- .../toxml/SimpleAttributeWritingStrategy.java | 50 -- .../SimpleBinaryAttributeWritingStrategy.java | 44 -- ...mpleCompositeAttributeWritingStrategy.java | 32 -- ...leIdentityRefAttributeWritingStrategy.java | 48 -- .../SimpleUnionAttributeWritingStrategy.java | 42 -- .../mapping/config/Config.java | 294 ---------- .../mapping/config/InstanceConfig.java | 238 -------- .../config/InstanceConfigElementResolved.java | 54 -- .../mapping/config/ModuleConfig.java | 63 -- .../config/ModuleElementDefinition.java | 62 -- .../mapping/config/ModuleElementResolved.java | 29 - .../config/ServiceRegistryWrapper.java | 99 ---- .../mapping/config/Services.java | 291 ---------- .../mapping/rpc/InstanceRuntimeRpc.java | 98 ---- .../mapping/rpc/ModuleRpcs.java | 64 --- .../mapping/rpc/Rpcs.java | 33 -- .../mapping/runtime/InstanceRuntime.java | 120 ---- .../mapping/runtime/ModuleRuntime.java | 53 -- .../mapping/runtime/Runtime.java | 101 ---- .../AbstractConfigNetconfOperation.java | 12 +- .../operations/Commit.java | 26 +- .../operations/Datastore.java | 36 -- .../operations/DiscardChanges.java | 34 +- .../operations/Lock.java | 27 +- .../operations/UnLock.java | 13 +- .../operations/Validate.java | 38 +- .../AbstractEditConfigStrategy.java | 48 -- .../editconfig/DeleteEditConfigStrategy.java | 49 -- .../operations/editconfig/EditConfig.java | 284 +-------- .../editconfig/EditConfigStrategy.java | 22 - .../editconfig/EditConfigXmlParser.java | 129 +---- .../editconfig/EditStrategyType.java | 75 --- .../editconfig/MergeEditConfigStrategy.java | 119 ---- .../MissingInstanceHandlingStrategy.java | 44 -- .../editconfig/NoneEditConfigStrategy.java | 43 -- .../editconfig/RemoveEditConfigStrategy.java | 27 - .../editconfig/ReplaceEditConfigStrategy.java | 62 -- .../operations/get/Get.java | 120 +--- .../CandidateDatastoreQueryStrategy.java | 32 -- .../getconfig/DatastoreQueryStrategy.java | 23 - .../operations/getconfig/GetConfig.java | 73 +-- .../RunningDatastoreQueryStrategy.java | 32 -- .../operations/runtimerpc/RuntimeRpc.java | 212 +------ .../runtimerpc/RuntimeRpcElementResolved.java | 185 ------ .../osgi/Activator.java | 77 +-- .../osgi/EnumResolver.java | 16 - .../osgi/NetconfOperationProvider.java | 28 +- .../NetconfOperationServiceFactoryImpl.java | 96 +--- .../osgi/NetconfOperationServiceImpl.java | 18 +- .../osgi/YangStoreContext.java | 40 -- .../osgi/YangStoreService.java | 279 --------- .../osgi/YangStoreSnapshot.java | 179 ------ .../transactions/TransactionProvider.java | 234 -------- .../confignetconfconnector/util/Util.java | 32 -- .../NetconfMappingTest.java | 110 ++-- .../ServiceTrackerTest.java | 4 +- ...entityRefAttributeReadingStrategyTest.java | 42 -- .../operations/ValidateTest.java | 46 +- .../operations/editconfig/EditConfigTest.java | 44 +- .../MergeEditConfigStrategyTest.java | 5 +- .../ReplaceEditConfigStrategyTest.java | 3 +- .../RuntimeRpcElementResolvedTest.java | 71 --- .../netconf/config-persister-impl/pom.xml | 86 --- ...pabilityStrippingConfigSnapshotHolder.java | 103 ---- .../ConfigPersisterNotificationHandler.java | 114 ---- .../persist/impl/ConfigPusherImpl.java | 410 ------------- .../persist/impl/NoOpStorageAdapter.java | 45 -- .../persist/impl/PersisterAggregator.java | 212 ------- .../impl/PropertiesProviderAdapterImpl.java | 41 -- .../impl/osgi/ConfigPersisterActivator.java | 215 ------- .../impl/osgi/PropertiesProviderBaseImpl.java | 43 -- .../main/resources/netconfOp/client_hello.xml | 5 - .../src/main/resources/netconfOp/commit.xml | 3 - .../main/resources/netconfOp/editConfig.xml | 12 - ...lityStrippingConfigSnapshotHolderTest.java | 46 -- ...onfigPersisterNotificationHandlerTest.java | 65 --- ...nfigPersisterNotificationListenerTest.java | 81 --- .../netconf/persist/impl/DummyAdapter.java | 47 -- .../persist/impl/PersisterAggregatorTest.java | 172 ------ .../impl/osgi/ConfigPersisterTest.java | 149 ----- .../impl/osgi/MockedBundleContext.java | 153 ----- .../impl/osgi/TestingExceptionHandler.java | 75 --- .../src/test/resources/capabilities-all.txt | 20 - .../test/resources/capabilities-stripped.txt | 5 - .../src/test/resources/logback-test.xml | 13 - .../src/test/resources/snapshot.xml | 103 ---- .../src/test/resources/test1.properties | 3 - .../src/test/resources/test2.properties | 9 - .../src/test/resources/test3.properties | 4 - .../features/netconf-connector/pom.xml | 180 ++++++ .../src/main/resources/features.xml | 36 ++ opendaylight/netconf/features/netconf/pom.xml | 267 +++++++++ .../netconf/src/main/resources/features.xml | 145 +++++ opendaylight/netconf/features/pom.xml | 17 + .../netconf/mdsal-netconf-connector/pom.xml | 32 -- .../mdsal/connector/CurrentSchemaContext.java | 16 +- .../MdsalNetconfOperationServiceFactory.java | 10 +- .../mdsal/connector/TransactionProvider.java | 18 +- .../netconf/mdsal/connector/ops/Commit.java | 8 +- .../mdsal/connector/ops/DiscardChanges.java | 16 +- .../mdsal/connector/ops/EditConfig.java | 42 +- .../netconf/mdsal/connector/ops/Lock.java | 14 +- .../mdsal/connector/ops/RuntimeRpc.java | 32 +- .../netconf/mdsal/connector/ops/Unlock.java | 12 +- .../mdsal/connector/ops/get/AbstractGet.java | 40 +- .../netconf/mdsal/connector/ops/get/Get.java | 18 +- .../mdsal/connector/ops/get/GetConfig.java | 20 +- .../ops/NetconfMDSalMappingTest.java | 68 +-- .../mdsal/connector/ops/RuntimeRpcTest.java | 14 +- .../netconf/mdsal-netconf-monitoring/pom.xml | 31 - .../NetconfMdsalMonitoringMapperModule.java | 2 +- ...confMonitoringOperationServiceFactory.java | 2 +- .../ietf-netconf-monitoring-extension/pom.xml | 2 +- .../ietf-netconf-monitoring-extension.yang | 0 .../ietf-netconf-monitoring/pom.xml | 2 +- .../state/schemas/LocationBuilder.java | 0 .../state/schemas/SchemaLocationBuilder.java | 0 .../main/yang/ietf-netconf-monitoring.yang | 0 .../ietf-netconf-notifications/pom.xml | 2 +- ...ietf-netconf-notifications@2012-02-06.yang | 0 .../yang/nc-notifications@2008-07-14.yang | 0 .../main/yang/notifications@2008-07-14.yang | 0 .../netconf/{ => models}/ietf-netconf/pom.xml | 2 +- .../main/yang/ietf-netconf@2011-06-01.yang | 0 opendaylight/netconf/models/pom.xml | 78 +++ opendaylight/netconf/netconf-api/pom.xml | 35 +- .../controller/netconf/api/Capability.java | 31 - .../api/NetconfDocumentedException.java | 310 +--------- .../api/jmx/CommitJMXNotification.java | 51 -- .../api/jmx/DefaultCommitOperationMXBean.java | 19 - .../api/jmx/NetconfJMXNotification.java | 62 -- .../api/monitoring/CapabilityListener.java | 5 +- .../netconf/api/util/NetconfConstants.java | 4 + .../netconf/api/xml/XmlNetconfConstants.java | 38 +- .../api/NetconfDocumentedExceptionTest.java | 26 +- .../netconf/netconf-artifacts/pom.xml | 29 + .../NetconfClientSessionNegotiator.java | 2 +- .../netconf/netconf-config-dispatcher/pom.xml | 75 +++ .../NetconfClientDispatcherModule.java | 35 ++ .../NetconfClientDispatcherModuleFactory.java | 17 + .../src/main/yang/odl-netconf-cfg.yang | 31 + .../main/yang/odl-netconfig-client-cfg.yang | 64 +++ .../NetconfClientDispatcherModuleTest.java | 102 ++++ opendaylight/netconf/netconf-impl/pom.xml | 43 +- .../impl/NetconfServerDispatcherModule.java | 3 +- .../netconf/impl/CommitNotifier.java | 32 -- .../DefaultCommitNotificationProducer.java | 64 --- .../impl/NetconfServerSessionListener.java | 24 +- ...NetconfServerSessionNegotiatorFactory.java | 24 +- .../netconf/impl/SubtreeFilter.java | 22 +- .../operations/DefaultCloseSession.java | 18 +- .../mapping/operations/DefaultCommit.java | 146 ----- .../mapping/operations/DefaultStartExi.java | 19 +- .../mapping/operations/DefaultStopExi.java | 8 +- ...regatedNetconfOperationServiceFactory.java | 8 +- .../impl/osgi/NetconfImplActivator.java | 84 ++- .../osgi/NetconfMonitoringServiceImpl.java | 67 ++- .../impl/osgi/NetconfOperationRouter.java | 4 +- .../impl/osgi/NetconfOperationRouterImpl.java | 53 +- .../util/DeserializerExceptionHandler.java | 8 +- .../netconf/impl/ConcurrentClientsTest.java | 20 +- .../impl/NetconfDispatcherImplTest.java | 7 +- .../netconf/impl/SubtreeFilterTest.java | 2 +- .../operations/DefaultCloseSessionTest.java | 8 +- .../mapping/operations/DefaultCommitTest.java | 86 --- .../operations/DefaultStopExiTest.java | 4 +- opendaylight/netconf/netconf-it/pom.xml | 4 - .../netconf/it/AbstractNetconfConfigTest.java | 45 +- .../it/NetconfConfigPersisterITTest.java | 71 ++- .../netconf/it/NetconfITMonitoringTest.java | 5 +- .../netconf/it/NetconfITSecureTest.java | 2 +- .../controller/netconf/it/NetconfITTest.java | 12 +- .../controller/netconf/it/SSLUtil.java | 57 -- .../netconf/netconf-mapping-api/pom.xml | 36 +- .../netconf/mapping/api/NetconfOperation.java | 8 +- .../api/NetconfOperationChainedExecution.java | 6 +- .../api/NetconfOperationServiceFactory.java | 2 +- .../mapping/api/HandlingPriorityTest.java | 24 +- .../controller/netconf/monitoring/Get.java | 29 +- .../netconf/monitoring/GetSchema.java | 23 +- .../osgi/NetconfMonitoringActivator.java | 2 +- .../netconf/monitoring/GetSchemaTest.java | 8 +- .../netconf/monitoring/GetTest.java | 19 +- .../monitoring/xml/JaxBSerializerTest.java | 15 +- .../netconf/netconf-netty-util/pom.xml | 11 +- .../nettyutil/AbstractNetconfSession.java | 2 +- .../NetconfXMLToHelloMessageDecoder.java | 2 +- .../handler/NetconfXMLToMessageDecoder.java | 2 +- .../nettyutil/handler/exi/EXIParameters.java | 2 +- .../handler/exi/NetconfStartExiMessage.java | 2 +- .../handler/NetconfEXIHandlersTest.java | 3 +- .../NetconfHelloMessageToXMLEncoderTest.java | 2 +- .../NetconfXMLToHelloMessageDecoderTest.java | 2 +- .../handler/exi/EXIParametersTest.java | 4 +- .../netconf/netconf-notifications-api/pom.xml | 9 +- .../BaseNetconfNotificationListener.java | 2 +- .../NetconfNotificationCollector.java | 2 +- .../netconf-notifications-impl/pom.xml | 1 + .../impl/NetconfNotificationManager.java | 18 +- .../impl/ops/CreateSubscription.java | 10 +- .../netconf/notifications/impl/ops/Get.java | 15 +- .../impl/ops/NotificationsTransformUtil.java | 2 +- .../notifications/impl/osgi/Activator.java | 14 +- .../impl/ops/CreateSubscriptionTest.java | 4 +- .../notifications/impl/ops/GetTest.java | 2 +- .../ops/NotificationsTransformUtilTest.java | 2 +- opendaylight/netconf/netconf-ssh/pom.xml | 31 - opendaylight/netconf/netconf-tcp/pom.xml | 31 - opendaylight/netconf/netconf-util/pom.xml | 9 +- .../controller/netconf/util/NetconfUtil.java | 11 +- .../util/capability/BasicCapability.java | 61 -- .../util/capability/YangModuleCapability.java | 57 -- .../exception/MissingNameSpaceException.java | 26 - .../exception/UnexpectedElementException.java | 26 - .../UnexpectedNamespaceException.java | 26 - .../mapping/AbstractLastNetconfOperation.java | 16 +- .../mapping/AbstractNetconfOperation.java | 19 +- .../AbstractSingletonNetconfOperation.java | 6 +- .../util/messages/NetconfHelloMessage.java | 8 +- .../util/messages/NetconfMessageUtil.java | 17 +- .../util/messages/SendErrorExceptionUtil.java | 23 +- .../netconf/util/xml/XmlElement.java | 540 ------------------ .../netconf/util/xml/XmlNetconfValidator.java | 1 + .../controller/netconf/util/xml/XmlUtil.java | 222 ------- .../netconf/util/NetconfUtilTest.java | 2 +- .../AbstractLastNetconfOperationTest.java | 8 +- .../mapping/AbstractNetconfOperationTest.java | 8 +- ...AbstractSingletonNetconfOperationTest.java | 6 +- .../messages/SendErrorExceptionUtilTest.java | 6 +- .../netconf/util/test/XmlFileLoader.java | 2 +- .../netconf/util/test/XmlUnitUtil.java | 2 +- .../netconf/util/xml/XMLNetconfUtilTest.java | 25 + .../netconf/util/xml/XmlElementTest.java | 143 ----- .../netconf/util/xml/XmlUtilTest.java | 86 --- opendaylight/netconf/pom.xml | 40 +- .../netconf/sal-netconf-connector/pom.xml | 189 ++++++ .../netconf/NetconfConnectorModule.java | 273 +++++++++ .../NetconfConnectorModuleFactory.java | 61 ++ .../sal/connect/api/MessageTransformer.java | 23 + .../sal/connect/api/RemoteDevice.java | 22 + .../connect/api/RemoteDeviceCommunicator.java | 19 + .../sal/connect/api/RemoteDeviceHandler.java | 26 + .../api/SchemaContextProviderFactory.java | 20 + .../sal/connect/api/package-info.java | 14 + .../sal/connect/netconf/NetconfDevice.java | 507 ++++++++++++++++ .../connect/netconf/NetconfStateSchemas.java | 277 +++++++++ .../connect/netconf/NotificationHandler.java | 106 ++++ .../listener/NetconfDeviceCapabilities.java | 61 ++ .../listener/NetconfDeviceCommunicator.java | 357 ++++++++++++ .../listener/NetconfSessionPreferences.java | 205 +++++++ .../netconf/listener/UncancellableFuture.java | 52 ++ .../sal/connect/netconf/package-info.java | 12 + .../netconf/sal/KeepaliveSalFacade.java | 245 ++++++++ .../netconf/sal/NetconfDeviceDataBroker.java | 93 +++ .../sal/NetconfDeviceNotificationService.java | 61 ++ .../connect/netconf/sal/NetconfDeviceRpc.java | 105 ++++ .../netconf/sal/NetconfDeviceSalFacade.java | 96 ++++ .../netconf/sal/NetconfDeviceSalProvider.java | 153 +++++ .../sal/NetconfDeviceTopologyAdapter.java | 262 +++++++++ .../netconf/sal/tx/AbstractWriteTx.java | 177 ++++++ .../connect/netconf/sal/tx/ReadOnlyTx.java | 150 +++++ .../connect/netconf/sal/tx/ReadWriteTx.java | 90 +++ .../sal/tx/WriteCandidateRunningTx.java | 69 +++ .../netconf/sal/tx/WriteCandidateTx.java | 205 +++++++ .../netconf/sal/tx/WriteRunningTx.java | 145 +++++ ...NetconfRemoteSchemaYangSourceProvider.java | 209 +++++++ .../mapping/NetconfMessageTransformer.java | 331 +++++++++++ .../connect/netconf/util/NetconfBaseOps.java | 287 ++++++++++ .../util/NetconfMessageTransformUtil.java | 338 +++++++++++ .../util/NetconfRpcFutureCallback.java | 48 ++ .../netconf/util/NodeContainerProxy.java | 152 +++++ .../sal/connect/util/MessageCounter.java | 28 + .../sal/connect/util/RemoteDeviceId.java | 163 ++++++ .../sal/connect/util/package-info.java | 14 + .../src/main/yang/netconf-node-topology.yang | 75 +++ .../yang/odl-sal-netconf-connector-cfg.yang | 174 ++++++ .../connect/netconf/NetconfDeviceTest.java | 313 ++++++++++ .../netconf/NetconfStateSchemasTest.java | 48 ++ .../netconf/NetconfToNotificationTest.java | 80 +++ .../netconf/NetconfToRpcRequestTest.java | 116 ++++ .../NetconfDeviceCommunicatorTest.java | 479 ++++++++++++++++ .../NetconfSessionPreferencesTest.java | 71 +++ .../netconf/sal/KeepaliveSalFacadeTest.java | 159 ++++++ .../sal/NetconfDeviceTopologyAdapterTest.java | 81 +++ .../sal/tx/NetconfDeviceWriteOnlyTxTest.java | 147 +++++ .../netconf/sal/tx/ReadOnlyTxTest.java | 63 ++ .../NetconfMessageTransformerTest.java | 309 ++++++++++ .../netconf-state.schemas.payload.xml | 514 +++++++++++++++++ .../test/resources/notification-payload.xml | 14 + .../resources/schemas/config-test-rpc.yang | 176 ++++++ .../rpc-notification-subscription.yang | 38 ++ .../test/resources/schemas/test-module.yang | 18 + .../resources/schemas/user-notification.yang | 56 ++ .../{ => tools}/netconf-cli/.gitignore | 0 .../netconf/{ => tools}/netconf-cli/README | 0 .../{ => tools}/netconf-cli/README_ODL | 0 .../netconf/{ => tools}/netconf-cli/pom.xml | 2 +- .../controller/netconf/cli/Cli.java | 0 .../cli/CommandArgHandlerRegistry.java | 0 .../controller/netconf/cli/Main.java | 0 .../cli/NetconfDeviceConnectionHandler.java | 0 .../cli/NetconfDeviceConnectionManager.java | 0 .../netconf/cli/SchemaContextRegistry.java | 0 .../netconf/cli/commands/AbstractCommand.java | 0 .../netconf/cli/commands/Command.java | 0 .../cli/commands/CommandConstants.java | 0 .../cli/commands/CommandDispatcher.java | 0 .../commands/CommandInvocationException.java | 0 .../netconf/cli/commands/input/Input.java | 0 .../cli/commands/input/InputDefinition.java | 0 .../netconf/cli/commands/local/Close.java | 0 .../netconf/cli/commands/local/Connect.java | 0 .../cli/commands/local/Disconnect.java | 0 .../netconf/cli/commands/local/Help.java | 0 .../netconf/cli/commands/output/Output.java | 0 .../cli/commands/output/OutputDefinition.java | 0 .../cli/commands/remote/RemoteCommand.java | 0 .../netconf/cli/io/BaseConsoleContext.java | 0 .../netconf/cli/io/ConsoleContext.java | 0 .../controller/netconf/cli/io/ConsoleIO.java | 0 .../netconf/cli/io/ConsoleIOImpl.java | 0 .../controller/netconf/cli/io/IOUtil.java | 0 .../netconf/cli/reader/AbstractReader.java | 0 .../cli/reader/GenericListEntryReader.java | 0 .../controller/netconf/cli/reader/Reader.java | 0 .../netconf/cli/reader/ReadingException.java | 0 .../cli/reader/custom/ConfigReader.java | 0 .../cli/reader/custom/EditContentReader.java | 0 .../cli/reader/custom/FilterReader.java | 0 .../cli/reader/custom/PasswordReader.java | 0 .../netconf/cli/reader/impl/AnyXmlReader.java | 2 +- .../reader/impl/BasicDataHolderReader.java | 0 .../netconf/cli/reader/impl/ChoiceReader.java | 0 .../cli/reader/impl/ContainerReader.java | 0 .../cli/reader/impl/DecisionReader.java | 0 .../cli/reader/impl/GenericListReader.java | 0 .../cli/reader/impl/GenericReader.java | 0 .../cli/reader/impl/LeafListEntryReader.java | 0 .../netconf/cli/reader/impl/LeafReader.java | 0 .../cli/reader/impl/ListEntryReader.java | 0 .../cli/reader/impl/SeparatedNodes.java | 0 .../cli/reader/impl/UnionTypeReader.java | 0 .../netconf/cli/writer/OutFormatter.java | 0 .../netconf/cli/writer/WriteException.java | 0 .../controller/netconf/cli/writer/Writer.java | 0 .../netconf/cli/writer/custom/DataWriter.java | 0 .../cli/writer/impl/AbstractWriter.java | 0 .../impl/AugmentationNodeCliSerializer.java | 0 .../writer/impl/ChoiceNodeCliSerializer.java | 0 ...utFromNormalizedNodeSerializerFactory.java | 0 .../impl/ContainerNodeCliSerializer.java | 0 .../writer/impl/LeafNodeCliSerializer.java | 0 .../impl/LeafSetEntryNodeCliSerializer.java | 0 .../writer/impl/LeafSetNodeCliSerializer.java | 0 .../impl/MapEntryNodeCliSerializer.java | 0 .../cli/writer/impl/MapNodeCliSerializer.java | 0 .../impl/NodeCliSerializerDispatcher.java | 0 .../cli/writer/impl/NormalizedNodeWriter.java | 0 .../src/main/resources/logback.xml | 0 .../schema/common/ietf-inet-types.yang | 0 .../schema/common/netconf-cli-ext.yang | 0 .../resources/schema/local/netconf-cli.yang | 0 .../resources/schema/remote/ietf-netconf.yang | 0 .../netconf/cli/ConsoleIOTestImpl.java | 0 .../netconf/cli/NetconfCliTest.java | 0 .../netconf/cli/ValueForMessages.java | 0 .../controller/netconf/cli/io/IOUtilTest.java | 0 .../schema-context/ietf-inet-types.yang | 0 .../schema-context/ietf-netconf.yang | 0 .../test/resources/schema-context/model1.yang | 0 .../test/resources/schema-context/model2.yang | 0 .../{ => tools}/netconf-testtool/edit.txt | 0 .../{ => tools}/netconf-testtool/pom.xml | 2 +- .../src/main/assembly/stress-client.xml | 0 .../test/tool/AcceptingAuthProvider.java | 0 .../test/tool/DummyMonitoringService.java | 13 +- .../tool/FakeModuleBuilderCapability.java | 0 .../controller/netconf/test/tool/Main.java | 4 +- .../test/tool/ModuleBuilderCapability.java | 4 +- .../test/tool/NetconfDeviceSimulator.java | 11 +- .../netconf/test/tool/TestToolUtils.java | 0 .../http/perf/AsyncExecutionStrategy.java | 0 .../tool/client/http/perf/Parameters.java | 0 .../client/http/perf/PerfClientCallable.java | 0 .../tool/client/http/perf/RestPerfClient.java | 0 .../http/perf/SyncExecutionStrategy.java | 0 .../client/stress/AsyncExecutionStrategy.java | 2 +- .../stress/ConfigurableClientDispatcher.java | 0 .../tool/client/stress/ExecutionStrategy.java | 0 .../test/tool/client/stress/Parameters.java | 0 .../test/tool/client/stress/StressClient.java | 2 +- .../client/stress/StressClientCallable.java | 0 .../client/stress/SyncExecutionStrategy.java | 2 +- .../netconf/test/tool/rpc/DataList.java | 2 +- .../test/tool/rpc/SimulatedCommit.java | 8 +- .../tool/rpc/SimulatedCreateSubscription.java | 8 +- .../test/tool/rpc/SimulatedEditConfig.java | 8 +- .../netconf/test/tool/rpc/SimulatedGet.java | 8 +- .../test/tool/rpc/SimulatedGetConfig.java | 8 +- .../netconf/test/tool/rpc/SimulatedLock.java | 8 +- .../test/tool/rpc/SimulatedUnLock.java | 8 +- .../99-netconf-connector-simulated.xml | 0 .../src/main/resources/logback.xml | 0 .../main/resources/org.ops4j.pax.url.mvn.cfg | 0 opendaylight/netconf/tools/pom.xml | 106 ++++ 446 files changed, 10903 insertions(+), 12317 deletions(-) delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/exception/NetconfConfigHandlingException.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/exception/NoTransactionFoundException.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/exception/OperationNotPermittedException.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/AttributeIfcSwitchStatement.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/AbstractAttributeReadingStrategy.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ArrayAttributeReadingStrategy.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/AttributeConfigElement.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/AttributeReadingStrategy.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/CompositeAttributeReadingStrategy.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ObjectNameAttributeReadingStrategy.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ObjectXmlReader.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleAttributeReadingStrategy.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleBinaryAttributeReadingStrategy.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleCompositeAttributeReadingStrategy.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleIdentityRefAttributeReadingStrategy.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleUnionAttributeReadingStrategy.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/AbstractAttributeMappingStrategy.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ArrayAttributeMappingStrategy.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/AttributeMappingStrategy.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/CompositeAttributeMappingStrategy.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/EnumAttributeMappingStrategy.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectMapper.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectNameAttributeMappingStrategy.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/SimpleAttributeMappingStrategy.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/UnionCompositeAttributeMappingStrategy.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/AbstractAttributeResolvingStrategy.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ArrayAttributeResolvingStrategy.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/AttributeResolvingStrategy.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/CompositeAttributeResolvingStrategy.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/EnumAttributeResolvingStrategy.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectNameAttributeResolvingStrategy.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectResolver.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/SimpleAttributeResolvingStrategy.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/UnionCompositeAttributeResolvingStrategy.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/ArrayAttributeWritingStrategy.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/AttributeWritingStrategy.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/CompositeAttributeWritingStrategy.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/ObjectNameAttributeWritingStrategy.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/ObjectXmlWriter.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/RuntimeBeanEntryWritingStrategy.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleAttributeWritingStrategy.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleBinaryAttributeWritingStrategy.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleCompositeAttributeWritingStrategy.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleIdentityRefAttributeWritingStrategy.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleUnionAttributeWritingStrategy.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Config.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfig.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfigElementResolved.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleConfig.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleElementDefinition.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleElementResolved.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ServiceRegistryWrapper.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Services.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/rpc/InstanceRuntimeRpc.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/rpc/ModuleRpcs.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/rpc/Rpcs.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/InstanceRuntime.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/ModuleRuntime.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/Runtime.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/Datastore.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/AbstractEditConfigStrategy.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/DeleteEditConfigStrategy.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigStrategy.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditStrategyType.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MergeEditConfigStrategy.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MissingInstanceHandlingStrategy.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/NoneEditConfigStrategy.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/RemoveEditConfigStrategy.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/ReplaceEditConfigStrategy.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/getconfig/CandidateDatastoreQueryStrategy.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/getconfig/DatastoreQueryStrategy.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/getconfig/RunningDatastoreQueryStrategy.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpcElementResolved.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/EnumResolver.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/YangStoreContext.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/YangStoreService.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/YangStoreSnapshot.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/transactions/TransactionProvider.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/util/Util.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleIdentityRefAttributeReadingStrategyTest.java delete mode 100644 opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpcElementResolvedTest.java delete mode 100644 opendaylight/netconf/config-persister-impl/pom.xml delete mode 100644 opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/CapabilityStrippingConfigSnapshotHolder.java delete mode 100644 opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/ConfigPersisterNotificationHandler.java delete mode 100644 opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/ConfigPusherImpl.java delete mode 100644 opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/NoOpStorageAdapter.java delete mode 100644 opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/PersisterAggregator.java delete mode 100644 opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/PropertiesProviderAdapterImpl.java delete mode 100644 opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/osgi/ConfigPersisterActivator.java delete mode 100644 opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/osgi/PropertiesProviderBaseImpl.java delete mode 100644 opendaylight/netconf/config-persister-impl/src/main/resources/netconfOp/client_hello.xml delete mode 100644 opendaylight/netconf/config-persister-impl/src/main/resources/netconfOp/commit.xml delete mode 100644 opendaylight/netconf/config-persister-impl/src/main/resources/netconfOp/editConfig.xml delete mode 100644 opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/CapabilityStrippingConfigSnapshotHolderTest.java delete mode 100644 opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/ConfigPersisterNotificationHandlerTest.java delete mode 100644 opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/ConfigPersisterNotificationListenerTest.java delete mode 100644 opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/DummyAdapter.java delete mode 100644 opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/PersisterAggregatorTest.java delete mode 100644 opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/osgi/ConfigPersisterTest.java delete mode 100644 opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/osgi/MockedBundleContext.java delete mode 100644 opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/osgi/TestingExceptionHandler.java delete mode 100644 opendaylight/netconf/config-persister-impl/src/test/resources/capabilities-all.txt delete mode 100644 opendaylight/netconf/config-persister-impl/src/test/resources/capabilities-stripped.txt delete mode 100644 opendaylight/netconf/config-persister-impl/src/test/resources/logback-test.xml delete mode 100644 opendaylight/netconf/config-persister-impl/src/test/resources/snapshot.xml delete mode 100644 opendaylight/netconf/config-persister-impl/src/test/resources/test1.properties delete mode 100644 opendaylight/netconf/config-persister-impl/src/test/resources/test2.properties delete mode 100644 opendaylight/netconf/config-persister-impl/src/test/resources/test3.properties create mode 100644 opendaylight/netconf/features/netconf-connector/pom.xml create mode 100644 opendaylight/netconf/features/netconf-connector/src/main/resources/features.xml create mode 100644 opendaylight/netconf/features/netconf/pom.xml create mode 100644 opendaylight/netconf/features/netconf/src/main/resources/features.xml create mode 100644 opendaylight/netconf/features/pom.xml rename opendaylight/netconf/{ => models}/ietf-netconf-monitoring-extension/pom.xml (96%) rename opendaylight/netconf/{ => models}/ietf-netconf-monitoring-extension/src/main/yang/ietf-netconf-monitoring-extension.yang (100%) rename opendaylight/netconf/{ => models}/ietf-netconf-monitoring/pom.xml (97%) rename 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 (100%) rename 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 (100%) rename opendaylight/netconf/{ => models}/ietf-netconf-monitoring/src/main/yang/ietf-netconf-monitoring.yang (100%) rename opendaylight/netconf/{ => models}/ietf-netconf-notifications/pom.xml (97%) rename opendaylight/netconf/{ => models}/ietf-netconf-notifications/src/main/yang/ietf-netconf-notifications@2012-02-06.yang (100%) rename opendaylight/netconf/{ => models}/ietf-netconf-notifications/src/main/yang/nc-notifications@2008-07-14.yang (100%) rename opendaylight/netconf/{ => models}/ietf-netconf-notifications/src/main/yang/notifications@2008-07-14.yang (100%) rename opendaylight/netconf/{ => models}/ietf-netconf/pom.xml (97%) rename opendaylight/netconf/{ => models}/ietf-netconf/src/main/yang/ietf-netconf@2011-06-01.yang (100%) create mode 100644 opendaylight/netconf/models/pom.xml delete mode 100644 opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/Capability.java delete mode 100644 opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/jmx/CommitJMXNotification.java delete mode 100644 opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/jmx/DefaultCommitOperationMXBean.java delete mode 100644 opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/jmx/NetconfJMXNotification.java create mode 100644 opendaylight/netconf/netconf-config-dispatcher/pom.xml create mode 100644 opendaylight/netconf/netconf-config-dispatcher/src/main/java/org/opendaylight/controller/config/yang/config/netconf/client/dispatcher/NetconfClientDispatcherModule.java create mode 100644 opendaylight/netconf/netconf-config-dispatcher/src/main/java/org/opendaylight/controller/config/yang/config/netconf/client/dispatcher/NetconfClientDispatcherModuleFactory.java create mode 100644 opendaylight/netconf/netconf-config-dispatcher/src/main/yang/odl-netconf-cfg.yang create mode 100644 opendaylight/netconf/netconf-config-dispatcher/src/main/yang/odl-netconfig-client-cfg.yang create mode 100644 opendaylight/netconf/netconf-config-dispatcher/src/test/java/org/opendaylight/controller/config/yang/config/netconf/client/dispatcher/NetconfClientDispatcherModuleTest.java delete mode 100644 opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/CommitNotifier.java delete mode 100644 opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/DefaultCommitNotificationProducer.java delete mode 100644 opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultCommit.java delete mode 100644 opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultCommitTest.java delete mode 100644 opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/SSLUtil.java rename opendaylight/netconf/netconf-mapping-api/src/{ => main}/test/java/org/opendaylight/controller/netconf/mapping/api/HandlingPriorityTest.java (60%) delete mode 100644 opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/capability/BasicCapability.java delete mode 100644 opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/capability/YangModuleCapability.java delete mode 100644 opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/exception/MissingNameSpaceException.java delete mode 100644 opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/exception/UnexpectedElementException.java delete mode 100644 opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/exception/UnexpectedNamespaceException.java delete mode 100644 opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlElement.java delete mode 100644 opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlUtil.java create mode 100644 opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/xml/XMLNetconfUtilTest.java delete mode 100644 opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/xml/XmlElementTest.java delete mode 100644 opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/xml/XmlUtilTest.java create mode 100644 opendaylight/netconf/sal-netconf-connector/pom.xml create mode 100644 opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/connector/netconf/NetconfConnectorModule.java create mode 100644 opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/connector/netconf/NetconfConnectorModuleFactory.java create mode 100644 opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/api/MessageTransformer.java create mode 100644 opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/api/RemoteDevice.java create mode 100644 opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/api/RemoteDeviceCommunicator.java create mode 100644 opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/api/RemoteDeviceHandler.java create mode 100644 opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/api/SchemaContextProviderFactory.java create mode 100644 opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/api/package-info.java create mode 100644 opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDevice.java create mode 100644 opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfStateSchemas.java create mode 100644 opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NotificationHandler.java create mode 100644 opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/listener/NetconfDeviceCapabilities.java create mode 100644 opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/listener/NetconfDeviceCommunicator.java create mode 100644 opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/listener/NetconfSessionPreferences.java create mode 100644 opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/listener/UncancellableFuture.java create mode 100644 opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/package-info.java create mode 100644 opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/KeepaliveSalFacade.java create mode 100644 opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceDataBroker.java create mode 100644 opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceNotificationService.java create mode 100644 opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceRpc.java create mode 100644 opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceSalFacade.java create mode 100644 opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceSalProvider.java create mode 100644 opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceTopologyAdapter.java create mode 100644 opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/AbstractWriteTx.java create mode 100644 opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/ReadOnlyTx.java create mode 100644 opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/ReadWriteTx.java create mode 100644 opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/WriteCandidateRunningTx.java create mode 100644 opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/WriteCandidateTx.java create mode 100644 opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/WriteRunningTx.java create mode 100644 opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/schema/NetconfRemoteSchemaYangSourceProvider.java create mode 100644 opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/schema/mapping/NetconfMessageTransformer.java create mode 100644 opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/util/NetconfBaseOps.java create mode 100644 opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/util/NetconfMessageTransformUtil.java create mode 100644 opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/util/NetconfRpcFutureCallback.java create mode 100644 opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/util/NodeContainerProxy.java create mode 100644 opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/util/MessageCounter.java create mode 100644 opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/util/RemoteDeviceId.java create mode 100644 opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/util/package-info.java create mode 100644 opendaylight/netconf/sal-netconf-connector/src/main/yang/netconf-node-topology.yang create mode 100644 opendaylight/netconf/sal-netconf-connector/src/main/yang/odl-sal-netconf-connector-cfg.yang create mode 100644 opendaylight/netconf/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceTest.java create mode 100644 opendaylight/netconf/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/NetconfStateSchemasTest.java create mode 100644 opendaylight/netconf/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/NetconfToNotificationTest.java create mode 100644 opendaylight/netconf/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/NetconfToRpcRequestTest.java create mode 100644 opendaylight/netconf/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/listener/NetconfDeviceCommunicatorTest.java create mode 100644 opendaylight/netconf/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/listener/NetconfSessionPreferencesTest.java create mode 100644 opendaylight/netconf/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/sal/KeepaliveSalFacadeTest.java create mode 100644 opendaylight/netconf/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceTopologyAdapterTest.java create mode 100644 opendaylight/netconf/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/NetconfDeviceWriteOnlyTxTest.java create mode 100644 opendaylight/netconf/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/ReadOnlyTxTest.java create mode 100644 opendaylight/netconf/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/schema/mapping/NetconfMessageTransformerTest.java create mode 100644 opendaylight/netconf/sal-netconf-connector/src/test/resources/netconf-state.schemas.payload.xml create mode 100644 opendaylight/netconf/sal-netconf-connector/src/test/resources/notification-payload.xml create mode 100644 opendaylight/netconf/sal-netconf-connector/src/test/resources/schemas/config-test-rpc.yang create mode 100644 opendaylight/netconf/sal-netconf-connector/src/test/resources/schemas/rpc-notification-subscription.yang create mode 100644 opendaylight/netconf/sal-netconf-connector/src/test/resources/schemas/test-module.yang create mode 100644 opendaylight/netconf/sal-netconf-connector/src/test/resources/schemas/user-notification.yang rename opendaylight/netconf/{ => tools}/netconf-cli/.gitignore (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/README (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/README_ODL (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/pom.xml (98%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/Cli.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/CommandArgHandlerRegistry.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/Main.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/NetconfDeviceConnectionHandler.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/NetconfDeviceConnectionManager.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/SchemaContextRegistry.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/AbstractCommand.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/Command.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/CommandConstants.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/CommandDispatcher.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/CommandInvocationException.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/input/Input.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/input/InputDefinition.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/local/Close.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/local/Connect.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/local/Disconnect.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/local/Help.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/output/Output.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/output/OutputDefinition.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/remote/RemoteCommand.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/io/BaseConsoleContext.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/io/ConsoleContext.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/io/ConsoleIO.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/io/ConsoleIOImpl.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/io/IOUtil.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/AbstractReader.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/GenericListEntryReader.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/Reader.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/ReadingException.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/custom/ConfigReader.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/custom/EditContentReader.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/custom/FilterReader.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/custom/PasswordReader.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/AnyXmlReader.java (98%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/BasicDataHolderReader.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/ChoiceReader.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/ContainerReader.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/DecisionReader.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/GenericListReader.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/GenericReader.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/LeafListEntryReader.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/LeafReader.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/ListEntryReader.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/SeparatedNodes.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/UnionTypeReader.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/OutFormatter.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/WriteException.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/Writer.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/custom/DataWriter.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/AbstractWriter.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/AugmentationNodeCliSerializer.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/ChoiceNodeCliSerializer.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/CliOutputFromNormalizedNodeSerializerFactory.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/ContainerNodeCliSerializer.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/LeafNodeCliSerializer.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/LeafSetEntryNodeCliSerializer.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/LeafSetNodeCliSerializer.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/MapEntryNodeCliSerializer.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/MapNodeCliSerializer.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/NodeCliSerializerDispatcher.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/NormalizedNodeWriter.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/resources/logback.xml (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/resources/schema/common/ietf-inet-types.yang (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/resources/schema/common/netconf-cli-ext.yang (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/resources/schema/local/netconf-cli.yang (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/main/resources/schema/remote/ietf-netconf.yang (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/test/java/org/opendaylight/controller/netconf/cli/ConsoleIOTestImpl.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/test/java/org/opendaylight/controller/netconf/cli/NetconfCliTest.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/test/java/org/opendaylight/controller/netconf/cli/ValueForMessages.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/test/java/org/opendaylight/controller/netconf/cli/io/IOUtilTest.java (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/test/resources/schema-context/ietf-inet-types.yang (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/test/resources/schema-context/ietf-netconf.yang (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/test/resources/schema-context/model1.yang (100%) rename opendaylight/netconf/{ => tools}/netconf-cli/src/test/resources/schema-context/model2.yang (100%) rename opendaylight/netconf/{ => tools}/netconf-testtool/edit.txt (100%) rename opendaylight/netconf/{ => tools}/netconf-testtool/pom.xml (99%) rename opendaylight/netconf/{ => tools}/netconf-testtool/src/main/assembly/stress-client.xml (100%) rename opendaylight/netconf/{ => tools}/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/AcceptingAuthProvider.java (100%) rename opendaylight/netconf/{ => tools}/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/DummyMonitoringService.java (96%) rename opendaylight/netconf/{ => tools}/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/FakeModuleBuilderCapability.java (100%) rename opendaylight/netconf/{ => tools}/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/Main.java (99%) rename opendaylight/netconf/{ => tools}/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/ModuleBuilderCapability.java (93%) rename opendaylight/netconf/{ => tools}/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/NetconfDeviceSimulator.java (97%) rename opendaylight/netconf/{ => tools}/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/TestToolUtils.java (100%) rename opendaylight/netconf/{ => tools}/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/http/perf/AsyncExecutionStrategy.java (100%) rename opendaylight/netconf/{ => tools}/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/http/perf/Parameters.java (100%) rename opendaylight/netconf/{ => tools}/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/http/perf/PerfClientCallable.java (100%) rename opendaylight/netconf/{ => tools}/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/http/perf/RestPerfClient.java (100%) rename opendaylight/netconf/{ => tools}/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/http/perf/SyncExecutionStrategy.java (100%) rename opendaylight/netconf/{ => tools}/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/AsyncExecutionStrategy.java (98%) rename opendaylight/netconf/{ => tools}/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/ConfigurableClientDispatcher.java (100%) rename opendaylight/netconf/{ => tools}/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/ExecutionStrategy.java (100%) rename opendaylight/netconf/{ => tools}/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/Parameters.java (100%) rename opendaylight/netconf/{ => tools}/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/StressClient.java (99%) rename opendaylight/netconf/{ => tools}/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/StressClientCallable.java (100%) rename opendaylight/netconf/{ => tools}/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/SyncExecutionStrategy.java (98%) rename opendaylight/netconf/{ => tools}/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/DataList.java (92%) rename opendaylight/netconf/{ => tools}/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedCommit.java (79%) rename opendaylight/netconf/{ => tools}/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedCreateSubscription.java (96%) rename opendaylight/netconf/{ => tools}/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedEditConfig.java (89%) rename opendaylight/netconf/{ => tools}/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedGet.java (83%) rename opendaylight/netconf/{ => tools}/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedGetConfig.java (84%) rename opendaylight/netconf/{ => tools}/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedLock.java (79%) rename opendaylight/netconf/{ => tools}/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedUnLock.java (79%) rename opendaylight/netconf/{ => tools}/netconf-testtool/src/main/resources/99-netconf-connector-simulated.xml (100%) rename opendaylight/netconf/{ => tools}/netconf-testtool/src/main/resources/logback.xml (100%) rename opendaylight/netconf/{ => tools}/netconf-testtool/src/main/resources/org.ops4j.pax.url.mvn.cfg (100%) create mode 100644 opendaylight/netconf/tools/pom.xml diff --git a/opendaylight/netconf/config-netconf-connector/pom.xml b/opendaylight/netconf/config-netconf-connector/pom.xml index d8b2ea1c1d..71b9efb7ad 100644 --- a/opendaylight/netconf/config-netconf-connector/pom.xml +++ b/opendaylight/netconf/config-netconf-connector/pom.xml @@ -17,6 +17,11 @@ ${project.groupId} config-api + + ${project.groupId} + config-manager-facade-xml + 0.4.0-SNAPSHOT + ${project.groupId} config-util @@ -25,6 +30,10 @@ ${project.groupId} netconf-api + + ${project.groupId} + netconf-impl + ${project.groupId} netconf-mapping-api @@ -58,12 +67,12 @@ binding-generator-impl - org.osgi - org.osgi.core + org.slf4j + slf4j-api org.slf4j - slf4j-api + slf4j-simple xmlunit @@ -80,11 +89,6 @@ config-manager test - - ${project.groupId} - netconf-impl - test - ${project.groupId} @@ -108,12 +112,6 @@ org.opendaylight.controller.netconf.confignetconfconnector.osgi.Activator - 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, 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 index 9bcd075a1d..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/exception/NetconfConfigHandlingException.java +++ /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.emptyMap()); - } - - public NetconfConfigHandlingException(final String message, final ErrorType errorType, final ErrorTag errorTag, - final ErrorSeverity errorSeverity, final Map 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 index 2724757eb9..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/exception/NoTransactionFoundException.java +++ /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. emptyMap()); - } - - public NoTransactionFoundException(final String message, final ErrorType errorType, final ErrorTag errorTag, - final ErrorSeverity errorSeverity, final Map 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 index d92ea4521e..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/exception/OperationNotPermittedException.java +++ /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. emptyMap()); - } - - public OperationNotPermittedException(final String message, final ErrorType errorType, final ErrorTag errorTag, - final ErrorSeverity errorSeverity, final Map 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 index 38c0b06de4..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/AttributeIfcSwitchStatement.java +++ /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 { - - 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 index cf42686e2c..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/AbstractAttributeReadingStrategy.java +++ /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 configNodes) throws NetconfDocumentedException { - if (configNodes.size() == 0){ - return AttributeConfigElement.createNullValue(postprocessNullableDefault(nullableDefault)); - } - return readElementHook(configNodes); - } - - abstract AttributeConfigElement readElementHook(List 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 index 80e549e719..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ArrayAttributeReadingStrategy.java +++ /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 configNodes) throws NetconfDocumentedException { - List 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 index fac1b358ce..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/AttributeConfigElement.java +++ /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 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> attributeResolvingStrategy, - String attrName) throws NetconfDocumentedException { - resolvedValue = attributeResolvingStrategy.parseAttribute(attrName, value); - Optional resolvedDefault = attributeResolvingStrategy.parseAttribute(attrName, defaultValue); - resolvedDefaultValue = resolvedDefault.isPresent() ? resolvedDefault.get() : null; - } - - public Optional 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 index 359a4c4a3a..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/AttributeReadingStrategy.java +++ /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 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 index 3e4957ba67..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/CompositeAttributeReadingStrategy.java +++ /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 innerStrategies; - - public CompositeAttributeReadingStrategy(String nullableDefault, - Map innerStrategies) { - super(nullableDefault); - this.innerStrategies = innerStrategies; - } - - @Override - AttributeConfigElement readElementHook(List configNodes) throws NetconfDocumentedException { - - Preconditions.checkState(configNodes.size() == 1, "This element should be present only once %s", configNodes); - - XmlElement complexElement = configNodes.get(0); - - Map innerMap = Maps.newHashMap(); - - List recognisedChildren = Lists.newArrayList(); - for (Entry innerAttrEntry : innerStrategies.entrySet()) { - List 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 index 709c8d23b8..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ObjectNameAttributeReadingStrategy.java +++ /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 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 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 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 index 15d4d080e2..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ObjectXmlReader.java +++ /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 { - - private String key; - private Map> identityMap; - - public Map prepareReading(Map yangToAttrConfig, Map> identityMap) { - Map strategies = Maps.newHashMap(); - this.identityMap = identityMap; - - for (Entry 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 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 inner = ((TOAttribute)lastAttribute).getYangPropertiesToTypesMap(); - - Map innerStrategies = Maps.newHashMap(); - - for (Entry 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 index 8f6a7cd1e4..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleAttributeReadingStrategy.java +++ /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 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 index 3a62672900..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleBinaryAttributeReadingStrategy.java +++ /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 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 index 7d78e7d868..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleCompositeAttributeReadingStrategy.java +++ /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 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 index 6d702ef59f..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleIdentityRefAttributeReadingStrategy.java +++ /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> identityMap; - - public SimpleIdentityRefAttributeReadingStrategy(String nullableDefault, String key, Map> identityMap) { - super(nullableDefault); - this.key = key; - this.identityMap = identityMap; - } - - @Override - protected String readElementContent(XmlElement xmlElement) throws NetconfDocumentedException { - Map.Entry 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 revisions = identityMap.get(namespace); - if(revisions.keySet().size() > 1) { - for (Map.Entry 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 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 index 605542fb51..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleUnionAttributeReadingStrategy.java +++ /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 chars = Lists.newArrayListWithCapacity(charArray.length); - - for (char c : charArray) { - chars.add(Character.toString(c)); - } - - Map 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 index 0d5fcb99b8..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/AbstractAttributeMappingStrategy.java +++ /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> implements - AttributeMappingStrategy { - - 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 index a4eeb0c572..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ArrayAttributeMappingStrategy.java +++ /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, ArrayType> { - - private final AttributeMappingStrategy> innerElementStrategy; - - public ArrayAttributeMappingStrategy(ArrayType arrayType, - AttributeMappingStrategy> innerElementStrategy) { - super(arrayType); - this.innerElementStrategy = innerElementStrategy; - } - - @Override - public Optional> mapAttribute(Object value) { - if (value == null){ - return Optional.absent(); - } - - Preconditions.checkArgument(value.getClass().isArray(), "Value has to be instanceof Array "); - - List 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 index d36b13b91e..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/AttributeMappingStrategy.java +++ /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> { - - O getOpenType(); - - Optional 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 index 16421d5a1d..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/CompositeAttributeMappingStrategy.java +++ /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, CompositeType> { - - private final Map>> innerStrategies; - private final Map jmxToJavaNameMapping; - - public CompositeAttributeMappingStrategy(CompositeType compositeType, - Map>> innerStrategies, - Map jmxToJavaNameMapping) { - super(compositeType); - this.innerStrategies = innerStrategies; - this.jmxToJavaNameMapping = jmxToJavaNameMapping; - } - - @Override - public Optional> 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 expectedCompositeTypeKeys = expectedType.keySet(); - Set currentCompositeTypeKeys = currentType.keySet(); - Preconditions.checkArgument(expectedCompositeTypeKeys.equals(currentCompositeTypeKeys), - "Composite type mismatch, expected composite type with attributes " + expectedCompositeTypeKeys - + " but was " + currentCompositeTypeKeys); - - Map 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> 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 index 052438beb5..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/EnumAttributeMappingStrategy.java +++ /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 { - - private final EnumResolver enumResolver; - - public EnumAttributeMappingStrategy(CompositeType openType, final EnumResolver enumResolver) { - super(openType); - this.enumResolver = enumResolver; - } - - @Override - public Optional 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 index 2608c57e00..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectMapper.java +++ /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>> { - - private EnumResolver enumResolver; - - public Map>> prepareMapping( - Map configDefinition, EnumResolver enumResolver) { - this.enumResolver = Preconditions.checkNotNull(enumResolver); - Map>> strategies = Maps.newHashMap(); - - for (Entry attrEntry : configDefinition.entrySet()) { - strategies.put(attrEntry.getKey(), prepareStrategy(attrEntry.getValue())); - } - - return strategies; - } - - public AttributeMappingStrategy> 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 createJmxToYangMapping(TOAttribute attributeIfc) { - Map retVal = Maps.newHashMap(); - for (Entry entry : attributeIfc.getJmxPropertiesToTypesMap().entrySet()) { - retVal.put(entry.getKey(), (entry.getValue()).getAttributeYangName()); - } - return retVal; - } - - @Override - protected AttributeMappingStrategy> caseJavaSimpleAttribute(SimpleType openType) { - return new SimpleAttributeMappingStrategy(openType); - } - - @Override - protected AttributeMappingStrategy> caseJavaEnumAttribute(final OpenType openType) { - return new EnumAttributeMappingStrategy(((CompositeType) openType), enumResolver); - } - - @Override - protected AttributeMappingStrategy> caseJavaArrayAttribute(ArrayType openType) { - - AttributeMappingStrategy> innerStrategy = new SimpleAttributeMappingStrategy( - (SimpleType) openType.getElementOpenType()); - return new ArrayAttributeMappingStrategy(openType, innerStrategy); - } - - @Override - protected AttributeMappingStrategy> caseJavaCompositeAttribute(CompositeType openType) { - Map>> innerStrategies = Maps.newHashMap(); - - Map 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> caseJavaUnionAttribute(OpenType openType) { - Map>> innerStrategies = Maps.newHashMap(); - - Map 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> caseDependencyAttribute( - SimpleType openType) { - return new ObjectNameAttributeMappingStrategy(openType, namespaceOfDepAttr); - } - - @Override - protected AttributeMappingStrategy> caseTOAttribute(CompositeType openType) { - Map>> innerStrategies = Maps.newHashMap(); - - Preconditions.checkState(getLastAttribute() instanceof TOAttribute); - TOAttribute lastTO = (TOAttribute) getLastAttribute(); - - for (Entry innerAttrEntry : ((TOAttribute)getLastAttribute()).getJmxPropertiesToTypesMap().entrySet()) { - innerStrategies.put(innerAttrEntry.getKey(), prepareStrategy(innerAttrEntry.getValue())); - } - - return new CompositeAttributeMappingStrategy(openType, innerStrategies, - createJmxToYangMapping(lastTO)); - } - - @Override - protected AttributeMappingStrategy> caseListAttribute(ArrayType openType) { - Preconditions.checkState(getLastAttribute() instanceof ListAttribute); - return new ArrayAttributeMappingStrategy(openType, - prepareStrategy(((ListAttribute) getLastAttribute()).getInnerAttribute())); - } - - @Override - protected AttributeMappingStrategy> 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 index b0569dec62..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectNameAttributeMappingStrategy.java +++ /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> { - - private final String namespace; - - public ObjectNameAttributeMappingStrategy(SimpleType openType, String namespace) { - super(openType); - this.namespace = namespace; - } - - @Override - public Optional 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 index 101649edb9..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/SimpleAttributeMappingStrategy.java +++ /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> { - - public SimpleAttributeMappingStrategy(SimpleType openType) { - super(openType); - } - - @Override - public Optional 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 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 index 033ab4391f..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/UnionCompositeAttributeMappingStrategy.java +++ /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>> innerStrategies, Map 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 index 5763ed8caf..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/AbstractAttributeResolvingStrategy.java +++ /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> implements AttributeResolvingStrategy { - 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 index 9c17fa4892..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ArrayAttributeResolvingStrategy.java +++ /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> { - - private final AttributeResolvingStrategy> innerTypeResolvingStrategy; - - private static final Logger LOG = LoggerFactory.getLogger(ArrayAttributeResolvingStrategy.class); - - public ArrayAttributeResolvingStrategy(AttributeResolvingStrategy> innerTypeResolved, - ArrayType openType) { - super(openType); - this.innerTypeResolvingStrategy = innerTypeResolved; - } - - @Override - public Optional 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(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 index 23d01dea5d..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/AttributeResolvingStrategy.java +++ /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> { - O getOpenType(); - - Optional 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 index b912a49186..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/CompositeAttributeResolvingStrategy.java +++ /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 { - private final Map>> innerTypes; - private final Map yangToJavaAttrMapping; - - private static final Logger LOG = LoggerFactory.getLogger(CompositeAttributeResolvingStrategy.class); - - CompositeAttributeResolvingStrategy(Map>> innerTypes, - CompositeType openType, Map yangToJavaAttrMapping) { - super(openType); - this.innerTypes = innerTypes; - this.yangToJavaAttrMapping = yangToJavaAttrMapping; - } - - @Override - public String toString() { - return "ResolvedCompositeAttribute [" + innerTypes + "]"; - } - - @Override - public Optional 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 items = Maps.newHashMap(); - Map> 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> 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 index 25c4da1a66..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/EnumAttributeResolvingStrategy.java +++ /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 { - - 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 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 index 34b4a8e3c9..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectNameAttributeResolvingStrategy.java +++ /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> { - - 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 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 index 93c83eb93c..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectResolver.java +++ /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>> { - - private final ServiceRegistryWrapper serviceTracker; - private EnumResolver enumResolver; - - public ObjectResolver(ServiceRegistryWrapper serviceTracker) { - this.serviceTracker = serviceTracker; - } - - public Map>> prepareResolving( - Map configDefinition, final EnumResolver enumResolver) { - this.enumResolver = enumResolver; - - Map>> strategies = Maps.newHashMap(); - - for (Entry attrEntry : configDefinition.entrySet()) { - strategies.put(attrEntry.getKey(), - prepareStrategy(attrEntry.getValue())); - } - - return strategies; - } - - private AttributeResolvingStrategy> prepareStrategy(AttributeIfc attributeIfc) { - return switchAttribute(attributeIfc); - } - - private Map createYangToJmxMapping(TOAttribute attributeIfc) { - Map retVal = Maps.newHashMap(); - for (Entry entry : attributeIfc.getYangPropertiesToTypesMap().entrySet()) { - retVal.put(entry.getKey(), (entry.getValue()).getLowerCaseCammelCase()); - } - return retVal; - } - - @Override - protected AttributeResolvingStrategy> caseJavaEnumAttribute(final OpenType openType) { - return new EnumAttributeResolvingStrategy((CompositeType) openType, enumResolver); - } - - @Override - protected AttributeResolvingStrategy> caseJavaSimpleAttribute(SimpleType openType) { - return new SimpleAttributeResolvingStrategy(openType); - } - - @Override - protected AttributeResolvingStrategy> caseJavaArrayAttribute(ArrayType openType) { - - SimpleType innerType = (SimpleType) openType.getElementOpenType(); - AttributeResolvingStrategy> strat = new SimpleAttributeResolvingStrategy(innerType); - return new ArrayAttributeResolvingStrategy(strat, openType); - } - - @Override - protected AttributeResolvingStrategy> caseJavaCompositeAttribute(CompositeType openType) { - Map>> innerMap = Maps.newHashMap(); - Map yangToJmxMapping = Maps.newHashMap(); - - fillMappingForComposite(openType, innerMap, yangToJmxMapping); - return new CompositeAttributeResolvingStrategy(innerMap, openType, yangToJmxMapping); - } - - private void fillMappingForComposite(CompositeType openType, Map>> innerMap, Map yangToJmxMapping) { - for (String innerAttributeKey : openType.keySet()) { - innerMap.put(innerAttributeKey, caseJavaAttribute(openType.getType(innerAttributeKey))); - yangToJmxMapping.put(innerAttributeKey, innerAttributeKey); - } - } - - @Override - protected AttributeResolvingStrategy> caseJavaUnionAttribute(OpenType openType) { - - Preconditions.checkState(openType instanceof CompositeType, "Unexpected open type, expected %s but was %s"); - CompositeType compositeType = (CompositeType) openType; - - Map>> innerMap = Maps.newHashMap(); - Map yangToJmxMapping = Maps.newHashMap(); - fillMappingForComposite(compositeType, innerMap, yangToJmxMapping); - - return new UnionCompositeAttributeResolvingStrategy(innerMap, compositeType, yangToJmxMapping); - } - - @Override - protected AttributeResolvingStrategy> caseDependencyAttribute( - SimpleType openType) { - return new ObjectNameAttributeResolvingStrategy(serviceTracker); - } - - @Override - protected AttributeResolvingStrategy> caseTOAttribute(CompositeType openType) { - Preconditions.checkState(getLastAttribute() instanceof TOAttribute); - TOAttribute toAttribute = (TOAttribute) getLastAttribute(); - - Map>> 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> caseListAttribute(ArrayType openType) { - Preconditions.checkState(getLastAttribute() instanceof ListAttribute); - AttributeIfc innerAttribute = ((ListAttribute) getLastAttribute()).getInnerAttribute(); - return new ArrayAttributeResolvingStrategy(prepareStrategy(innerAttribute), openType); - } - - @Override - protected AttributeResolvingStrategy> 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 index f1e603c60d..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/SimpleAttributeResolvingStrategy.java +++ /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> { - - 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 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 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 index 4cab995d4e..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/UnionCompositeAttributeResolvingStrategy.java +++ /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>> innerTypes, - CompositeType openType, Map yangToJavaAttrMapping) { - super(innerTypes, openType, yangToJavaAttrMapping); - } - - protected Map 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 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 index e888e4dd5c..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/ArrayAttributeWritingStrategy.java +++ /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 index d0c2b885f7..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/AttributeWritingStrategy.java +++ /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 index 11cb35cc31..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/CompositeAttributeWritingStrategy.java +++ /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 innerStrats; - - public CompositeAttributeWritingStrategy(Document document, String key, - Map 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 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 index 043aec6eba..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/ObjectNameAttributeWritingStrategy.java +++ /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.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 index 022e370c30..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/ObjectXmlWriter.java +++ /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 { - - private Document document; - private String key; - - public Map prepareWriting(Map yangToAttrConfig, - Document document) { - - Map preparedWriting = Maps.newHashMap(); - - for (Entry 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 innerStrats = Maps.newHashMap(); - String currentKey = key; - for (Entry 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 index ea53467232..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/RuntimeBeanEntryWritingStrategy.java +++ /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 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.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.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 index 4b68b9afcd..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleAttributeWritingStrategy.java +++ /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 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 index 8407ded18e..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleBinaryAttributeWritingStrategy.java +++ /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 index eac77438bf..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleCompositeAttributeWritingStrategy.java +++ /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 index 069ccc1093..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleIdentityRefAttributeWritingStrategy.java +++ /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 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 index ee97b27a32..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleUnionAttributeWritingStrategy.java +++ /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 index c26b4cf5bf..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Config.java +++ /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> moduleConfigs; - - private final Map> identityMap; - - private final EnumResolver enumResolver; - - public Config(Map> moduleConfigs, final EnumResolver enumResolver) { - this(moduleConfigs, Collections.>emptyMap(), enumResolver); - } - - public Config(Map> moduleConfigs, Map> identityMap, final EnumResolver enumResolver) { - this.moduleConfigs = moduleConfigs; - this.identityMap = identityMap; - this.enumResolver = enumResolver; - } - - public static Map>> getMappedInstances(Set instancesToMap, - Map> configs) { - Multimap moduleToInstances = mapInstancesToModules(instancesToMap); - - Map>> retVal = Maps.newLinkedHashMap(); - - for (Entry> namespaceToModuleToConfigEntry : configs.entrySet()) { - - Map> innerRetVal = Maps.newHashMap(); - - for (Entry mbeEntry : namespaceToModuleToConfigEntry.getValue().entrySet()) { - - String moduleName = mbeEntry.getKey(); - Collection 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 mapInstancesToModules(Set instancesToMap) { - Multimap retVal = HashMultimap.create(); - - for (ObjectName objectName : instancesToMap) { - String factoryName = ObjectNameUtil.getFactoryName(objectName); - retVal.put(factoryName, objectName); - } - return retVal; - } - - public Element toXml(Set instancesToMap, Optional maybeNamespace, Document document, - Element dataElement, ServiceRegistryWrapper serviceTracker) { - - Map>> 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>> moduleToInstanceEntry : moduleToInstances.entrySet()) { - for (Entry> 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> fromXmlModulesResolved(XmlElement xml, EditStrategyType defaultEditStrategyType, ServiceRegistryWrapper serviceTracker) throws NetconfDocumentedException { - Optional modulesElement = getModulesElement(xml); - List moduleElements = getModulesElementList(modulesElement); - - Map> retVal = Maps.newHashMap(); - - for (XmlElement moduleElement : moduleElements) { - ResolvingStrategy resolvingStrategy = new ResolvingStrategy() { - @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> fromXmlModulesMap(XmlElement xml, - EditStrategyType defaultEditStrategyType, ServiceRegistryWrapper serviceTracker) throws NetconfDocumentedException { - Optional modulesElement = getModulesElement(xml); - List moduleElements = getModulesElementList(modulesElement); - - Map> retVal = Maps.newHashMap(); - - for (XmlElement moduleElement : moduleElements) { - ResolvingStrategy resolvingStrategy = new ResolvingStrategy() { - @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 getModulesElement(XmlElement xml) { - return xml.getOnlyChildElementOptionally(XmlNetconfConstants.MODULES_KEY, - XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG); - } - - private List getModulesElementList(Optional modulesElement) throws NetconfDocumentedException { - List moduleElements; - - if (modulesElement.isPresent()) { - moduleElements = modulesElement.get().getChildElementsWithSameNamespace(XmlNetconfConstants.MODULE_KEY); - modulesElement.get().checkUnrecognisedElements(moduleElements); - } else { - moduleElements = Lists.newArrayList(); - } - return moduleElements; - } - - private void resolveModule(Map> retVal, ServiceRegistryWrapper serviceTracker, - XmlElement moduleElement, EditStrategyType defaultStrategy, ResolvingStrategy resolvingStrategy) throws NetconfDocumentedException { - XmlElement typeElement = null; - typeElement = moduleElement.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.TYPE_KEY); - Entry 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 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 servicesElement = getServicesElement(xml); - - Services services; - if (servicesElement.isPresent()) { - services = Services.fromXml(servicesElement.get()); - } else { - services = new Services(); - } - - return services; - } - - private static Optional 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 servicesOpt = getServicesElement(parent); - Optional modulesOpt = getModulesElement(parent); - - List 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 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 { - 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 index 7cfeb453bb..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfig.java +++ /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 yangToAttrConfig; - private final String nullableDummyContainerName; - private final Map jmxToAttrConfig; - private final BeanReader configRegistryClient; - - public InstanceConfig(BeanReader configRegistryClient, Map yangNamesToAttributes, - String nullableDummyContainerName) { - - this.yangToAttrConfig = yangNamesToAttributes; - this.nullableDummyContainerName = nullableDummyContainerName; - this.jmxToAttrConfig = reverseMap(yangNamesToAttributes); - this.configRegistryClient = configRegistryClient; - } - - private Map getMappedConfiguration(ObjectName on, final EnumResolver enumResolver) { - - // TODO make field, mappingStrategies can be instantiated only once - Map>> mappingStrategies = new ObjectMapper() - .prepareMapping(jmxToAttrConfig, enumResolver); - - Map toXml = Maps.newHashMap(); - - for (Entry 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> 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 strats = new ObjectXmlWriter().prepareWriting(yangToAttrConfig, document); - Map 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 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>> resolvingStrategies = new ObjectResolver( - depTracker).prepareResolving(yangToAttrConfig, enumResolver); - - for (Entry configDefEntry : mappedConfig.getConfiguration().entrySet()) { - AttributeConfigElement value = configDefEntry.getValue(); - String attributeName = configDefEntry.getKey(); - try { - AttributeResolvingStrategy> 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> identityMap, final EnumResolver enumResolver) throws NetconfDocumentedException { - Map retVal = Maps.newHashMap(); - - Map strats = new ObjectXmlReader().prepareReading(yangToAttrConfig, identityMap); - List recognisedChildren = Lists.newArrayList(); - - XmlElement typeElement = moduleElement.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.TYPE_KEY); - XmlElement nameElement = moduleElement.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.NAME_KEY); - List 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 readStratEntry : strats.entrySet()) { - List 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 getConfigNodes(XmlElement moduleElement, String moduleNamespace, String name, - List recognisedChildren, List typeAndName) throws NetconfDocumentedException { - List 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 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 reverseMap(Map yangNameToAttr) { - Map reversednameToAtr = Maps.newHashMap(); - - for (Entry 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 index ef5ba753d3..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfigElementResolved.java +++ /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 configuration; - - public InstanceConfigElementResolved(String currentStrategy, Map configuration, - EditStrategyType defaultStrategy) - throws NetconfDocumentedException { - this.editStrategy = parseStrategy(currentStrategy, defaultStrategy); - this.configuration = configuration; - } - - public InstanceConfigElementResolved(Map 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 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 index 5cadc08047..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleConfig.java +++ /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.absent()); - - // type belongs to config.yang namespace, but needs to be prefix:moduleName - - 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.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> 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 index 88a18adcfe..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleElementDefinition.java +++ /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 index 6d2936c827..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleElementResolved.java +++ /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 index 9ce550e505..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ServiceRegistryWrapper.java +++ /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>> mappedServices = getMappedServices(); - Map> 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 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>> getMappedServices() { - Map>> retVal = Maps.newHashMap(); - - Map> serviceMapping = configServiceRefRegistry.getServiceMapping(); - for (Map.Entry> 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> serviceToRefs = retVal.get(namespace); - if(serviceToRefs==null) { - serviceToRefs = Maps.newHashMap(); - retVal.put(namespace, serviceToRefs); - } - - String localName = qname.getLocalName(); - Map 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 index 74655f938f..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Services.java +++ /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>> namespaceToServiceNameToRefNameToInstance = Maps - .newHashMap(); - - /** - * - */ - public Map>> getNamespaceToServiceNameToRefNameToInstance() { - return namespaceToServiceNameToRefNameToInstance; - } - - private static Services resolveServices(Map>> mappedServices) { - Services tracker = new Services(); - - for (Entry>> namespaceEntry : mappedServices.entrySet()) { - String namespace = namespaceEntry.getKey(); - - for (Entry> serviceEntry : namespaceEntry.getValue().entrySet()) { - - String serviceName = serviceEntry.getKey(); - for (Entry refEntry : serviceEntry.getValue().entrySet()) { - - Map> namespaceToServices = tracker.namespaceToServiceNameToRefNameToInstance.get(namespace); - if (namespaceToServices == null) { - namespaceToServices = Maps.newHashMap(); - tracker.namespaceToServiceNameToRefNameToInstance.put(namespace, namespaceToServices); - } - - Map 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>> retVal = Maps.newHashMap(); - - List services = xml.getChildElements(SERVICE_KEY); - xml.checkUnrecognisedElements(services); - - for (XmlElement service : services) { - - XmlElement typeElement = service.getOnlyChildElement(TYPE_KEY); - Entry prefixNamespace = typeElement.findNamespaceOfTextContent(); - - Preconditions.checkState(prefixNamespace.getKey()!=null && !prefixNamespace.getKey().equals(""), "Type attribute was not prefixed"); - - Map> namespaceToServices = retVal.get(prefixNamespace.getValue()); - if(namespaceToServices == null) { - namespaceToServices = Maps.newHashMap(); - retVal.put(prefixNamespace.getValue(), namespaceToServices); - } - - String serviceName = ObjectNameAttributeReadingStrategy.checkPrefixAndExtractServiceName(typeElement, prefixNamespace); - - Map innerMap = namespaceToServices.get(serviceName); - if (innerMap == null) { - innerMap = Maps.newHashMap(); - namespaceToServices.put(serviceName, innerMap); - } - - List 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>> mappedServices = serviceRegistryWrapper.getMappedServices(); - for (Entry>> namespaceToRefEntry : mappedServices.entrySet()) { - - for (Entry> serviceEntry : namespaceToRefEntry.getValue().entrySet()) { - // service belongs to config.yang namespace - Element serviceElement = XmlUtil.createElement(document, SERVICE_KEY, Optional.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 instanceEntry : serviceEntry.getValue().entrySet()) { - Element instanceElement = XmlUtil.createElement(document, XmlNetconfConstants.INSTANCE_KEY, Optional.absent()); - serviceElement.appendChild(instanceElement); - - Element nameElement = XmlUtil.createTextElement(document, NAME_KEY, instanceEntry.getKey(), Optional.absent()); - instanceElement.appendChild(nameElement); - - Element providerElement = XmlUtil.createTextElement(document, PROVIDER_KEY, instanceEntry.getValue(), Optional.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 index f7108f44c7..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/rpc/InstanceRuntimeRpc.java +++ /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 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 map(List parameters) { - Map mapped = Maps.newHashMap(); - for (JavaAttribute javaAttribute : parameters) { - mapped.put(javaAttribute.getAttributeYangName(), javaAttribute); - } - return mapped; - } - - private void resolveConfiguration(Map mappedConfig) { - - // TODO make field, resolvingStrategies can be instantiated only once - Map>> resolvingStrategies = new ObjectResolver(null) - .prepareResolving(yangToAttrConfig, enumResolver); - // TODO make constructor for object resolver without service tracker - for (Entry configDefEntry : mappedConfig.entrySet()) { - try { - - AttributeResolvingStrategy> 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 fromXml(XmlElement configRootNode) throws NetconfDocumentedException { - Map retVal = Maps.newHashMap(); - - // FIXME add identity map to runtime data - Map strats = new ObjectXmlReader().prepareReading(yangToAttrConfig, - Collections.> emptyMap()); - - for (Entry readStratEntry : strats.entrySet()) { - List 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 index 7316dbcb06..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/rpc/ModuleRpcs.java +++ /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 yangToJavaNames = Maps.newHashMap(); - private final Map> 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 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 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 index 2eef2a6fe8..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/rpc/Rpcs.java +++ /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> mappedRpcs; - - public Rpcs(Map> mappedRpcs) { - super(); - this.mappedRpcs = mappedRpcs; - } - - public ModuleRpcs getRpcMapping(RuntimeRpcElementResolved id) { - Map 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 index ce30dc4391..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/InstanceRuntime.java +++ /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 childrenMappings; - private final Map jmxToYangChildRbeMapping; - - public InstanceRuntime(InstanceConfig instanceMapping, Map childrenMappings, - Map 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 findChildren(ObjectName innerRootBean, Set childRbeOns) { - final Map wantedProperties = innerRootBean.getKeyPropertyList(); - - return Sets.newHashSet(Collections2.filter(childRbeOns, new Predicate() { - - @Override - public boolean apply(ObjectName on) { - Map localProperties = on.getKeyPropertyList(); - for (Entry 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 getRootBeans(Set childRbeOns, final String string, final int keyListSize) { - return Sets.newHashSet(Collections2.filter(childRbeOns, new Predicate() { - - @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 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 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 childMappingEntry : childrenMappings.entrySet()) { - Set innerRootBeans = getRootBeans(childRbeOns, childMappingEntry.getKey(), rootOn - .getKeyPropertyList().size()); - - for (ObjectName objectName : innerRootBeans) { - Set 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 index ca2c019342..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/ModuleRuntime.java +++ /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 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 runtimeBeanOns, - Document document, ModuleConfig moduleConfig, ObjectName configBeanON, final EnumResolver enumResolver) { - - Element moduleElement = moduleConfig.toXml(configBeanON, document, namespace, enumResolver); - - ObjectName rootName = findRoot(runtimeBeanOns); - - Set 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 index ddbc99d0e5..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/Runtime.java +++ /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> moduleRuntimes; - private final Map> moduleConfigs; - - public Runtime(Map> moduleRuntimes, - Map> moduleConfigs) { - this.moduleRuntimes = moduleRuntimes; - this.moduleConfigs = moduleConfigs; - } - - private Map> mapInstancesToModules(Set instancesToMap) { - Map> 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 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 instancesToMap, Set configBeans, Document document, final EnumResolver enumResolver) { - Element root = XmlUtil.createElement(document, XmlNetconfConstants.DATA_KEY, Optional.absent()); - - Element modulesElement = XmlUtil.createElement(document, XmlNetconfConstants.MODULES_KEY, Optional.of(XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG)); - root.appendChild(modulesElement); - - Map> moduleToRuntimeInstance = mapInstancesToModules(instancesToMap); - Map>> moduleToConfigInstance = Config.getMappedInstances( - configBeans, moduleConfigs); - - for (String localNamespace : moduleConfigs.keySet()) { - - Map> instanceToMbe = moduleToConfigInstance.get(localNamespace); - - for (String moduleName : moduleConfigs.get(localNamespace).keySet()) { - Multimap 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; - } - -} diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/AbstractConfigNetconfOperation.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/AbstractConfigNetconfOperation.java index c4217106ce..8029a1b0a6 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/AbstractConfigNetconfOperation.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/AbstractConfigNetconfOperation.java @@ -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; } } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/Commit.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/Commit.java index 8a0830e48a..6e295580f9 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/Commit.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/Commit.java @@ -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 index 9c55953bbc..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/Datastore.java +++ /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); - } - } -} diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/DiscardChanges.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/DiscardChanges.java index 1f70a1e52d..3010b4ffe9 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/DiscardChanges.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/DiscardChanges.java @@ -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 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); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/Lock.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/Lock.java index ea019642c5..f9372c0cf3 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/Lock.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/Lock.java @@ -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()); } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/UnLock.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/UnLock.java index 07b10aa327..c221273241 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/UnLock.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/UnLock.java @@ -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 diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/Validate.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/Validate.java index 6fc7165ed7..38918b18ca 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/Validate.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/Validate.java @@ -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 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 index df4671371d..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/AbstractEditConfigStrategy.java +++ /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 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 configuration, ConfigTransactionClient ta, - String module, String instance, ServiceRegistryWrapper services) throws NetconfConfigHandlingException; - - abstract void executeStrategy(Map 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 index 0155d59583..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/DeleteEditConfigStrategy.java +++ /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 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 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); - } - } -} diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfig.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfig.java index b7699bf69c..d9076fa891 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfig.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfig.java @@ -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.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 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>> namespaceToServiceNameToRefNameToInstance = services - .getNamespaceToServiceNameToRefNameToInstance(); - - for (Map.Entry>> namespaceToServiceToRefEntry : namespaceToServiceNameToRefNameToInstance.entrySet()) { - for (Map.Entry> serviceToRefEntry : namespaceToServiceToRefEntry.getValue().entrySet()) { - - String qnameOfService = getQname(ta, namespaceToServiceToRefEntry.getKey(), serviceToRefEntry.getKey()); - Map refNameToInstance = serviceToRefEntry.getValue(); - - for (Map.Entry 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 modulesToResolved : execution.getResolvedXmlElements(ta).values()) { - - for (Map.Entry 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 modulesToResolved : execution.getModulesDefinition(ta).values()) { - for (Map.Entry 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> factories = transformMbeToModuleConfigs(configRegistryClient, - yangStoreSnapshot.getModuleMXBeanEntryMap()); - Map> identitiesMap = transformIdentities(yangStoreSnapshot.getModules()); - return new Config(factories, identitiesMap, yangStoreSnapshot.getEnumResolver()); - } - - - public static class IdentityMapping { - private final Map 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> transformIdentities(Set modules) { - Map> mappedIds = Maps.newHashMap(); - for (Module module : modules) { - String namespace = module.getNamespace().toString(); - Map 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> transformMbeToModuleConfigs ( - final BeanReader configRegistryClient, Map> mBeanEntries) { - - Map> namespaceToModuleNameToModuleConfig = Maps.newHashMap(); - - for (Map.Entry> namespaceToModuleToMbe : mBeanEntries.entrySet()) { - for (Map.Entry 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 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.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 index 9c78457fce..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigStrategy.java +++ /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 configuration, - ConfigTransactionClient ta, ServiceRegistryWrapper services) throws NetconfConfigHandlingException; - -} diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigXmlParser.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigXmlParser.java index 99c0a2ff0d..3995a0a5a4 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigXmlParser.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigXmlParser.java @@ -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> 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> 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 index 25d772f4ac..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditStrategyType.java +++ /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 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 index d3d5bd90a7..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MergeEditConfigStrategy.java +++ /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 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 configuration, ConfigTransactionClient ta, ObjectName on, ServiceRegistryWrapper services) throws NetconfConfigHandlingException { - - for (Entry 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 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 index 1eb4c834dc..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MissingInstanceHandlingStrategy.java +++ /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 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 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 index 83afd70816..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/NoneEditConfigStrategy.java +++ /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 configuration, - ConfigTransactionClient ta, ServiceRegistryWrapper services) throws NetconfConfigHandlingException { - if(configuration != null && !configuration.isEmpty()) { - for (Map.Entry attrEntry : configuration.entrySet()) { - if(attrEntry.getValue().getEditStrategy().isPresent()) { - final Map 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 index 55040d7824..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/RemoveEditConfigStrategy.java +++ /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 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 index 8d786d2c8d..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/ReplaceEditConfigStrategy.java +++ /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 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 configuration, ConfigTransactionClient ta, ObjectName on, ServiceRegistryWrapper services) throws NetconfConfigHandlingException { - for (Entry 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); - } - } - } -} diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/get/Get.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/get/Get.java index 40592ea64b..0b79f5e17c 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/get/Get.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/get/Get.java @@ -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> createModuleRuntimes(ConfigRegistryClient configRegistryClient, - Map> mBeanEntries) { - Map> retVal = Maps.newHashMap(); - - for (Map.Entry> namespaceToModuleEntry : mBeanEntries.entrySet()) { - - Map innerMap = Maps.newHashMap(); - Map entriesFromNamespace = namespaceToModuleEntry.getValue(); - for (Map.Entry moduleToMXEntry : entriesFromNamespace.entrySet()) { - - ModuleMXBeanEntry mbe = moduleToMXEntry.getValue(); - - Map 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 cache) { - Map 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 createJmxToYangMap(List children) { - Map 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 runtimeBeans = getConfigRegistryClient().lookupRuntimeBeans(); - - final Set configBeans = Datastore.getInstanceQueryStrategy(Datastore.running, transactionProvider) - .queryInstances(getConfigRegistryClient()); - - final Map> moduleRuntimes = createModuleRuntimes(getConfigRegistryClient(), - yangStoreSnapshot.getModuleMXBeanEntryMap()); - final Map> 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 index 6275fcad46..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/getconfig/CandidateDatastoreQueryStrategy.java +++ /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 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 index d73311664b..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/getconfig/DatastoreQueryStrategy.java +++ /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 queryInstances(ConfigRegistryClient configRegistryClient); - -} diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/getconfig/GetConfig.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/getconfig/GetConfig.java index 401124e7d9..e5ba3dbb1e 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/getconfig/GetConfig.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/getconfig/GetConfig.java @@ -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 maybeNamespace; - private final TransactionProvider transactionProvider; - private static final Logger LOG = LoggerFactory.getLogger(GetConfig.class); - public GetConfig(YangStoreContext yangStoreSnapshot, Optional maybeNamespace, - TransactionProvider transactionProvider, ConfigRegistryClient configRegistryClient, - String netconfSessionIdForReporting) { - super(configRegistryClient, netconfSessionIdForReporting); - this.yangStoreSnapshot = yangStoreSnapshot; + public GetConfig(final ConfigSubsystemFacade configSubsystemFacade, final Optional 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.absent()); - final Set 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 index 74b5f60a10..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/getconfig/RunningDatastoreQueryStrategy.java +++ /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 queryInstances(ConfigRegistryClient configRegistryClient) { - ObjectName on = transactionProvider.getOrCreateReadTransaction(); - 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/runtimerpc/RuntimeRpc.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpc.java index f7d28b789e..2be3308b90 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpc.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpc.java @@ -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> 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 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 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 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.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 attributes; - private final AttributeIfc returnType; - private final String namespace; - - public NetconfOperationExecution(final ObjectName on, final String name, - final Map 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 sortAttributes( - final Map attributes, final XmlElement xml) { - final Map 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> mBeanEntries, final EnumResolver enumResolver) { - - final Map> map = Maps.newHashMap(); - - for (final Map.Entry> namespaceToModuleEntry : mBeanEntries.entrySet()) { - - Map namespaceToModules = map.get(namespaceToModuleEntry.getKey()); - if (namespaceToModules == null) { - namespaceToModules = Maps.newHashMap(); - map.put(namespaceToModuleEntry.getKey(), namespaceToModules); - } - - for (final Map.Entry 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 index 4bf469d7e6..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpcElementResolved.java +++ /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 additionalAttributes; - - private RuntimeRpcElementResolved(String namespace, String moduleName, String instanceName, String runtimeBeanName, - Map 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 getAdditionalAttributes() { - return additionalAttributes; - } - - public String getInstanceName() { - return instanceName; - } - - public String getNamespace() { - return namespace; - } - - public String getRuntimeBeanName() { - return runtimeBeanName; - } - - public ObjectName getObjectName(ModuleRpcs rpcMapping) { - Map 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: - *
-     * /modules/module[name=instanceName][type=moduleType]
-     * 
- * or - *
-     * /a:modules/a:module[a:name=instanceName][a:type=moduleType]
-     * 
- */ - private static final String xpathPatternBlueprint = - "/" + getRegExForPrefixedName(Modules.QNAME.getLocalName())+ "/" + getRegExForPrefixedName(Module.QNAME.getLocalName()) - - + "\\[" - + "(?" + getRegExForPrefixedName(XmlNetconfConstants.TYPE_KEY) + "|" + getRegExForPrefixedName(XmlNetconfConstants.NAME_KEY) + ")" - + "=('|\")?(?[^'\"\\]]+)('|\")?" - + "( and |\\]\\[)" - + "(?" + getRegExForPrefixedName(XmlNetconfConstants.TYPE_KEY) + "|" + getRegExForPrefixedName(XmlNetconfConstants.NAME_KEY) + ")" - + "=('|\")?(?[^'\"\\]]+)('|\")?" - + "\\]" - - + "(?.*)"; - - /** - * 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: - *
-     * /modules/module[name=instanceName and type=moduleType]/inner[key=b]
-     * 
- */ - private static final String additionalPatternBlueprint = getRegExForPrefixedName("(?.+)") + "\\[(?" + getRegExForPrefixedName("(.+)") + ")=('|\")?(?[^'\"\\]]+)('|\")?\\]"; - 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 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 getAdditionalKeys(String elementName, String moduleName) { - HashMap 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; - } - } -} diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/Activator.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/Activator.java index 6f082b7ab1..5d01b8decd 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/Activator.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/Activator.java @@ -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 schemaServiceTrackerCustomizer = new ServiceTrackerCustomizer() { - ServiceTrackerCustomizer customizer = new ServiceTrackerCustomizer() { @Override - public ConfigRegistryLookupThread addingService(ServiceReference 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 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 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 reference, ConfigSubsystemFacadeFactory service) { + LOG.warn("Config manager facade was modified unexpectedly"); } @Override - public void removedService(ServiceReference reference, ConfigRegistryLookupThread configRegistryLookup) { - configRegistryLookup.interrupt(); - if (osgiRegistration != null) { - osgiRegistration.unregister(); - } - osgiRegistration = null; - Activator.this.configRegistryLookup = null; + public void removedService(ServiceReference reference, ConfigSubsystemFacadeFactory service) { + LOG.warn("Config manager facade was removed unexpectedly"); } }; - ServiceTracker listenerTracker = new ServiceTracker<>(context, SchemaContextProvider.class, customizer); - listenerTracker.open(); + ServiceTracker 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 properties = new Hashtable<>(); - properties.put(NetconfConstants.SERVICE_NAME, NetconfConstants.CONFIG_NETCONF_CONNECTOR); - osgiRegistration = context.registerService(NetconfOperationServiceFactory.class, factory, properties); - } + private ServiceRegistration 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 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 index 7efdf5f415..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/EnumResolver.java +++ /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); -} diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationProvider.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationProvider.java index e3fdc056d9..b0a62a04dc 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationProvider.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationProvider.java @@ -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 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 getOperations() { return operations; } - private static Set setUpOperations(YangStoreContext yangStoreSnapshot, - ConfigRegistryClient configRegistryClient, TransactionProvider transactionProvider, + private static Set setUpOperations(final ConfigSubsystemFacade configSubsystemFacade, String netconfSessionIdForReporting) { Set ops = Sets.newHashSet(); - GetConfig getConfigOp = new GetConfig(yangStoreSnapshot, Optional. absent(), transactionProvider, - configRegistryClient, netconfSessionIdForReporting); + GetConfig getConfigOp = new GetConfig(configSubsystemFacade, Optional. 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; } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationServiceFactoryImpl.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationServiceFactoryImpl.java index cb9c956b90..6ea628d019 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationServiceFactoryImpl.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationServiceFactoryImpl.java @@ -8,100 +8,56 @@ 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 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 added, Set removed) { + listener.onCapabilitiesChanged( + transformModulesToCapabilities(added), transformModulesToCapabilities(removed)); + } + }); } - public static Set setupCapabilities(final YangStoreContext yangStoreSnapshot) { - Set 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 modules = yangStoreSnapshot.getModules(); - for (Module module : modules) { - capabilities.add(new YangModuleCapability(module, yangStoreSnapshot.getModuleSource(module))); + private static final Function MODULE_TO_CAPABILITY = new Function() { + @Override + public Capability apply(final Module module) { + return new YangModuleCapability(module, module.getSource()); } + }; - return capabilities; + public static Set transformModulesToCapabilities(Set modules) { + return Sets.newHashSet(Collections2.transform(modules, MODULE_TO_CAPABILITY)); } } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationServiceImpl.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationServiceImpl.java index 28001851cc..17cbbcace0 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationServiceImpl.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationServiceImpl.java @@ -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 index 290912afbb..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/YangStoreContext.java +++ /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> getModuleMXBeanEntryMap(); - - - Map> 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 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 index ad771f99d8..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/YangStoreService.java +++ /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> ref = - new AtomicReference<>(new SoftReference(null)); - - private final AtomicReference> refBindingContext = - new AtomicReference<>(new SoftReference(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 listeners = Collections.synchronizedSet(new HashSet()); - - 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 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> getModuleMXBeanEntryMap() { - return getYangStoreSnapshot().getModuleMXBeanEntryMap(); - } - - @Override - public Map> getQNamesToIdentitiesToModuleMXBeanEntries() { - return getYangStoreSnapshot().getQNamesToIdentitiesToModuleMXBeanEntries(); - } - - @Override - public Set 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(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_TO_CAPABILITY = new Function() { - @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 removed = Sets.difference(previous.getModules(), current.getModules()); - final Sets.SetView 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_TO_URI = new Function() { - @Override - public Uri apply(final Module input) { - return new Uri(new YangModuleCapability(input, input.getSource()).getCapabilityUri()); - } - }; - - static NetconfCapabilityChange computeDiff(final Sets.SetView removed, final Sets.SetView 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.emptyList()); - return netconfCapabilityChangeBuilder.build(); - } - - - /** - * Looks for NetconfNotificationCollector service and publishes base netconf notifications if possible - */ - private static class NotificationCollectorTracker implements ServiceTrackerCustomizer, BaseNetconfNotificationListener, AutoCloseable { - - private final BundleContext context; - private final ServiceTracker 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 reference) { - closePublisherRegistration(); - publisherReg = context.getService(reference).registerBaseNotificationPublisher(); - return null; - } - - @Override - public synchronized void modifiedService(final ServiceReference reference, final NetconfNotificationCollector service) { - closePublisherRegistration(); - publisherReg = context.getService(reference).registerBaseNotificationPublisher(); - } - - @Override - public synchronized void removedService(final ServiceReference 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 index c798da7f76..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/YangStoreSnapshot.java +++ /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> moduleMXBeanEntryMap; - - - private final Map> 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 namespaceToPackageMapping = Maps.newHashMap(); - PackageTranslator packageTranslator = new PackageTranslator(namespaceToPackageMapping); - Map qNamesToSIEs = new HashMap<>(); - Map knownSEITracker = new HashMap<>(); - // create SIE structure qNamesToSIEs - for (Module module : resolveSchemaContext.getModules()) { - String packageName = packageTranslator.getPackageName(module); - Map namesToSIEntries = ServiceInterfaceEntry - .create(module, packageName, knownSEITracker); - for (Entry 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> moduleMXBeanEntryMap = Maps.newHashMap(); - - Map> 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 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> getModuleMXBeanEntryMap() { - return moduleMXBeanEntryMap; - } - - @Override - public Map> getQNamesToIdentitiesToModuleMXBeanEntries() { - return qNamesToIdentitiesToModuleMXBeanEntries; - } - - @Override - public Set getModules() { - final Set 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 moduleSource = schemaContext.getModuleSource(moduleIdentifier); - if(moduleSource.isPresent()) { - return moduleSource.get(); - } else { - try { - return Iterables.find(getModules(), new Predicate() { - @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 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 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 index 7655cb300d..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/transactions/TransactionProvider.java +++ /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 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 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 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 ta = getTransaction(); - - if (ta.isPresent()) { - return ta.get(); - } - candidateTx = configRegistryClient.beginConfig(); - allOpenedTransactions.add(candidateTx); - return candidateTx; - } - - public synchronized ObjectName getOrCreateReadTransaction() { - Optional 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 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 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 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 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 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 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 index 7b286df0f7..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/util/Util.java +++ /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); - } - -} diff --git a/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java b/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java index 388a131a56..9a9f9c5de1 100644 --- a/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java +++ b/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java @@ -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. absent(), transactionProvider, - configRegistryClient, NETCONF_SESSION_ID); + DocumentedException { + GetConfig getConfigOp = new GetConfig(configSubsystemFacade, Optional. 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. absent(), transactionProvider, - configRegistryClient, NETCONF_SESSION_ID); + DocumentedException { + GetConfig getConfigOp = new GetConfig(configSubsystemFacade, Optional. 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 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); diff --git a/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/ServiceTrackerTest.java b/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/ServiceTrackerTest.java index 52b6f677a4..0fc738eb38 100644 --- a/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/ServiceTrackerTest.java +++ b/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/ServiceTrackerTest.java @@ -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 index db21d82119..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleIdentityRefAttributeReadingStrategyTest.java +++ /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> 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("local")); - assertEquals(org.opendaylight.yangtools.yang.common.QName.create(URI.create("namespace"), rev, "local").toString(), read); - - read = key.readElementContent(XmlElement.fromString("a:local")); - assertEquals(org.opendaylight.yangtools.yang.common.QName.create(URI.create("inner"), rev, "local").toString(), read); - - read = key.readElementContent(XmlElement.fromString("local").getOnlyChildElement()); - assertEquals(org.opendaylight.yangtools.yang.common.QName.create(URI.create("namespace"), rev, "local").toString(), read); - } -} diff --git a/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/ValidateTest.java b/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/ValidateTest.java index 89d9061426..f840fe3669 100644 --- a/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/ValidateTest.java +++ b/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/ValidateTest.java @@ -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(""); - 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(""); - 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(""); - 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(""); - 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(""); - 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(">"); - 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(""); - final TransactionProvider transactionProvider = mock(TransactionProvider.class); final Element okElement = XmlUtil.readXmlToElement(""); - 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)); } diff --git a/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigTest.java b/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigTest.java index ad57f897e0..b0b9c75286 100644 --- a/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigTest.java +++ b/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigTest.java @@ -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(""))).when(mock).getConfigElement(); return mock; } diff --git a/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MergeEditConfigStrategyTest.java b/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MergeEditConfigStrategyTest.java index b1877498a9..ab5635603d 100644 --- a/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MergeEditConfigStrategyTest.java +++ b/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MergeEditConfigStrategyTest.java @@ -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(); diff --git a/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/ReplaceEditConfigStrategyTest.java b/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/ReplaceEditConfigStrategyTest.java index 22a3f10547..269555fc3d 100644 --- a/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/ReplaceEditConfigStrategyTest.java +++ b/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/ReplaceEditConfigStrategyTest.java @@ -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 index 6ed2861b85..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpcElementResolvedTest.java +++ /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 additional; - - @Parameterized.Parameters(name = "{index}: parsed({0}) contains moduleName:{1} and instanceName:{2}") - public static Collection 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 index 5691e04b8f..0000000000 --- a/opendaylight/netconf/config-persister-impl/pom.xml +++ /dev/null @@ -1,86 +0,0 @@ - - - 4.0.0 - - - org.opendaylight.controller - netconf-subsystem - 0.4.0-SNAPSHOT - ../ - - config-persister-impl - bundle - ${project.artifactId} - - - - ${project.groupId} - netconf-api - - - ${project.groupId} - netconf-util - - - com.google.guava - guava - - - - org.opendaylight.controller - config-persister-api - - - org.osgi - org.osgi.core - - - org.slf4j - slf4j-api - - - - - ${project.groupId} - netconf-impl - test - - - ${project.groupId} - netconf-util - test-jar - test - - - org.opendaylight.controller - config-persister-directory-xml-adapter - test - - - org.opendaylight.controller - config-persister-file-xml-adapter - test - - - org.opendaylight.yangtools - mockito-configuration - test - - - - - - - org.apache.felix - maven-bundle-plugin - - - org.opendaylight.controller.netconf.persist.impl.osgi.ConfigPersisterActivator - org.opendaylight.controller.config.persister.storage.adapter - - - - - - - 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 index eac58cbd7f..0000000000 --- a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/CapabilityStrippingConfigSnapshotHolder.java +++ /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 capabilities) { - final XmlElement configElement = XmlElement.fromDomElement(snapshot); - configSnapshot = XmlUtil.toString(configElement.getDomElement()); - stripCapabilitiesResult = stripCapabilities(configElement, capabilities); - } - - private static class StripCapabilitiesResult { - private final SortedSet requiredCapabilities, obsoleteCapabilities; - - private StripCapabilitiesResult(SortedSet requiredCapabilities, SortedSet obsoleteCapabilities) { - this.requiredCapabilities = Collections.unmodifiableSortedSet(requiredCapabilities); - this.obsoleteCapabilities = Collections.unmodifiableSortedSet(obsoleteCapabilities); - } - } - - - @VisibleForTesting - static StripCapabilitiesResult stripCapabilities(XmlElement configElement, Set allCapabilitiesFromHello) { - // collect all namespaces - Set foundNamespacesInXML = getNamespaces(configElement); - LOG.trace("All capabilities {}\nFound namespaces in XML {}", allCapabilitiesFromHello, foundNamespacesInXML); - // required are referenced both in xml and hello - SortedSet requiredCapabilities = new TreeSet<>(); - // can be removed - SortedSet 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 getNamespaces(XmlElement element){ - Set result = new HashSet<>(); - for (Entry 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 getCapabilities() { - return stripCapabilitiesResult.requiredCapabilities; - } - - @VisibleForTesting - Set 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 index fe7b3da770..0000000000 --- a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/ConfigPersisterNotificationHandler.java +++ /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 index c41a2f4d16..0000000000 --- a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/ConfigPusherImpl.java +++ /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> queue = new LinkedBlockingQueue>(QUEUE_SIZE); - - public ConfigPusherImpl(NetconfOperationServiceFactory configNetconfConnector, long maxWaitForCapabilitiesMillis, - long conflictingVersionTimeoutMillis) { - this.configNetconfConnector = configNetconfConnector; - this.maxWaitForCapabilitiesMillis = maxWaitForCapabilitiesMillis; - this.conflictingVersionTimeoutMillis = conflictingVersionTimeoutMillis; - } - - public void process(List autoCloseables, MBeanServerConnection platformMBeanServer, Persister persisterAggregator) throws InterruptedException { - List 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 configs) throws InterruptedException { - LOG.debug("Requested to push configs {}", configs); - this.queue.put(configs); - } - - private LinkedHashMap internalPushConfigs(List configs) throws NetconfDocumentedException { - LOG.debug("Last config snapshots to be pushed to netconf: {}", configs); - LinkedHashMap 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 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 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 missingCaps; - - private NotEnoughCapabilitiesException(String message, Set missingCaps) { - super(message); - this.missingCaps = missingCaps; - } - - public Set 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 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 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 computeNotFoundCapabilities(Set expectedCapabilities, NetconfOperationServiceFactory serviceCandidate) { - Collection actual = Collections2.transform(serviceCandidate.getCapabilities(), new Function() { - @Override - public String apply(@Nonnull final Capability input) { - return input.getCapabilityUri(); - } - }); - Set 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 allOperations = new TreeMap<>(); - Set 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 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 index 26e497387a..0000000000 --- a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/NoOpStorageAdapter.java +++ /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 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 index 0c51166fe4..0000000000 --- a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/PersisterAggregator.java +++ /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:
- 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
-
- 
- * 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 persisterWithConfigurations; - - public PersisterAggregator(List persisterWithConfigurations) { - this.persisterWithConfigurations = persisterWithConfigurations; - - } - - public static PersisterAggregator createFromProperties(PropertiesProvider propertiesProvider) { - List 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 loadLastConfigs() { - // iterate in reverse order - ListIterator li = persisterWithConfigurations.listIterator(persisterWithConfigurations.size()); - while(li.hasPrevious()) { - PersisterWithConfiguration persisterWithConfiguration = li.previous(); - List 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 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 index 238661f638..0000000000 --- a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/PropertiesProviderAdapterImpl.java +++ /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 index b27bec3c83..0000000000 --- a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/osgi/ConfigPersisterActivator.java +++ /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 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 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 { - private final BundleContext context; - private final InnerCustomizer innerCustomizer; - - OuterCustomizer(BundleContext context, InnerCustomizer innerCustomizer) { - this.context = context; - this.innerCustomizer = innerCustomizer; - } - - @Override - public NetconfOperationServiceFactory addingService(ServiceReference 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 reference, NetconfOperationServiceFactory service) { - - } - - @Override - public void removedService(ServiceReference reference, NetconfOperationServiceFactory service) { - - } - } - - class InnerCustomizer implements ServiceTrackerCustomizer { - private final List 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 configs, long maxWaitForCapabilitiesMillis, long conflictingVersionTimeoutMillis, - PersisterAggregator persisterAggregator) { - this.configs = configs; - this.maxWaitForCapabilitiesMillis = maxWaitForCapabilitiesMillis; - this.conflictingVersionTimeoutMillis = conflictingVersionTimeoutMillis; - this.persisterAggregator = persisterAggregator; - } - - @Override - public NetconfOperationServiceFactory addingService(ServiceReference 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 reference, NetconfOperationServiceFactory service) { - LOG.trace("Got InnerCustomizer.modifiedService {}", reference); - } - - @Override - public void removedService(ServiceReference 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 index d73f3b801e..0000000000 --- a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/osgi/PropertiesProviderBaseImpl.java +++ /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 index b1f783343d..0000000000 --- a/opendaylight/netconf/config-persister-impl/src/main/resources/netconfOp/client_hello.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - urn:ietf:params:netconf:base:1.0 - - 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 index ae1f6e87fa..0000000000 --- a/opendaylight/netconf/config-persister-impl/src/main/resources/netconfOp/commit.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - \ 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 index 8f6ec9c4c2..0000000000 --- a/opendaylight/netconf/config-persister-impl/src/main/resources/netconfOp/editConfig.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - merge - - - - - - \ 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 index 554e13487b..0000000000 --- a/opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/CapabilityStrippingConfigSnapshotHolderTest.java +++ /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 allCapabilities = readLines("/capabilities-all.txt"); - Set 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 obsoleteCapabilities = Sets.difference(allCapabilities, expectedCapabilities); - - assertEquals(obsoleteCapabilities, tested.getObsoleteCapabilities()); - } - - private Set 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 index e96b547169..0000000000 --- a/opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/ConfigPersisterNotificationHandlerTest.java +++ /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 index f0cd267dd6..0000000000 --- a/opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/ConfigPersisterNotificationListenerTest.java +++ /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("")).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 index 792f8cd1c0..0000000000 --- a/opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/DummyAdapter.java +++ /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 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 index c962a46bb1..0000000000 --- a/opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/PersisterAggregatorTest.java +++ /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 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 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 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 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 index b998b9eff0..0000000000 --- a/opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/osgi/ConfigPersisterTest.java +++ /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( - "\n" + - "\n" + - "" - ); - } - - - @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 index bd18c8c30e..0000000000 --- a/opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/osgi/MockedBundleContext.java +++ /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 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 "<" + CONFIG_SNAPSHOT + "/>"; - } - - @Override - public SortedSet getCapabilities() { - TreeSet 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 index fcd39d6ae6..0000000000 --- a/opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/osgi/TestingExceptionHandler.java +++ /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 exType, String exMessageToContain) { - assertException(exMessageToContain, exType, exMessageToContain); - } - - public void assertException(String failMessageSuffix, Class 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 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 exType, - String exMessageToContain, Class 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 index 84c85b740c..0000000000 --- a/opendaylight/netconf/config-persister-impl/src/test/resources/capabilities-all.txt +++ /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 index 4a0b7ffffd..0000000000 --- a/opendaylight/netconf/config-persister-impl/src/test/resources/capabilities-stripped.txt +++ /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 index a4ff3abe49..0000000000 --- a/opendaylight/netconf/config-persister-impl/src/test/resources/logback-test.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - %date{"yyyy-MM-dd HH:mm:ss.SSS z"} [%thread] %-5level %logger{36} - %msg%n - - - - - - - - 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 index a6a57d704a..0000000000 --- a/opendaylight/netconf/config-persister-impl/src/test/resources/snapshot.xml +++ /dev/null @@ -1,103 +0,0 @@ - - - - prefix:schema-service-singleton - yang-schema-service - - - prefix:hash-map-data-store - hash-map-data-store - - - prefix:dom-broker-impl - dom-broker - - dom:dom-data-store - ref_hash-map-data-store - - - - prefix:binding-broker-impl - binding-broker-impl - - binding:binding-notification-service - ref_binding-notification-broker - - - binding:binding-data-broker - ref_binding-data-broker - - - - prefix:runtime-generated-mapping - runtime-mapping-singleton - - - prefix:binding-notification-broker - binding-notification-broker - - - prefix:binding-data-broker - binding-data-broker - - dom:dom-broker-osgi-registry - ref_dom-broker - - - binding:binding-dom-mapping-service - ref_runtime-mapping-singleton - - - - - - dom:schema-service - - ref_yang-schema-service - /config/modules/module[name='schema-service-singleton']/instance[name='yang-schema-service'] - - - - binding:binding-notification-service - - ref_binding-notification-broker - /config/modules/module[name='binding-notification-broker']/instance[name='binding-notification-broker'] - - - - dom:dom-data-store - - ref_hash-map-data-store - /config/modules/module[name='hash-map-data-store']/instance[name='hash-map-data-store'] - - - - binding:binding-broker-osgi-registry - - ref_binding-broker-impl - /config/modules/module[name='binding-broker-impl']/instance[name='binding-broker-impl'] - - - - binding-impl:binding-dom-mapping-service - - ref_runtime-mapping-singleton - /config/modules/module[name='runtime-generated-mapping']/instance[name='runtime-mapping-singleton'] - - - - dom:dom-broker-osgi-registry - - ref_dom-broker - /config/modules/module[name='dom-broker-impl']/instance[name='dom-broker'] - - - - binding:binding-data-broker - - ref_binding-data-broker - /config/modules/module[name='binding-data-broker']/instance[name='binding-data-broker'] - - - - 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 index 851c5996d3..0000000000 --- a/opendaylight/netconf/config-persister-impl/src/test/resources/test1.properties +++ /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 index 729c67d6c5..0000000000 --- a/opendaylight/netconf/config-persister-impl/src/test/resources/test2.properties +++ /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 index 90ba77273b..0000000000 --- a/opendaylight/netconf/config-persister-impl/src/test/resources/test3.properties +++ /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 index 0000000000..731266c6d5 --- /dev/null +++ b/opendaylight/netconf/features/netconf-connector/pom.xml @@ -0,0 +1,180 @@ + + + 4.0.0 + + org.opendaylight.controller + netconf-subsystem + 0.4.0-SNAPSHOT + ../../ + + features-netconf-connector + + + ${mdsal.version} + jar + + features.xml + + + + org.opendaylight.yangtools + features-yangtools + ${yangtools.version} + features + xml + + + org.opendaylight.controller + features-mdsal + ${mdsal.version} + features + xml + + + org.opendaylight.controller + features-netconf + features + xml + + + org.opendaylight.aaa + features-aaa + ${aaa.version} + features + xml + + + org.opendaylight.controller + sal-netconf-connector + + + org.opendaylight.controller.model + model-inventory + + + org.opendaylight.controller + netconf-config-dispatcher + + + org.opendaylight.controller + netconf-tcp + + + org.opendaylight.controller + netconf-ssh + + + org.bouncycastle + bcpkix-jdk15on + + + org.bouncycastle + bcprov-jdk15on + + + + org.opendaylight.controller + netconf-connector-config + ${netconf.version} + xml + config + + + + + + + org.opendaylight.odlparent + features-test + test + + + + org.opendaylight.controller + opendaylight-karaf-empty + ${commons.opendaylight.version} + zip + + + + + + + + src/main/resources + true + + + + + org.apache.maven.plugins + maven-resources-plugin + + + filter + generate-resources + + resources + + + + + + org.codehaus.mojo + build-helper-maven-plugin + + + attach-artifacts + package + + attach-artifact + + + + + ${project.build.directory}/classes/${features.file} + xml + features + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + org.opendaylight.controller + opendaylight-karaf-empty + ${commons.opendaylight.version} + + + org.opendaylight.odlparent:features-test + + + + + + + scm:git:http://git.opendaylight.org/gerrit/controller.git + scm:git:ssh://git.opendaylight.org:29418/controller.git + HEAD + https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=summary + + 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 index 0000000000..70cbb4e0ea --- /dev/null +++ b/opendaylight/netconf/features/netconf-connector/src/main/resources/features.xml @@ -0,0 +1,36 @@ + + + + + mvn:org.opendaylight.controller/features-mdsal/${mdsal.version}/xml/features + mvn:org.opendaylight.yangtools/features-yangtools/${yangtools.version}/xml/features + mvn:org.opendaylight.controller/features-netconf/${netconf.version}/xml/features + + + odl-netconf-connector + odl-netconf-connector-ssh + + + + odl-mdsal-broker + odl-netconf-client + odl-yangtools-models + mvn:org.opendaylight.controller/sal-netconf-connector/${project.version} + mvn:org.opendaylight.controller.model/model-inventory/${mdsal.version} + + + + odl-netconf-ssh + odl-netconf-connector + mvn:org.opendaylight.controller/netconf-connector-config/${netconf.version}/xml/config + + + diff --git a/opendaylight/netconf/features/netconf/pom.xml b/opendaylight/netconf/features/netconf/pom.xml new file mode 100644 index 0000000000..90b4851c7e --- /dev/null +++ b/opendaylight/netconf/features/netconf/pom.xml @@ -0,0 +1,267 @@ + + + 4.0.0 + + org.opendaylight.controller + netconf-subsystem + 0.4.0-SNAPSHOT + ../../ + + features-netconf + + jar + + + features.xml + + + + + + org.opendaylight.aaa + features-aaa + ${aaa.version} + features + xml + + + org.opendaylight.controller + features-config + features + xml + runtime + + + org.opendaylight.controller + features-protocol-framework + features + xml + runtime + + + org.opendaylight.controller + features-config-persister + features + xml + runtime + + + org.opendaylight.controller + netconf-api + + + org.opendaylight.controller + netconf-config + + + org.opendaylight.controller + netconf-auth + + + org.opendaylight.controller + netconf-notifications-api + + + org.opendaylight.controller + netconf-notifications-impl + + + org.opendaylight.controller + ietf-netconf + + + org.opendaylight.controller + ietf-netconf-monitoring + + + org.opendaylight.controller + ietf-netconf-monitoring-extension + + + org.opendaylight.controller + ietf-netconf-notifications + + + org.opendaylight.yangtools.model + ietf-inet-types + + + org.opendaylight.yangtools.model + ietf-yang-types + + + org.opendaylight.yangtools + yang-model-api + + + org.opendaylight.controller + netconf-mapping-api + + + org.opendaylight.controller + netconf-util + + + org.opendaylight.controller + netconf-impl + + + org.opendaylight.controller + config-manager-facade-xml + ${config.version} + + + org.opendaylight.controller + config-netconf-connector + + + org.opendaylight.controller + netconf-netty-util + + + org.apache.sshd + sshd-core + + + openexi + nagasena + + + io.netty + netty-codec + + + io.netty + netty-handler + + + io.netty + netty-common + + + io.netty + netty-buffer + + + io.netty + netty-transport + + + org.opendaylight.controller + netconf-client + + + org.opendaylight.controller + netconf-config + ${config.version} + xml + config + + + org.opendaylight.controller + netconf-connector-config + ${netconf.version} + xml + config + + + org.opendaylight.controller + netconf-monitoring + + + org.opendaylight.controller + mdsal-netconf-monitoring + + + org.opendaylight.controller + mdsal-netconf-connector + + + org.opendaylight.controller + netconf-mdsal-config + config + xml + + + + org.opendaylight.odlparent + features-test + test + + + + org.opendaylight.controller + opendaylight-karaf-empty + ${commons.opendaylight.version} + zip + + + + + + + true + src/main/resources + + + + + org.apache.maven.plugins + maven-resources-plugin + + + filter + + resources + + generate-resources + + + + + org.codehaus.mojo + build-helper-maven-plugin + + + attach-artifacts + + attach-artifact + + package + + + + ${project.build.directory}/classes/${features.file} + xml + features + + + + + + + + + + + + + + + + + + + + + + + + + + scm:git:http://git.opendaylight.org/gerrit/controller.git + scm:git:ssh://git.opendaylight.org:29418/controller.git + HEAD + https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL + + 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 index 0000000000..ab38cef3b4 --- /dev/null +++ b/opendaylight/netconf/features/netconf/src/main/resources/features.xml @@ -0,0 +1,145 @@ + + + + mvn:org.opendaylight.controller/features-protocol-framework/${protocol-framework.version}/xml/features + mvn:org.opendaylight.controller/features-config/${config.version}/xml/features + mvn:org.opendaylight.controller/features-config-persister/${config.version}/xml/features + + mvn:org.opendaylight.aaa/features-aaa/${aaa.version}/xml/features + + + odl-netconf-api + odl-netconf-mapping-api + odl-netconf-util + odl-netconf-impl + odl-config-netconf-connector + odl-netconf-netty-util + odl-netconf-client + odl-netconf-monitoring + + + + odl-protocol-framework + mvn:org.opendaylight.yangtools/yang-model-api/${yangtools.version} + mvn:org.opendaylight.controller/config-util/${config.version} + mvn:org.opendaylight.controller/netconf-api/${project.version} + mvn:org.opendaylight.controller/netconf-auth/${project.version} + mvn:org.opendaylight.controller/ietf-netconf-monitoring/${project.version} + mvn:org.opendaylight.controller/ietf-netconf/${project.version} + mvn:org.opendaylight.controller/ietf-netconf-notifications/${project.version} + mvn:org.opendaylight.controller/ietf-netconf-monitoring-extension/${project.version} + mvn:org.opendaylight.yangtools.model/ietf-inet-types/${ietf-inet-types.version} + mvn:org.opendaylight.yangtools.model/ietf-yang-types/${ietf-yang-types.version} + mvn:org.opendaylight.yangtools.model/ietf-yang-types-20130715/2013.07.15.8-SNAPSHOT + + + + odl-netconf-api + mvn:org.opendaylight.controller/netconf-mapping-api/${project.version} + + + + odl-netconf-mapping-api + mvn:org.opendaylight.yangtools/yang-model-api/${yangtools.version} + mvn:org.opendaylight.yangtools/yang-data-api/${yangtools.version} + mvn:org.opendaylight.controller/netconf-util/${project.version} + + + + mvn:org.opendaylight.controller/yang-jmx-generator/${project.version} + odl-netconf-api + odl-netconf-mapping-api + odl-netconf-util + odl-netconf-netty-util + + odl-config-netconf-connector + + mvn:org.opendaylight.controller/config-manager-facade-xml/${project.version} + odl-netconf-monitoring + odl-netconf-notifications-impl + mvn:org.opendaylight.controller/netconf-impl/${project.version} + + + + mvn:org.opendaylight.controller/yang-jmx-generator/${project.version} + mvn:org.opendaylight.controller/config-manager-facade-xml/${project.version} + odl-config-manager + odl-netconf-netty-util + mvn:org.opendaylight.controller/netconf-impl/${project.version} + odl-netconf-notifications-api + mvn:org.opendaylight.controller/netconf-notifications-impl/${project.version} + mvn:org.opendaylight.controller/config-netconf-connector/${project.version} + + + + odl-netconf-api + odl-netconf-mapping-api + odl-netconf-util + mvn:org.opendaylight.controller/netconf-netty-util/${project.version} + mvn:org.bouncycastle/bcpkix-jdk15on/${bouncycastle.version} + mvn:org.bouncycastle/bcprov-jdk15on/${bouncycastle.version} + mvn:org.apache.sshd/sshd-core/${sshd-core.version} + mvn:openexi/nagasena/${exi.nagasena.version} + mvn:io.netty/netty-codec/${netty.version} + mvn:io.netty/netty-handler/${netty.version} + mvn:io.netty/netty-common/${netty.version} + mvn:io.netty/netty-buffer/${netty.version} + mvn:io.netty/netty-transport/${netty.version} + + + + odl-config-all + odl-netconf-netty-util + mvn:org.opendaylight.controller/netconf-client/${project.version} + mvn:org.opendaylight.controller/netconf-config-dispatcher/${config.version} + mvn:org.opendaylight.controller/netconf-config/${project.version}/xml/config + + + + odl-netconf-util + mvn:org.opendaylight.controller/netconf-monitoring/${project.version} + + + + odl-config-manager-facade-xml + odl-netconf-api + mvn:org.opendaylight.controller/netconf-notifications-api/${project.version} + + + + odl-netconf-notifications-api + odl-netconf-util + mvn:org.opendaylight.controller/netconf-notifications-impl/${project.version} + + + + odl-netconf-tcp + + odl-aaa-netconf-plugin + mvn:org.opendaylight.controller/netconf-ssh/${project.version} + + + + odl-netconf-impl + odl-config-netty + mvn:org.opendaylight.controller/netconf-tcp/${project.version} + + + + odl-config-all + odl-netconf-all + odl-netconf-tcp + odl-netconf-ssh + odl-netconf-client + odl-mdsal-broker + mvn:org.opendaylight.controller/mdsal-netconf-connector/${project.version} + mvn:org.opendaylight.controller/mdsal-netconf-monitoring/${project.version} + mvn:org.opendaylight.controller/netconf-mdsal-config/${project.version}/xml/config + + diff --git a/opendaylight/netconf/features/pom.xml b/opendaylight/netconf/features/pom.xml new file mode 100644 index 0000000000..55b9bc239b --- /dev/null +++ b/opendaylight/netconf/features/pom.xml @@ -0,0 +1,17 @@ + + + 4.0.0 + + org.opendaylight.controller + netconf-subsystem + 0.4.0-SNAPSHOT + ../ + + features-netconf-parent + pom + + + netconf + netconf-connector + + diff --git a/opendaylight/netconf/mdsal-netconf-connector/pom.xml b/opendaylight/netconf/mdsal-netconf-connector/pom.xml index fc9ae83457..14b0b69dfe 100644 --- a/opendaylight/netconf/mdsal-netconf-connector/pom.xml +++ b/opendaylight/netconf/mdsal-netconf-connector/pom.xml @@ -109,41 +109,9 @@ - org.opendaylight.yangtools yang-maven-plugin - - - config - - generate-sources - - - - - org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator - ${jmxGeneratorPath} - - urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang - - - - org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl - ${salGeneratorPath} - - - true - - - - - - org.opendaylight.controller - yang-jmx-generator-plugin - ${config.version} - - diff --git a/opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/CurrentSchemaContext.java b/opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/CurrentSchemaContext.java index 1aa38eb80c..c947027f74 100644 --- a/opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/CurrentSchemaContext.java +++ b/opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/CurrentSchemaContext.java @@ -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 currentContext = new AtomicReference(); private final ListenerRegistration schemaContextListenerListenerRegistration; - private final Set listeners = Collections.synchronizedSet(Sets.newHashSet()); + private final Set listeners1 = Collections.synchronizedSet(Sets.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 addedCaps = MdsalNetconfOperationServiceFactory.transformCapabilities(currentContext.get()); - for (final CapabilityListener listener : listeners) { - listener.onCapabilitiesAdded(addedCaps); + for (final CapabilityListener listener : listeners1) { + listener.onCapabilitiesChanged(addedCaps, Collections.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.emptySet()); + listeners1.add(listener); return new AutoCloseable() { @Override public void close() throws Exception { - listeners.remove(listener); + listeners1.remove(listener); } }; } diff --git a/opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/MdsalNetconfOperationServiceFactory.java b/opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/MdsalNetconfOperationServiceFactory.java index 96244fdc68..4cb9bdb006 100644 --- a/opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/MdsalNetconfOperationServiceFactory.java +++ b/opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/MdsalNetconfOperationServiceFactory.java @@ -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 transformCapabilities(final SchemaContext currentContext) { final Set 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 modules = currentContext.getModules(); for (final Module module : modules) { diff --git a/opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/TransactionProvider.java b/opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/TransactionProvider.java index f1b214b83e..eddd08b112 100644 --- a/opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/TransactionProvider.java +++ b/opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/TransactionProvider.java @@ -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 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); } diff --git a/opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/ops/Commit.java b/opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/ops/Commit.java index 47e8f80585..bc8abc5d75 100644 --- a/opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/ops/Commit.java +++ b/opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/ops/Commit.java @@ -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); diff --git a/opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/ops/DiscardChanges.java b/opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/ops/DiscardChanges.java index ce4de18ee6..f575197b59 100644 --- a/opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/ops/DiscardChanges.java +++ b/opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/ops/DiscardChanges.java @@ -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.absent()); diff --git a/opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/ops/EditConfig.java b/opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/ops/EditConfig.java index 914ff20006..889068940e 100644 --- a/opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/ops/EditConfig.java +++ b/opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/ops/EditConfig.java @@ -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.absent()); } - private void executeOperations(final DataTreeChangeTracker changeTracker) throws NetconfDocumentedException { + private void executeOperations(final DataTreeChangeTracker changeTracker) throws DocumentedException { final DOMDataReadWriteTransaction rwTx = transactionProvider.getOrCreateTransaction(); final List aa = changeTracker.getDataTreeChanges(); final ListIterator 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> 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> 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 getSchemaNodeFromNamespace(final String namespace, final XmlElement element) throws NetconfDocumentedException{ + private Optional getSchemaNodeFromNamespace(final String namespace, final XmlElement element) throws DocumentedException{ Optional 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 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); diff --git a/opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/ops/Lock.java b/opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/ops/Lock.java index 252f4a637f..22fe064885 100644 --- a/opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/ops/Lock.java +++ b/opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/ops/Lock.java @@ -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.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()); diff --git a/opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/ops/RuntimeRpc.java b/opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/ops/RuntimeRpc.java index 51f9e220c5..0c35b89800 100644 --- a/opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/ops/RuntimeRpc.java +++ b/opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/ops/RuntimeRpc.java @@ -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 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 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 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); diff --git a/opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/ops/Unlock.java b/opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/ops/Unlock.java index 634be3e22f..4cea4cbdeb 100644 --- a/opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/ops/Unlock.java +++ b/opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/ops/Unlock.java @@ -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.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 diff --git a/opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/ops/get/AbstractGet.java b/opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/ops/get/AbstractGet.java index d028a89e36..21372f8e45 100644 --- a/opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/ops/get/AbstractGet.java +++ b/opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/ops/get/AbstractGet.java @@ -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 container in the response. * if filter is not present we want to read the entire datastore - return ROOT. - * @throws NetconfDocumentedException + * @throws DocumentedException */ - protected Optional getDataRootFromFilter(XmlElement operationElement) throws NetconfDocumentedException { + protected Optional getDataRootFromFilter(XmlElement operationElement) throws DocumentedException { Optional 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 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 parseSource(final XmlElement xml) throws NetconfDocumentedException { + private static Optional parseSource(final XmlElement xml) throws DocumentedException { final Optional 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.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); } diff --git a/opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/ops/get/Get.java b/opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/ops/get/Get.java index 1daccd265c..41d488aee9 100644 --- a/opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/ops/get/Get.java +++ b/opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/ops/get/Get.java @@ -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 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 diff --git a/opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/ops/get/GetConfig.java b/opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/ops/get/GetConfig.java index 955666f2fe..5f36ca5a30 100644 --- a/opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/ops/get/GetConfig.java +++ b/opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/ops/get/GetConfig.java @@ -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 diff --git a/opendaylight/netconf/mdsal-netconf-connector/src/test/java/org/opendaylight/controller/netconf/mdsal/connector/ops/NetconfMDSalMappingTest.java b/opendaylight/netconf/mdsal-netconf-connector/src/test/java/org/opendaylight/controller/netconf/mdsal/connector/ops/NetconfMDSalMappingTest.java index 1b680368aa..3e17c16679 100644 --- a/opendaylight/netconf/mdsal-netconf-connector/src/test/java/org/opendaylight/controller/netconf/mdsal/connector/ops/NetconfMDSalMappingTest.java +++ b/opendaylight/netconf/mdsal-netconf-connector/src/test/java/org/opendaylight/controller/netconf/mdsal/connector/ops/NetconfMDSalMappingTest.java @@ -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); diff --git a/opendaylight/netconf/mdsal-netconf-connector/src/test/java/org/opendaylight/controller/netconf/mdsal/connector/ops/RuntimeRpcTest.java b/opendaylight/netconf/mdsal-netconf-connector/src/test/java/org/opendaylight/controller/netconf/mdsal/connector/ops/RuntimeRpcTest.java index aa6ff06c5f..02a9514651 100644 --- a/opendaylight/netconf/mdsal-netconf-connector/src/test/java/org/opendaylight/controller/netconf/mdsal/connector/ops/RuntimeRpcTest.java +++ b/opendaylight/netconf/mdsal-netconf-connector/src/test/java/org/opendaylight/controller/netconf/mdsal/connector/ops/RuntimeRpcTest.java @@ -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); diff --git a/opendaylight/netconf/mdsal-netconf-monitoring/pom.xml b/opendaylight/netconf/mdsal-netconf-monitoring/pom.xml index 04585e1833..b02a6d291c 100644 --- a/opendaylight/netconf/mdsal-netconf-monitoring/pom.xml +++ b/opendaylight/netconf/mdsal-netconf-monitoring/pom.xml @@ -61,37 +61,6 @@ org.opendaylight.yangtools yang-maven-plugin - - - config - - generate-sources - - - - - org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator - ${jmxGeneratorPath} - - urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang - - - - org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl - ${salGeneratorPath} - - - true - - - - - - org.opendaylight.controller - yang-jmx-generator-plugin - ${config.version} - - diff --git a/opendaylight/netconf/mdsal-netconf-monitoring/src/main/java/org/opendaylight/controller/config/yang/netconf/mdsal/monitoring/NetconfMdsalMonitoringMapperModule.java b/opendaylight/netconf/mdsal-netconf-monitoring/src/main/java/org/opendaylight/controller/config/yang/netconf/mdsal/monitoring/NetconfMdsalMonitoringMapperModule.java index 3c73c2c84c..8256627d01 100644 --- a/opendaylight/netconf/mdsal-netconf-monitoring/src/main/java/org/opendaylight/controller/config/yang/netconf/mdsal/monitoring/NetconfMdsalMonitoringMapperModule.java +++ b/opendaylight/netconf/mdsal-netconf-monitoring/src/main/java/org/opendaylight/controller/config/yang/netconf/mdsal/monitoring/NetconfMdsalMonitoringMapperModule.java @@ -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; diff --git a/opendaylight/netconf/mdsal-netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/NetconfMonitoringOperationServiceFactory.java b/opendaylight/netconf/mdsal-netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/NetconfMonitoringOperationServiceFactory.java index cac15044f0..b959fa5c52 100644 --- a/opendaylight/netconf/mdsal-netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/NetconfMonitoringOperationServiceFactory.java +++ b/opendaylight/netconf/mdsal-netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/NetconfMonitoringOperationServiceFactory.java @@ -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; diff --git a/opendaylight/netconf/ietf-netconf-monitoring-extension/pom.xml b/opendaylight/netconf/models/ietf-netconf-monitoring-extension/pom.xml 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 760261b1e4..0824b750fc 100644 --- a/opendaylight/netconf/ietf-netconf-monitoring-extension/pom.xml +++ b/opendaylight/netconf/models/ietf-netconf-monitoring-extension/pom.xml @@ -3,7 +3,7 @@ 4.0.0 org.opendaylight.controller - netconf-subsystem + netconf-models 0.4.0-SNAPSHOT ietf-netconf-monitoring-extension diff --git a/opendaylight/netconf/ietf-netconf-monitoring-extension/src/main/yang/ietf-netconf-monitoring-extension.yang b/opendaylight/netconf/models/ietf-netconf-monitoring-extension/src/main/yang/ietf-netconf-monitoring-extension.yang similarity index 100% rename from opendaylight/netconf/ietf-netconf-monitoring-extension/src/main/yang/ietf-netconf-monitoring-extension.yang rename to opendaylight/netconf/models/ietf-netconf-monitoring-extension/src/main/yang/ietf-netconf-monitoring-extension.yang diff --git a/opendaylight/netconf/ietf-netconf-monitoring/pom.xml b/opendaylight/netconf/models/ietf-netconf-monitoring/pom.xml similarity index 97% rename from opendaylight/netconf/ietf-netconf-monitoring/pom.xml rename to opendaylight/netconf/models/ietf-netconf-monitoring/pom.xml index e4819c0a44..68b5558acc 100644 --- a/opendaylight/netconf/ietf-netconf-monitoring/pom.xml +++ b/opendaylight/netconf/models/ietf-netconf-monitoring/pom.xml @@ -3,7 +3,7 @@ 4.0.0 org.opendaylight.controller - netconf-subsystem + netconf-models 0.4.0-SNAPSHOT ietf-netconf-monitoring diff --git a/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 b/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 similarity index 100% rename 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 rename to 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 diff --git a/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 b/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 similarity index 100% rename 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 rename to 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 diff --git a/opendaylight/netconf/ietf-netconf-monitoring/src/main/yang/ietf-netconf-monitoring.yang b/opendaylight/netconf/models/ietf-netconf-monitoring/src/main/yang/ietf-netconf-monitoring.yang similarity index 100% rename from opendaylight/netconf/ietf-netconf-monitoring/src/main/yang/ietf-netconf-monitoring.yang rename to opendaylight/netconf/models/ietf-netconf-monitoring/src/main/yang/ietf-netconf-monitoring.yang diff --git a/opendaylight/netconf/ietf-netconf-notifications/pom.xml b/opendaylight/netconf/models/ietf-netconf-notifications/pom.xml similarity index 97% rename from opendaylight/netconf/ietf-netconf-notifications/pom.xml rename to opendaylight/netconf/models/ietf-netconf-notifications/pom.xml index 763cb82c36..f223634000 100644 --- a/opendaylight/netconf/ietf-netconf-notifications/pom.xml +++ b/opendaylight/netconf/models/ietf-netconf-notifications/pom.xml @@ -11,7 +11,7 @@ 4.0.0 org.opendaylight.controller - netconf-subsystem + netconf-models 0.4.0-SNAPSHOT ietf-netconf-notifications diff --git a/opendaylight/netconf/ietf-netconf-notifications/src/main/yang/ietf-netconf-notifications@2012-02-06.yang b/opendaylight/netconf/models/ietf-netconf-notifications/src/main/yang/ietf-netconf-notifications@2012-02-06.yang similarity index 100% rename from opendaylight/netconf/ietf-netconf-notifications/src/main/yang/ietf-netconf-notifications@2012-02-06.yang rename to opendaylight/netconf/models/ietf-netconf-notifications/src/main/yang/ietf-netconf-notifications@2012-02-06.yang diff --git a/opendaylight/netconf/ietf-netconf-notifications/src/main/yang/nc-notifications@2008-07-14.yang b/opendaylight/netconf/models/ietf-netconf-notifications/src/main/yang/nc-notifications@2008-07-14.yang similarity index 100% rename from opendaylight/netconf/ietf-netconf-notifications/src/main/yang/nc-notifications@2008-07-14.yang rename to opendaylight/netconf/models/ietf-netconf-notifications/src/main/yang/nc-notifications@2008-07-14.yang diff --git a/opendaylight/netconf/ietf-netconf-notifications/src/main/yang/notifications@2008-07-14.yang b/opendaylight/netconf/models/ietf-netconf-notifications/src/main/yang/notifications@2008-07-14.yang similarity index 100% rename from opendaylight/netconf/ietf-netconf-notifications/src/main/yang/notifications@2008-07-14.yang rename to opendaylight/netconf/models/ietf-netconf-notifications/src/main/yang/notifications@2008-07-14.yang diff --git a/opendaylight/netconf/ietf-netconf/pom.xml b/opendaylight/netconf/models/ietf-netconf/pom.xml similarity index 97% rename from opendaylight/netconf/ietf-netconf/pom.xml rename to opendaylight/netconf/models/ietf-netconf/pom.xml index 43ba3b17aa..f2db7577ea 100644 --- a/opendaylight/netconf/ietf-netconf/pom.xml +++ b/opendaylight/netconf/models/ietf-netconf/pom.xml @@ -11,7 +11,7 @@ 4.0.0 org.opendaylight.controller - netconf-subsystem + netconf-models 0.4.0-SNAPSHOT ietf-netconf diff --git a/opendaylight/netconf/ietf-netconf/src/main/yang/ietf-netconf@2011-06-01.yang b/opendaylight/netconf/models/ietf-netconf/src/main/yang/ietf-netconf@2011-06-01.yang similarity index 100% rename from opendaylight/netconf/ietf-netconf/src/main/yang/ietf-netconf@2011-06-01.yang rename to opendaylight/netconf/models/ietf-netconf/src/main/yang/ietf-netconf@2011-06-01.yang diff --git a/opendaylight/netconf/models/pom.xml b/opendaylight/netconf/models/pom.xml new file mode 100644 index 0000000000..bf87e428b5 --- /dev/null +++ b/opendaylight/netconf/models/pom.xml @@ -0,0 +1,78 @@ + + + 4.0.0 + + + org.opendaylight.controller + netconf-subsystem + 0.4.0-SNAPSHOT + + netconf-models + + 0.4.0-SNAPSHOT + pom + ${project.artifactId} + + + ietf-netconf + ietf-netconf-monitoring + ietf-netconf-notifications + ietf-netconf-monitoring-extension + + + + + + + org.apache.felix + maven-bundle-plugin + true + + + ${project.groupId}.${project.artifactId} + + + + + org.opendaylight.yangtools + yang-maven-plugin + + + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + + false + true + checkstyle-logging.xml + true + true + ${project.basedir} + **\/*.java,**\/*.xml,**\/*.ini,**\/*.sh,**\/*.bat,**\/*.yang + **\/target\/,**\/bin\/,**\/target-ide\/,**\/${jmxGeneratorPath}\/,**\/${salGeneratorPath}\/,**\/netconf\/test\/tool\/Main.java, **\/netconf\/test\/tool\/client\/stress\/StressClient.java + + + + org.opendaylight.yangtools + checkstyle-logging + ${yangtools.version} + + + + + + check + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + diff --git a/opendaylight/netconf/netconf-api/pom.xml b/opendaylight/netconf/netconf-api/pom.xml index d1c2af36ff..6b5299111d 100644 --- a/opendaylight/netconf/netconf-api/pom.xml +++ b/opendaylight/netconf/netconf-api/pom.xml @@ -24,6 +24,10 @@ org.opendaylight.controller config-api + + org.opendaylight.controller + config-manager-facade-xml + org.opendaylight.controller protocol-framework @@ -47,37 +51,6 @@ org.opendaylight.yangtools yang-maven-plugin - - - config - - generate-sources - - - - - org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator - ${jmxGeneratorPath} - - urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang - - - - org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl - ${salGeneratorPath} - - - true - - - - - - org.opendaylight.controller - yang-jmx-generator-plugin - ${config.version} - - 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 index 6a061b1ea9..0000000000 --- a/opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/Capability.java +++ /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 getModuleNamespace(); - - public Optional getModuleName(); - - public Optional getRevision(); - - public Optional getCapabilitySchema(); - - public Collection getLocation(); -} diff --git a/opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/NetconfDocumentedException.java b/opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/NetconfDocumentedException.java index e1e932b55a..9cf78c930b 100644 --- a/opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/NetconfDocumentedException.java +++ b/opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/NetconfDocumentedException.java @@ -8,321 +8,41 @@ 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 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. emptyMap()); - } - - public NetconfDocumentedException(final String message, final ErrorType errorType, final ErrorTag errorTag, - final ErrorSeverity errorSeverity, final Map 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. 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 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 errorInfo) { + super(message, errorType, errorTag, errorSeverity, errorInfo); } - public static NetconfDocumentedException wrap(E exception) throws NetconfDocumentedException { - final Map 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 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 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 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 parseErrorInfo( Node node ) { - Map 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 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 errorInfoMap = getErrorInfo(); - if( errorInfoMap != null && !errorInfoMap.isEmpty() ) { - /* - * - * message-id - * rpc - * - */ - - Node errorInfoNode = doc.createElementNS( URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0, ERROR_INFO ); - errorInfoNode.setPrefix( rpcReply.getPrefix() ); - rpcError.appendChild( errorInfoNode ); - - for ( Entry 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 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 index 4e3954a24d..0000000000 --- a/opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/jmx/CommitJMXNotification.java +++ /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 capabilities; - - CommitJMXNotification(NotificationBroadcasterSupport source, String message, Element cfgSnapshot, - Set 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 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 index edc0bc99c5..0000000000 --- a/opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/jmx/DefaultCommitOperationMXBean.java +++ /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 index cba98ee435..0000000000 --- a/opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/jmx/NetconfJMXNotification.java +++ /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 capabilities) { - return new CommitJMXNotification(source, message, cfgSnapshot, capabilities); - } - - static enum TransactionProviderJMXNotificationType { - commit; - } - -} diff --git a/opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/monitoring/CapabilityListener.java b/opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/monitoring/CapabilityListener.java index 5d9468c8ea..0ea9f6b493 100644 --- a/opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/monitoring/CapabilityListener.java +++ b/opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/monitoring/CapabilityListener.java @@ -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 addedCaps); + void onCapabilitiesChanged(Set added, Set removed); - void onCapabilitiesRemoved(Set removedCaps); } diff --git a/opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/util/NetconfConstants.java b/opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/util/NetconfConstants.java index b9c4dcaf4a..4fec3cdd0f 100644 --- a/opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/util/NetconfConstants.java +++ b/opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/util/NetconfConstants.java @@ -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 diff --git a/opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/xml/XmlNetconfConstants.java b/opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/xml/XmlNetconfConstants.java index 1bcae151d7..3be447a249 100644 --- a/opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/xml/XmlNetconfConstants.java +++ b/opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/xml/XmlNetconfConstants.java @@ -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"; } diff --git a/opendaylight/netconf/netconf-api/src/test/java/org/opendaylight/controller/netconf/api/NetconfDocumentedExceptionTest.java b/opendaylight/netconf/netconf-api/src/test/java/org/opendaylight/controller/netconf/api/NetconfDocumentedExceptionTest.java index dc18b106bf..3621f83312 100644 --- a/opendaylight/netconf/netconf-api/src/test/java/org/opendaylight/controller/netconf/api/NetconfDocumentedExceptionTest.java +++ b/opendaylight/netconf/netconf-api/src/test/java/org/opendaylight/controller/netconf/api/NetconfDocumentedExceptionTest.java @@ -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() ); } diff --git a/opendaylight/netconf/netconf-artifacts/pom.xml b/opendaylight/netconf/netconf-artifacts/pom.xml index 1d9e23edea..269dd4d68c 100644 --- a/opendaylight/netconf/netconf-artifacts/pom.xml +++ b/opendaylight/netconf/netconf-artifacts/pom.xml @@ -15,6 +15,10 @@ 0.4.0-SNAPSHOT pom + + 1.3.0-SNAPSHOT + + @@ -92,6 +96,11 @@ mdsal-netconf-monitoring ${project.version} + + ${project.groupId} + mdsal-netconf-monitoring + ${project.version} + ${project.groupId} netconf-netty-util @@ -117,6 +126,26 @@ netconf-util ${project.version} + + ${project.groupId} + netconf-mdsal-config + ${project.version} + config + xml + + + ${project.groupId} + sal-netconf-connector + ${mdsal.version} + + + ${project.groupId} + features-netconf-connector + ${mdsal.version} + features + xml + runtime + ${project.groupId} diff --git a/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClientSessionNegotiator.java b/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClientSessionNegotiator.java index b9a6f4104f..17f5608a1c 100644 --- a/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClientSessionNegotiator.java +++ b/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClientSessionNegotiator.java @@ -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 index 0000000000..ef657d26ff --- /dev/null +++ b/opendaylight/netconf/netconf-config-dispatcher/pom.xml @@ -0,0 +1,75 @@ + + + + 4.0.0 + + org.opendaylight.controller + netconf-subsystem + 0.4.0-SNAPSHOT + + + netconf-config-dispatcher + bundle + + + + ${project.groupId} + config-api + + + ${project.groupId} + netconf-client + + + + ${project.groupId} + config-manager + test-jar + test + + + ${project.groupId} + config-manager + test + + + ${project.groupId} + config-util + test + + + ${project.groupId} + netty-threadgroup-config + test + + + ${project.groupId} + netty-timer-config + test + + + org.opendaylight.yangtools + mockito-configuration + test + + + + + + + org.apache.felix + maven-bundle-plugin + + + org.opendaylight.yangtools + yang-maven-plugin + + + + 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 index 0000000000..0a10c2d3a8 --- /dev/null +++ b/opendaylight/netconf/netconf-config-dispatcher/src/main/java/org/opendaylight/controller/config/yang/config/netconf/client/dispatcher/NetconfClientDispatcherModule.java @@ -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 index 0000000000..cfd4ef69a5 --- /dev/null +++ b/opendaylight/netconf/netconf-config-dispatcher/src/main/java/org/opendaylight/controller/config/yang/config/netconf/client/dispatcher/NetconfClientDispatcherModuleFactory.java @@ -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 index 0000000000..16c2bcb062 --- /dev/null +++ b/opendaylight/netconf/netconf-config-dispatcher/src/main/yang/odl-netconf-cfg.yang @@ -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 index 0000000000..e00bdeb687 --- /dev/null +++ b/opendaylight/netconf/netconf-config-dispatcher/src/main/yang/odl-netconfig-client-cfg.yang @@ -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 index 0000000000..85477a0237 --- /dev/null +++ b/opendaylight/netconf/netconf-config-dispatcher/src/test/java/org/opendaylight/controller/config/yang/config/netconf/client/dispatcher/NetconfClientDispatcherModuleTest.java @@ -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; + } +} diff --git a/opendaylight/netconf/netconf-impl/pom.xml b/opendaylight/netconf/netconf-impl/pom.xml index 5bb624e38c..10f88c564e 100644 --- a/opendaylight/netconf/netconf-impl/pom.xml +++ b/opendaylight/netconf/netconf-impl/pom.xml @@ -29,6 +29,14 @@ ${project.groupId} netconf-mapping-api + + org.opendaylight.controller + netconf-notifications-api + + + org.opendaylight.controller + netconf-notifications-impl + ${project.groupId} netconf-netty-util @@ -64,10 +72,6 @@ ietf-inet-types - - org.osgi - org.osgi.core - org.slf4j slf4j-api @@ -124,37 +128,6 @@ org.opendaylight.yangtools yang-maven-plugin - - - config - - generate-sources - - - - - org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator - ${jmxGeneratorPath} - - urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang - - - - org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl - ${salGeneratorPath} - - - true - - - - - - org.opendaylight.controller - yang-jmx-generator-plugin - ${config.version} - - diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/config/yang/config/netconf/northbound/impl/NetconfServerDispatcherModule.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/config/yang/config/netconf/northbound/impl/NetconfServerDispatcherModule.java index 3c476608a2..687ca933f0 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/config/yang/config/netconf/northbound/impl/NetconfServerDispatcherModule.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/config/yang/config/netconf/northbound/impl/NetconfServerDispatcherModule.java @@ -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 index d9f8e34da9..0000000000 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/CommitNotifier.java +++ /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 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 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 index 88ff928c51..0000000000 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/DefaultCommitNotificationProducer.java +++ /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 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); - } - } -} diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionListener.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionListener.java index bc6a2f7284..b0dcf7876b 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionListener.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionListener.java @@ -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 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 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 transformCapabilities(final Capabilities capabilities) { + return Sets.newHashSet(Collections2.transform(capabilities.getCapability(), new Function() { + @Override + public String apply(final Uri uri) { + return uri.getValue(); + } + })); } } diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/SubtreeFilter.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/SubtreeFilter.java index d56648cdf0..597380e5c1 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/SubtreeFilter.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/SubtreeFilter.java @@ -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 prefixToNamespaceOfFilter; final Map.Entry prefixToNamespaceOfSrc; try { diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultCloseSession.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultCloseSession.java index 303352c9c5..3aa40b55a6 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultCloseSession.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultCloseSession.java @@ -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.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 index 13e56d71e8..0000000000 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultCommit.java +++ /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 transformCapabilities(final Capabilities capabilities) { - return Sets.newHashSet(Collections2.transform(capabilities.getCapability(), new Function() { - @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(); - } - -} diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultStartExi.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultStartExi.java index 5593c22fad..1dab7e0b45 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultStartExi.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultStartExi.java @@ -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; diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultStopExi.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultStopExi.java index 2b90a61505..8ee671733e 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultStopExi.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultStopExi.java @@ -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(); diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/AggregatedNetconfOperationServiceFactory.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/AggregatedNetconfOperationServiceFactory.java index ae68ecc120..d4a15e0dbd 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/AggregatedNetconfOperationServiceFactory.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/AggregatedNetconfOperationServiceFactory.java @@ -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 factories = new HashSet<>(); private final Multimap registrations = HashMultimap.create(); private final Set 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); } } diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfImplActivator.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfImplActivator.java index 1e35597d9a..8946765aa6 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfImplActivator.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfImplActivator.java @@ -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 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 notificationServiceTracker = + new ServiceTracker<>(context, NetconfNotificationCollector.class, new ServiceTrackerCustomizer() { + @Override + public NetconfNotificationCollector addingService(ServiceReference reference) { + listenerReg = context.getService(reference).registerBaseNotificationPublisher(); + monitoringService.setNotificationPublisher(listenerReg); + return null; + } + + @Override + public void modifiedService(ServiceReference reference, NetconfNotificationCollector service) { + + } + + @Override + public void removedService(ServiceReference 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(); diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfMonitoringServiceImpl.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfMonitoringServiceImpl.java index b02137b748..2b0d35bc9d 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfMonitoringServiceImpl.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfMonitoringServiceImpl.java @@ -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 capabilities = new ConcurrentHashMap<>(); private final Set 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 setupCapabilities(final Set caps) { + Set 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 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 added, Set 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 removed, final Set 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.emptyList()); + return netconfCapabilityChangeBuilder.build(); + } + + + private synchronized void onCapabilitiesAdded(final Set 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 addedCaps) { + private synchronized void onCapabilitiesRemoved(final Set 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; } } diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfOperationRouter.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfOperationRouter.java index 16cca1fee7..ab9a3ab1c4 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfOperationRouter.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfOperationRouter.java @@ -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; } diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfOperationRouterImpl.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfOperationRouterImpl.java index 9d58bd911c..56acf0f648 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfOperationRouterImpl.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfOperationRouterImpl.java @@ -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 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 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 sortedByPriority = getSortedNetconfOperationsWithCanHandle( message, session); @@ -129,7 +126,7 @@ public class NetconfOperationRouterImpl implements NetconfOperationRouter { } private TreeMap getSortedNetconfOperationsWithCanHandle(final Document message, - final NetconfServerSession session) throws NetconfDocumentedException { + final NetconfServerSession session) throws DocumentedException { TreeMap 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); } diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/util/DeserializerExceptionHandler.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/util/DeserializerExceptionHandler.java index e336914981..15205e4bed 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/util/DeserializerExceptionHandler.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/util/DeserializerExceptionHandler.java @@ -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 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); } diff --git a/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/ConcurrentClientsTest.java b/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/ConcurrentClientsTest.java index f20bbda75e..b8b544b90d 100644 --- a/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/ConcurrentClientsTest.java +++ b/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/ConcurrentClientsTest.java @@ -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.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(); diff --git a/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/NetconfDispatcherImplTest.java b/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/NetconfDispatcherImplTest.java index 4fd04e29ef..d7d679bcaf 100644 --- a/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/NetconfDispatcherImplTest.java +++ b/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/NetconfDispatcherImplTest.java @@ -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(); } diff --git a/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/SubtreeFilterTest.java b/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/SubtreeFilterTest.java index b925295e74..bc04b3320e 100644 --- a/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/SubtreeFilterTest.java +++ b/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/SubtreeFilterTest.java @@ -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; diff --git a/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultCloseSessionTest.java b/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultCloseSessionTest.java index 9afa76148e..cacee6c986 100644 --- a/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultCloseSessionTest.java +++ b/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultCloseSessionTest.java @@ -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 index 0c7406543f..0000000000 --- a/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultCommitTest.java +++ /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.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); - } -} diff --git a/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultStopExiTest.java b/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultStopExiTest.java index aaaf5991d4..466ec97f18 100644 --- a/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultStopExiTest.java +++ b/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultStopExiTest.java @@ -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 { diff --git a/opendaylight/netconf/netconf-it/pom.xml b/opendaylight/netconf/netconf-it/pom.xml index 4f722f4db4..7022cd13bb 100644 --- a/opendaylight/netconf/netconf-it/pom.xml +++ b/opendaylight/netconf/netconf-it/pom.xml @@ -46,10 +46,6 @@ org.opendaylight.yangtools object-cache-guava - - org.opendaylight.yangtools - mockito-configuration - ${project.groupId} diff --git a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/AbstractNetconfConfigTest.java b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/AbstractNetconfConfigTest.java index 1e31782bb2..b9d16bf34d 100644 --- a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/AbstractNetconfConfigTest.java +++ b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/AbstractNetconfConfigTest.java @@ -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 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 yangDependencies = getBasicYangs(); - return new HardcodedYangStoreService(yangDependencies); + return new HardcodedYangStoreService(yangDependencies, getBindingRuntimeContext()); } static Collection 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 inputStreams) throws IOException { + public HardcodedYangStoreService(final Collection 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 inputStreams) { diff --git a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfConfigPersisterITTest.java b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfConfigPersisterITTest.java index c421a46fdf..ba435e8a36 100644 --- a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfConfigPersisterITTest.java +++ b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfConfigPersisterITTest.java @@ -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 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); diff --git a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITMonitoringTest.java b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITMonitoringTest.java index e745b393fb..79733cc6f5 100644 --- a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITMonitoringTest.java +++ b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITMonitoringTest.java @@ -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"; diff --git a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITSecureTest.java b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITSecureTest.java index f15c41a454..91dbd4117d 100644 --- a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITSecureTest.java +++ b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITSecureTest.java @@ -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; diff --git a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java index 70d7acf159..866fe1ac61 100644 --- a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java +++ b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java @@ -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 index 56015b9625..0000000000 --- a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/SSLUtil.java +++ /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; - } - -} diff --git a/opendaylight/netconf/netconf-mapping-api/pom.xml b/opendaylight/netconf/netconf-mapping-api/pom.xml index ab8635b62d..85d38bced2 100644 --- a/opendaylight/netconf/netconf-mapping-api/pom.xml +++ b/opendaylight/netconf/netconf-mapping-api/pom.xml @@ -17,6 +17,11 @@ ${project.groupId} netconf-api + + org.opendaylight.controller + config-manager-facade-xml + 0.4.0-SNAPSHOT + com.google.guava @@ -33,37 +38,6 @@ org.opendaylight.yangtools yang-maven-plugin - - - config - - generate-sources - - - - - org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator - ${jmxGeneratorPath} - - urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang - - - - org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl - ${salGeneratorPath} - - - true - - - - - - org.opendaylight.controller - yang-jmx-generator-plugin - ${config.version} - - diff --git a/opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/NetconfOperation.java b/opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/NetconfOperation.java index c7298cbf1e..00b3124e7f 100644 --- a/opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/NetconfOperation.java +++ b/opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/NetconfOperation.java @@ -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; } diff --git a/opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/NetconfOperationChainedExecution.java b/opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/NetconfOperationChainedExecution.java index 4013d623bd..e474422cec 100644 --- a/opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/NetconfOperationChainedExecution.java +++ b/opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/NetconfOperationChainedExecution.java @@ -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"); } }; diff --git a/opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/NetconfOperationServiceFactory.java b/opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/NetconfOperationServiceFactory.java index 8caa177bfa..c737817828 100644 --- a/opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/NetconfOperationServiceFactory.java +++ b/opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/NetconfOperationServiceFactory.java @@ -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; /** diff --git a/opendaylight/netconf/netconf-mapping-api/src/test/java/org/opendaylight/controller/netconf/mapping/api/HandlingPriorityTest.java b/opendaylight/netconf/netconf-mapping-api/src/main/test/java/org/opendaylight/controller/netconf/mapping/api/HandlingPriorityTest.java similarity index 60% rename from opendaylight/netconf/netconf-mapping-api/src/test/java/org/opendaylight/controller/netconf/mapping/api/HandlingPriorityTest.java rename to opendaylight/netconf/netconf-mapping-api/src/main/test/java/org/opendaylight/controller/netconf/mapping/api/HandlingPriorityTest.java index 6faec64daf..04059c1722 100644 --- a/opendaylight/netconf/netconf-mapping-api/src/test/java/org/opendaylight/controller/netconf/mapping/api/HandlingPriorityTest.java +++ b/opendaylight/netconf/netconf-mapping-api/src/main/test/java/org/opendaylight/controller/netconf/mapping/api/HandlingPriorityTest.java @@ -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()); } } diff --git a/opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/Get.java b/opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/Get.java index 6ab3cd4b6e..baea3a5e09 100644 --- a/opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/Get.java +++ b/opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/Get.java @@ -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"); } } diff --git a/opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/GetSchema.java b/opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/GetSchema.java index 961c9f57c2..e235106019 100644 --- a/opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/GetSchema.java +++ b/opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/GetSchema.java @@ -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 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 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 versionElement = getSchemaElement diff --git a/opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/osgi/NetconfMonitoringActivator.java b/opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/osgi/NetconfMonitoringActivator.java index 4e9ecae3f2..1a0941085f 100644 --- a/opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/osgi/NetconfMonitoringActivator.java +++ b/opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/osgi/NetconfMonitoringActivator.java @@ -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; diff --git a/opendaylight/netconf/netconf-monitoring/src/test/java/org/opendaylight/controller/netconf/monitoring/GetSchemaTest.java b/opendaylight/netconf/netconf-monitoring/src/test/java/org/opendaylight/controller/netconf/monitoring/GetSchemaTest.java index 7b590b59e9..dd25aff33f 100644 --- a/opendaylight/netconf/netconf-monitoring/src/test/java/org/opendaylight/controller/netconf/monitoring/GetSchemaTest.java +++ b/opendaylight/netconf/netconf-monitoring/src/test/java/org/opendaylight/controller/netconf/monitoring/GetSchemaTest.java @@ -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 { " "; } - @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)); diff --git a/opendaylight/netconf/netconf-monitoring/src/test/java/org/opendaylight/controller/netconf/monitoring/GetTest.java b/opendaylight/netconf/netconf-monitoring/src/test/java/org/opendaylight/controller/netconf/monitoring/GetTest.java index 5a744fda14..86c9cc62e9 100644 --- a/opendaylight/netconf/netconf-monitoring/src/test/java/org/opendaylight/controller/netconf/monitoring/GetTest.java +++ b/opendaylight/netconf/netconf-monitoring/src/test/java/org/opendaylight/controller/netconf/monitoring/GetTest.java @@ -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()); diff --git a/opendaylight/netconf/netconf-monitoring/src/test/java/org/opendaylight/controller/netconf/monitoring/xml/JaxBSerializerTest.java b/opendaylight/netconf/netconf-monitoring/src/test/java/org/opendaylight/controller/netconf/monitoring/xml/JaxBSerializerTest.java index 50a355c227..e19febf1a7 100644 --- a/opendaylight/netconf/netconf-monitoring/src/test/java/org/opendaylight/controller/netconf/monitoring/xml/JaxBSerializerTest.java +++ b/opendaylight/netconf/netconf-monitoring/src/test/java/org/opendaylight/controller/netconf/monitoring/xml/JaxBSerializerTest.java @@ -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 added, Set removed) { } @Override - public void onCapabilitiesAdded(final Set addedCaps) { + public void onSessionUp(final NetconfManagementSession session) { } @Override - public void onCapabilitiesRemoved(final Set addedCaps) { + public void onSessionDown(final NetconfManagementSession session) { } diff --git a/opendaylight/netconf/netconf-netty-util/pom.xml b/opendaylight/netconf/netconf-netty-util/pom.xml index c979a1aa04..2ec59270db 100644 --- a/opendaylight/netconf/netconf-netty-util/pom.xml +++ b/opendaylight/netconf/netconf-netty-util/pom.xml @@ -60,10 +60,6 @@ openexi nagasena-rta - - org.osgi - org.osgi.core - org.slf4j slf4j-api @@ -85,12 +81,7 @@ maven-bundle-plugin - 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 + org.opendaylight.controller.netconf.nettyutil.* diff --git a/opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/AbstractNetconfSession.java b/opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/AbstractNetconfSession.java index a59b1a0d76..a4ad1a4e82 100644 --- a/opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/AbstractNetconfSession.java +++ b/opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/AbstractNetconfSession.java @@ -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; diff --git a/opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/NetconfXMLToHelloMessageDecoder.java b/opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/NetconfXMLToHelloMessageDecoder.java index 10f699f8d5..69af52d61e 100644 --- a/opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/NetconfXMLToHelloMessageDecoder.java +++ b/opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/NetconfXMLToHelloMessageDecoder.java @@ -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; diff --git a/opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/NetconfXMLToMessageDecoder.java b/opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/NetconfXMLToMessageDecoder.java index 5ae9bb4b1c..07fb789a08 100644 --- a/opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/NetconfXMLToMessageDecoder.java +++ b/opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/NetconfXMLToMessageDecoder.java @@ -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; diff --git a/opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/exi/EXIParameters.java b/opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/exi/EXIParameters.java index 8590068774..cb07635a1a 100644 --- a/opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/exi/EXIParameters.java +++ b/opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/exi/EXIParameters.java @@ -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; diff --git a/opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/exi/NetconfStartExiMessage.java b/opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/exi/NetconfStartExiMessage.java index 1d301d3d35..4cc0461f9e 100644 --- a/opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/exi/NetconfStartExiMessage.java +++ b/opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/exi/NetconfStartExiMessage.java @@ -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; diff --git a/opendaylight/netconf/netconf-netty-util/src/test/java/org/opendaylight/controller/netconf/nettyutil/handler/NetconfEXIHandlersTest.java b/opendaylight/netconf/netconf-netty-util/src/test/java/org/opendaylight/controller/netconf/nettyutil/handler/NetconfEXIHandlersTest.java index 5c5b5a21c3..34f8619a69 100644 --- a/opendaylight/netconf/netconf-netty-util/src/test/java/org/opendaylight/controller/netconf/nettyutil/handler/NetconfEXIHandlersTest.java +++ b/opendaylight/netconf/netconf-netty-util/src/test/java/org/opendaylight/controller/netconf/nettyutil/handler/NetconfEXIHandlersTest.java @@ -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; diff --git a/opendaylight/netconf/netconf-netty-util/src/test/java/org/opendaylight/controller/netconf/nettyutil/handler/NetconfHelloMessageToXMLEncoderTest.java b/opendaylight/netconf/netconf-netty-util/src/test/java/org/opendaylight/controller/netconf/nettyutil/handler/NetconfHelloMessageToXMLEncoderTest.java index 00d95df423..375448ee66 100644 --- a/opendaylight/netconf/netconf-netty-util/src/test/java/org/opendaylight/controller/netconf/nettyutil/handler/NetconfHelloMessageToXMLEncoderTest.java +++ b/opendaylight/netconf/netconf-netty-util/src/test/java/org/opendaylight/controller/netconf/nettyutil/handler/NetconfHelloMessageToXMLEncoderTest.java @@ -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 { diff --git a/opendaylight/netconf/netconf-netty-util/src/test/java/org/opendaylight/controller/netconf/nettyutil/handler/NetconfXMLToHelloMessageDecoderTest.java b/opendaylight/netconf/netconf-netty-util/src/test/java/org/opendaylight/controller/netconf/nettyutil/handler/NetconfXMLToHelloMessageDecoderTest.java index ac6370685a..43f31e69d7 100644 --- a/opendaylight/netconf/netconf-netty-util/src/test/java/org/opendaylight/controller/netconf/nettyutil/handler/NetconfXMLToHelloMessageDecoderTest.java +++ b/opendaylight/netconf/netconf-netty-util/src/test/java/org/opendaylight/controller/netconf/nettyutil/handler/NetconfXMLToHelloMessageDecoderTest.java @@ -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 { diff --git a/opendaylight/netconf/netconf-netty-util/src/test/java/org/opendaylight/controller/netconf/nettyutil/handler/exi/EXIParametersTest.java b/opendaylight/netconf/netconf-netty-util/src/test/java/org/opendaylight/controller/netconf/nettyutil/handler/exi/EXIParametersTest.java index 70186f39a4..5d1f009b30 100644 --- a/opendaylight/netconf/netconf-netty-util/src/test/java/org/opendaylight/controller/netconf/nettyutil/handler/exi/EXIParametersTest.java +++ b/opendaylight/netconf/netconf-netty-util/src/test/java/org/opendaylight/controller/netconf/nettyutil/handler/exi/EXIParametersTest.java @@ -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; diff --git a/opendaylight/netconf/netconf-notifications-api/pom.xml b/opendaylight/netconf/netconf-notifications-api/pom.xml index 3023a2d30e..009093ccba 100644 --- a/opendaylight/netconf/netconf-notifications-api/pom.xml +++ b/opendaylight/netconf/netconf-notifications-api/pom.xml @@ -24,6 +24,10 @@ org.opendaylight.controller netconf-api + + org.opendaylight.controller + config-manager-facade-xml + org.opendaylight.controller ietf-netconf-notifications @@ -43,11 +47,6 @@ org.apache.felix maven-bundle-plugin - - - org.opendaylight.controller.netconf.notifications.* - - diff --git a/opendaylight/netconf/netconf-notifications-api/src/main/java/org/opendaylight/controller/netconf/notifications/BaseNetconfNotificationListener.java b/opendaylight/netconf/netconf-notifications-api/src/main/java/org/opendaylight/controller/netconf/notifications/BaseNetconfNotificationListener.java index 899ab85e92..577aee39fb 100644 --- a/opendaylight/netconf/netconf-notifications-api/src/main/java/org/opendaylight/controller/netconf/notifications/BaseNetconfNotificationListener.java +++ b/opendaylight/netconf/netconf-notifications-api/src/main/java/org/opendaylight/controller/netconf/notifications/BaseNetconfNotificationListener.java @@ -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 diff --git a/opendaylight/netconf/netconf-notifications-api/src/main/java/org/opendaylight/controller/netconf/notifications/NetconfNotificationCollector.java b/opendaylight/netconf/netconf-notifications-api/src/main/java/org/opendaylight/controller/netconf/notifications/NetconfNotificationCollector.java index 2663a5db5f..9d3d5bab02 100644 --- a/opendaylight/netconf/netconf-notifications-api/src/main/java/org/opendaylight/controller/netconf/notifications/NetconfNotificationCollector.java +++ b/opendaylight/netconf/netconf-notifications-api/src/main/java/org/opendaylight/controller/netconf/notifications/NetconfNotificationCollector.java @@ -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 diff --git a/opendaylight/netconf/netconf-notifications-impl/pom.xml b/opendaylight/netconf/netconf-notifications-impl/pom.xml index 64255edc81..31f52918ba 100644 --- a/opendaylight/netconf/netconf-notifications-impl/pom.xml +++ b/opendaylight/netconf/netconf-notifications-impl/pom.xml @@ -58,6 +58,7 @@ org.opendaylight.controller.netconf.notifications.impl.osgi.Activator + org.opendaylight.controller.netconf.notifications.impl.* diff --git a/opendaylight/netconf/netconf-notifications-impl/src/main/java/org/opendaylight/controller/netconf/notifications/impl/NetconfNotificationManager.java b/opendaylight/netconf/netconf-notifications-impl/src/main/java/org/opendaylight/controller/netconf/notifications/impl/NetconfNotificationManager.java index d2dbcaf416..2bddb09690 100644 --- a/opendaylight/netconf/netconf-notifications-impl/src/main/java/org/opendaylight/controller/netconf/notifications/impl/NetconfNotificationManager.java +++ b/opendaylight/netconf/netconf-notifications-impl/src/main/java/org/opendaylight/controller/netconf/notifications/impl/NetconfNotificationManager.java @@ -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))); } } diff --git a/opendaylight/netconf/netconf-notifications-impl/src/main/java/org/opendaylight/controller/netconf/notifications/impl/ops/CreateSubscription.java b/opendaylight/netconf/netconf-notifications-impl/src/main/java/org/opendaylight/controller/netconf/notifications/impl/ops/CreateSubscription.java index 0d6b4248f6..bdd1c3a6a7 100644 --- a/opendaylight/netconf/netconf-notifications-impl/src/main/java/org/opendaylight/controller/netconf/notifications/impl/ops/CreateSubscription.java +++ b/opendaylight/netconf/netconf-notifications-impl/src/main/java/org/opendaylight/controller/netconf/notifications/impl/ops/CreateSubscription.java @@ -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.absent()); } - private static StreamNameType parseStreamIfPresent(final XmlElement operationElement) throws NetconfDocumentedException { + private static StreamNameType parseStreamIfPresent(final XmlElement operationElement) throws DocumentedException { final Optional stream = operationElement.getOnlyChildElementWithSameNamespaceOptionally("stream"); return stream.isPresent() ? new StreamNameType(stream.get().getTextContent()) : NetconfNotificationManager.BASE_STREAM_NAME; } diff --git a/opendaylight/netconf/netconf-notifications-impl/src/main/java/org/opendaylight/controller/netconf/notifications/impl/ops/Get.java b/opendaylight/netconf/netconf-notifications-impl/src/main/java/org/opendaylight/controller/netconf/notifications/impl/ops/Get.java index 85f29360c5..93848c5b0f 100644 --- a/opendaylight/netconf/netconf-notifications-impl/src/main/java/org/opendaylight/controller/netconf/notifications/impl/ops/Get.java +++ b/opendaylight/netconf/netconf-notifications-impl/src/main/java/org/opendaylight/controller/netconf/notifications/impl/ops/Get.java @@ -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"); } diff --git a/opendaylight/netconf/netconf-notifications-impl/src/main/java/org/opendaylight/controller/netconf/notifications/impl/ops/NotificationsTransformUtil.java b/opendaylight/netconf/netconf-notifications-impl/src/main/java/org/opendaylight/controller/netconf/notifications/impl/ops/NotificationsTransformUtil.java index 080176dcd4..131d3496bc 100644 --- a/opendaylight/netconf/netconf-notifications-impl/src/main/java/org/opendaylight/controller/netconf/notifications/impl/ops/NotificationsTransformUtil.java +++ b/opendaylight/netconf/netconf-notifications-impl/src/main/java/org/opendaylight/controller/netconf/notifications/impl/ops/NotificationsTransformUtil.java @@ -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; diff --git a/opendaylight/netconf/netconf-notifications-impl/src/main/java/org/opendaylight/controller/netconf/notifications/impl/osgi/Activator.java b/opendaylight/netconf/netconf-notifications-impl/src/main/java/org/opendaylight/controller/netconf/notifications/impl/osgi/Activator.java index 64442f743d..bd2d5d6b79 100644 --- a/opendaylight/netconf/netconf-notifications-impl/src/main/java/org/opendaylight/controller/netconf/notifications/impl/osgi/Activator.java +++ b/opendaylight/netconf/netconf-notifications-impl/src/main/java/org/opendaylight/controller/netconf/notifications/impl/osgi/Activator.java @@ -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 netconfNotificationCollectorServiceRegistration; private ServiceRegistration 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.emptySet()); return new AutoCloseable() { @Override public void close() { - listener.onCapabilitiesRemoved(capabilities); + listener.onCapabilitiesChanged(Collections.emptySet(), capabilities); } }; } @@ -66,7 +70,6 @@ public class Activator implements BundleActivator { private final CreateSubscription createSubscription = new CreateSubscription(netconfSessionIdForReporting, netconfNotificationManager); - @Override public Set getNetconfOperations() { return Sets.newHashSet( @@ -85,7 +88,6 @@ public class Activator implements BundleActivator { final Dictionary properties = new Hashtable<>(); properties.put(NetconfConstants.SERVICE_NAME, NetconfConstants.NETCONF_MONITORING); operationaServiceRegistration = context.registerService(NetconfOperationServiceFactory.class, netconfOperationServiceFactory, properties); - } @Override diff --git a/opendaylight/netconf/netconf-notifications-impl/src/test/java/org/opendaylight/controller/netconf/notifications/impl/ops/CreateSubscriptionTest.java b/opendaylight/netconf/netconf-notifications-impl/src/test/java/org/opendaylight/controller/netconf/notifications/impl/ops/CreateSubscriptionTest.java index aca8f2de91..1711a5bba1 100644 --- a/opendaylight/netconf/netconf-notifications-impl/src/test/java/org/opendaylight/controller/netconf/notifications/impl/ops/CreateSubscriptionTest.java +++ b/opendaylight/netconf/netconf-notifications-impl/src/test/java/org/opendaylight/controller/netconf/notifications/impl/ops/CreateSubscriptionTest.java @@ -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; diff --git a/opendaylight/netconf/netconf-notifications-impl/src/test/java/org/opendaylight/controller/netconf/notifications/impl/ops/GetTest.java b/opendaylight/netconf/netconf-notifications-impl/src/test/java/org/opendaylight/controller/netconf/notifications/impl/ops/GetTest.java index ac826a5e44..3fe5e5c7e5 100644 --- a/opendaylight/netconf/netconf-notifications-impl/src/test/java/org/opendaylight/controller/netconf/notifications/impl/ops/GetTest.java +++ b/opendaylight/netconf/netconf-notifications-impl/src/test/java/org/opendaylight/controller/netconf/notifications/impl/ops/GetTest.java @@ -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; diff --git a/opendaylight/netconf/netconf-notifications-impl/src/test/java/org/opendaylight/controller/netconf/notifications/impl/ops/NotificationsTransformUtilTest.java b/opendaylight/netconf/netconf-notifications-impl/src/test/java/org/opendaylight/controller/netconf/notifications/impl/ops/NotificationsTransformUtilTest.java index 7bb213ab46..ec1fe55c5c 100644 --- a/opendaylight/netconf/netconf-notifications-impl/src/test/java/org/opendaylight/controller/netconf/notifications/impl/ops/NotificationsTransformUtilTest.java +++ b/opendaylight/netconf/netconf-notifications-impl/src/test/java/org/opendaylight/controller/netconf/notifications/impl/ops/NotificationsTransformUtilTest.java @@ -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; diff --git a/opendaylight/netconf/netconf-ssh/pom.xml b/opendaylight/netconf/netconf-ssh/pom.xml index 5412ff80b5..3094362fe9 100644 --- a/opendaylight/netconf/netconf-ssh/pom.xml +++ b/opendaylight/netconf/netconf-ssh/pom.xml @@ -102,37 +102,6 @@ org.opendaylight.yangtools yang-maven-plugin - - - config - - generate-sources - - - - - org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator - ${jmxGeneratorPath} - - urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang - - - - org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl - ${salGeneratorPath} - - - true - - - - - - org.opendaylight.controller - yang-jmx-generator-plugin - ${config.version} - - diff --git a/opendaylight/netconf/netconf-tcp/pom.xml b/opendaylight/netconf/netconf-tcp/pom.xml index e1e650b4da..bc6b1bc459 100644 --- a/opendaylight/netconf/netconf-tcp/pom.xml +++ b/opendaylight/netconf/netconf-tcp/pom.xml @@ -60,37 +60,6 @@ org.opendaylight.yangtools yang-maven-plugin - - - config - - generate-sources - - - - - org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator - ${jmxGeneratorPath} - - urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang - - - - org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl - ${salGeneratorPath} - - - true - - - - - - org.opendaylight.controller - yang-jmx-generator-plugin - ${config.version} - - diff --git a/opendaylight/netconf/netconf-util/pom.xml b/opendaylight/netconf/netconf-util/pom.xml index b629e28618..5097570b12 100644 --- a/opendaylight/netconf/netconf-util/pom.xml +++ b/opendaylight/netconf/netconf-util/pom.xml @@ -13,6 +13,11 @@ + + org.opendaylight.controller + config-manager-facade-xml + 0.4.0-SNAPSHOT + ${project.groupId} netconf-api @@ -33,10 +38,6 @@ org.opendaylight.controller config-api - - org.osgi - org.osgi.core - org.slf4j slf4j-api diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/NetconfUtil.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/NetconfUtil.java index 5fd53dce55..40b894fc75 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/NetconfUtil.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/NetconfUtil.java @@ -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 index 999f83cf9c..0000000000 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/capability/BasicCapability.java +++ /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 getModuleNamespace() { - return Optional.absent(); - } - - @Override - public Optional getModuleName() { - return Optional.absent(); - } - - @Override - public Optional getRevision() { - return Optional.absent(); - } - - @Override - public Optional getCapabilitySchema() { - return Optional.absent(); - } - - @Override - public Collection 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 index e41affd471..0000000000 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/capability/YangModuleCapability.java +++ /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 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 getModuleName() { - return Optional.of(moduleName); - } - - @Override - public Optional getModuleNamespace() { - return Optional.of(moduleNamespace); - } - - @Override - public Optional 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 index d2a6d2b58d..0000000000 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/exception/MissingNameSpaceException.java +++ /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. emptyMap()); - } - - public MissingNameSpaceException(final String message, final ErrorType errorType, final ErrorTag errorTag, - final ErrorSeverity errorSeverity, final Map 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 index 6d7c7ca7c4..0000000000 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/exception/UnexpectedElementException.java +++ /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. emptyMap()); - } - - public UnexpectedElementException(final String message, final ErrorType errorType, final ErrorTag errorTag, - final ErrorSeverity errorSeverity, final Map 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 index 4a19390b36..0000000000 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/exception/UnexpectedNamespaceException.java +++ /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. emptyMap()); - } - - public UnexpectedNamespaceException(final String message, final ErrorType errorType, final ErrorTag errorTag, - final ErrorSeverity errorSeverity, final Map errorInfo){ - super(message,errorType,errorTag,errorSeverity,errorInfo); - } -} diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/mapping/AbstractLastNetconfOperation.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/mapping/AbstractLastNetconfOperation.java index c40bf3909a..96553a4def 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/mapping/AbstractLastNetconfOperation.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/mapping/AbstractLastNetconfOperation.java @@ -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; } diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/mapping/AbstractNetconfOperation.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/mapping/AbstractNetconfOperation.java index b7ebc51b70..707274ed4a 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/mapping/AbstractNetconfOperation.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/mapping/AbstractNetconfOperation.java @@ -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 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() { diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/mapping/AbstractSingletonNetconfOperation.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/mapping/AbstractSingletonNetconfOperation.java index 3e64e93ed7..307a7d7288 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/mapping/AbstractSingletonNetconfOperation.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/mapping/AbstractSingletonNetconfOperation.java @@ -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); } diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/messages/NetconfHelloMessage.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/messages/NetconfHelloMessage.java index 404885db7e..75f74d078f 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/messages/NetconfHelloMessage.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/messages/NetconfHelloMessage.java @@ -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); } diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/messages/NetconfMessageUtil.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/messages/NetconfMessageUtil.java index 3c6b6ccab9..354d74016d 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/messages/NetconfMessageUtil.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/messages/NetconfMessageUtil.java @@ -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 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; } diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/messages/SendErrorExceptionUtil.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/messages/SendErrorExceptionUtil.java index 490eb95b82..a187d54651 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/messages/SendErrorExceptionUtil.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/messages/SendErrorExceptionUtil.java @@ -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 index 3d46bf6ab4..0000000000 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlElement.java +++ /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 extractNamespaces() throws NetconfDocumentedException { - Map 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 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 getAttributes() { - - Map 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 getChildElementsInternal(ElementFilteringStrategy strat) { - NodeList childNodes = element.getChildNodes(); - final List 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 getChildElements() { - return getChildElementsInternal(new ElementFilteringStrategy() { - @Override - public boolean accept(Element e) { - return true; - } - }); - } - - public List getChildElementsWithinNamespace(final String childName, String namespace) { - return Lists.newArrayList(Collections2.filter(getChildElementsWithinNamespace(namespace), - new Predicate() { - @Override - public boolean apply(XmlElement xmlElement) { - return xmlElement.getName().equals(childName); - } - })); - } - - public List 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 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 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 getOnlyChildElementOptionally(String childName) { - List nameElements = getChildElements(childName); - if (nameElements.size() != 1) { - return Optional.absent(); - } - return Optional.of(nameElements.get(0)); - } - - public Optional getOnlyChildElementOptionally(final String childName, final String namespace) { - List children = getChildElementsWithinNamespace(namespace); - children = Lists.newArrayList(Collections2.filter(children, new Predicate() { - @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 getOnlyChildElementWithSameNamespaceOptionally(final String childName) { - Optional namespace = getNamespaceOptionally(); - if (namespace.isPresent()) { - List children = getChildElementsWithinNamespace(namespace.get()); - children = Lists.newArrayList(Collections2.filter(children, new Predicate() { - @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 getOnlyChildElementWithSameNamespaceOptionally() { - Optional 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 children = getChildElementsWithinNamespace(namespace); - children = Lists.newArrayList(Collections2.filter(children, new Predicate() { - @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 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 getOnlyChildElementOptionally() { - List 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 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 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 getNamespaceOptionally() { - String namespaceURI = element.getNamespaceURI(); - if (Strings.isNullOrEmpty(namespaceURI)) { - return Optional.absent(); - } else { - return Optional.of(namespaceURI); - } - } - - public String getNamespace() throws MissingNameSpaceException { - Optional 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. - * - *
-     * <type
-     * xmlns:th-java="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl">th-java:threadfactory-naming</type>
-     * 
- * - * 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 findNamespaceOfTextContent() throws NetconfDocumentedException { - Map 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 getChildElementsWithSameNamespace(final String childName) throws MissingNameSpaceException { - List children = getChildElementsWithinNamespace(getNamespace()); - return Lists.newArrayList(Collections2.filter(children, new Predicate() { - @Override - public boolean apply(XmlElement xmlElement) { - return xmlElement.getName().equals(childName); - } - })); - } - - public void checkUnrecognisedElements(List recognisedElements, - XmlElement... additionalRecognisedElements) throws NetconfDocumentedException { - List 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.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); - } -} diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlNetconfValidator.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlNetconfValidator.java index bdab8c6209..4de55a7ff3 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlNetconfValidator.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlNetconfValidator.java @@ -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 index 65754e6b34..0000000000 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlUtil.java +++ /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 DEFAULT_DOM_BUILDER = new ThreadLocal(){ - @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 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 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.absent()); - } - - public static Element createTextElementWithNamespacedContent(final Document document, final String qName, final String prefix, - final String namespace, final String contentWithoutPrefix, final Optional 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; - } -} diff --git a/opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/NetconfUtilTest.java b/opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/NetconfUtilTest.java index 007dfdc1e7..d85128067c 100644 --- a/opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/NetconfUtilTest.java +++ b/opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/NetconfUtilTest.java @@ -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 { diff --git a/opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/mapping/AbstractLastNetconfOperationTest.java b/opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/mapping/AbstractLastNetconfOperationTest.java index a6d1d5b999..5fca285719 100644 --- a/opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/mapping/AbstractLastNetconfOperationTest.java +++ b/opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/mapping/AbstractLastNetconfOperationTest.java @@ -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(); diff --git a/opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/mapping/AbstractNetconfOperationTest.java b/opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/mapping/AbstractNetconfOperationTest.java index c7f6321e2c..1002ea06f8 100644 --- a/opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/mapping/AbstractNetconfOperationTest.java +++ b/opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/mapping/AbstractNetconfOperationTest.java @@ -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(""); diff --git a/opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/mapping/AbstractSingletonNetconfOperationTest.java b/opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/mapping/AbstractSingletonNetconfOperationTest.java index 911b73f097..14db47f92b 100644 --- a/opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/mapping/AbstractSingletonNetconfOperationTest.java +++ b/opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/mapping/AbstractSingletonNetconfOperationTest.java @@ -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; } diff --git a/opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/messages/SendErrorExceptionUtilTest.java b/opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/messages/SendErrorExceptionUtilTest.java index 20287741b9..f98e6d9840 100644 --- a/opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/messages/SendErrorExceptionUtilTest.java +++ b/opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/messages/SendErrorExceptionUtilTest.java @@ -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 diff --git a/opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/test/XmlFileLoader.java b/opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/test/XmlFileLoader.java index 176a0de9a4..125162e524 100644 --- a/opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/test/XmlFileLoader.java +++ b/opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/test/XmlFileLoader.java @@ -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; diff --git a/opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/test/XmlUnitUtil.java b/opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/test/XmlUnitUtil.java index e0d432f27c..4cd7fccd25 100644 --- a/opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/test/XmlUnitUtil.java +++ b/opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/test/XmlUnitUtil.java @@ -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 index 0000000000..c702f6cab9 --- /dev/null +++ b/opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/xml/XMLNetconfUtilTest.java @@ -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("value"), 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 index 22210a394e..0000000000 --- a/opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/xml/XmlElementTest.java +++ /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 = "" + - "" + - "deepValue" + - "" + - "innerNamespaceValue" + - "b:valueWithPrefix" + - ""; - 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(""); - 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.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 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 index 79aa565df9..0000000000 --- a/opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/xml/XmlUtilTest.java +++ /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 = "\n" + - "value\n" + - "prefix:value\n" + - "prefix:value\n" + - ""; - - @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("\n" + - "]>\n" + - "\n" + - " \n" + - " urn:ietf:params:netconf:base:1.0 &xxe;\n" + - " \n" + - " ]]>]]>"); - } - - @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("value"), XPathConstants.NODE); - assertEquals("value", ((Element) value).getTextContent()); - } -} \ No newline at end of file diff --git a/opendaylight/netconf/pom.xml b/opendaylight/netconf/pom.xml index c5ffc80205..a98f632e8f 100644 --- a/opendaylight/netconf/pom.xml +++ b/opendaylight/netconf/pom.xml @@ -16,7 +16,6 @@ netconf-api - netconf-cli netconf-config netconf-impl config-netconf-connector @@ -24,22 +23,21 @@ mdsal-netconf-monitoring netconf-util netconf-netty-util - config-persister-impl netconf-mapping-api netconf-client + netconf-config-dispatcher netconf-ssh netconf-tcp netconf-monitoring - ietf-netconf - ietf-netconf-monitoring - ietf-netconf-notifications - ietf-netconf-monitoring-extension netconf-connector-config netconf-mdsal-config netconf-auth - netconf-testtool netconf-notifications-impl netconf-notifications-api + sal-netconf-connector + features + models + tools netconf-artifacts @@ -77,35 +75,37 @@ org.opendaylight.yangtools yang-maven-plugin - ${yangtools.version} - - - org.opendaylight.yangtools - maven-sal-api-gen-plugin - ${yangtools.version} - - + config generate-sources - src/main/yang - org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl - ${salGeneratorPath} + org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator + ${jmxGeneratorPath} + + urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang + - org.opendaylight.yangtools.yang.unified.doc.generator.maven.DocumentationGeneratorImpl - ${project.build.directory}/site/models + org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl + ${salGeneratorPath} true + + + org.opendaylight.controller + yang-jmx-generator-plugin + ${config.version} + + diff --git a/opendaylight/netconf/sal-netconf-connector/pom.xml b/opendaylight/netconf/sal-netconf-connector/pom.xml new file mode 100644 index 0000000000..1de7635596 --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/pom.xml @@ -0,0 +1,189 @@ + + + 4.0.0 + + org.opendaylight.controller + netconf-subsystem + 0.4.0-SNAPSHOT + + + sal-netconf-connector + + bundle + + + ${mdsal.version} + + + + ${project.groupId} + netconf-config-dispatcher + + + ${project.groupId} + sal-common-util + + + ${project.groupId} + sal-connector-api + + + org.opendaylight.controller + ietf-netconf-monitoring + + + org.opendaylight.controller + ietf-netconf-notifications + + + org.opendaylight.controller + netconf-client + + + org.opendaylight.controller + netconf-notifications-api + + + org.opendaylight.controller + netty-config-api + + + org.opendaylight.controller + netty-threadgroup-config + + + org.opendaylight.controller + sal-binding-api + + + org.opendaylight.yangtools + binding-generator-impl + + + org.opendaylight.controller + sal-binding-config + + + org.opendaylight.controller + threadpool-config-api + + + org.opendaylight.controller.model + model-inventory + + + org.opendaylight.yangtools.model + ietf-topology + + + org.opendaylight.controller + sal-broker-impl + + + org.opendaylight.yangtools + yang-data-impl + + + org.opendaylight.yangtools + yang-parser-impl + + + org.opendaylight.yangtools.model + ietf-inet-types + + + org.slf4j + slf4j-api + + + xmlunit + xmlunit + + + ${project.groupId} + config-api + provided + + + ${project.groupId} + config-manager + test + + + ${project.groupId} + config-manager + test-jar + test + + + ${project.groupId} + config-netconf-connector + test + + + ${project.groupId} + config-persister-impl + test + + + ${project.groupId} + config-util + + + ${project.groupId} + netconf-impl + test + + + ${project.groupId} + netconf-mapping-api + test + + + ${project.groupId} + netconf-util + test-jar + test + + + ${project.groupId} + yang-test + test + + + org.opendaylight.controller + logback-config + test + + + org.opendaylight.controller + sal-binding-broker-impl + test-jar + test + + + org.opendaylight.yangtools + mockito-configuration + test + + + + + + + org.apache.felix + maven-bundle-plugin + + + org.opendaylight.yangtools + yang-maven-plugin + + + + + scm:git:http://git.opendaylight.org/gerrit/controller.git + scm:git:ssh://git.opendaylight.org:29418/controller.git + HEAD + https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL + + 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 index 0000000000..b7c518ebfe --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/connector/netconf/NetconfConnectorModule.java @@ -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 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 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 getUserCapabilities() { + if(getYangModuleCapabilities() == null) { + return Optional.absent(); + } + + final List 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 salFacade; + private final NetconfDeviceCommunicator listener; + + public SalConnectorCloseable(final NetconfDeviceCommunicator listener, + final RemoteDeviceHandler 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 index 0000000000..afae0c8765 --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/connector/netconf/NetconfConnectorModuleFactory.java @@ -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 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 index 0000000000..861aaa43db --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/api/MessageTransformer.java @@ -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 { + + 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 index 0000000000..ca12e596e6 --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/api/RemoteDevice.java @@ -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> { + + 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 index 0000000000..4d2f2844d0 --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/api/RemoteDeviceCommunicator.java @@ -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 extends AutoCloseable { + + ListenableFuture> 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 index 0000000000..07c5fcb620 --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/api/RemoteDeviceHandler.java @@ -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 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 index 0000000000..43577c3c26 --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/api/SchemaContextProviderFactory.java @@ -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 capabilities, SchemaSourceProvider 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 index 0000000000..f8c86559fd --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/api/package-info.java @@ -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 index 0000000000..260ed801ab --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDevice.java @@ -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 { + + 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_TO_SOURCE_ID_FUNCTION = new Function() { + @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 salFacade; + private final ListeningExecutorService processingExecutor; + private final SchemaSourceRegistry schemaRegistry; + private final NetconfStateSchemas.NetconfStateSchemasResolver stateSchemasResolver; + private final NotificationHandler notificationHandler; + private final List> sourceRegistrations = Lists.newArrayList(); + + // Message transformer is constructed once the schemas are available + private MessageTransformer messageTransformer; + + public NetconfDevice(final SchemaResourcesDTO schemaResourcesDTO, final RemoteDeviceId id, final RemoteDeviceHandler 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 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 sourceResolverFuture = processingExecutor.submit(task); + + if (shouldListenOnSchemaChange(remoteSessionCapabilities)) { + registerToBaseNetconfStream(initRpc, listener); + } + + final FutureCallback resolvedSourceCallback = new FutureCallback() { + @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 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 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() { + @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 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 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 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 { + + 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 requiredSources = Sets.newHashSet(remoteSessionCapabilities.getModuleBasedCaps()); + final Set providedSources = availableSchemas.getAvailableYangSchemasQNames(); + + final Set 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 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 requiredSources; + private final Set providedSources; + + public DeviceSources(final Set requiredSources, final Set providedSources) { + this.requiredSources = requiredSources; + this.providedSources = providedSources; + } + + public Set getRequiredSourcesQName() { + return requiredSources; + } + + public Set getProvidedSourcesQName() { + return providedSources; + } + + public Collection getRequiredSources() { + return Collections2.transform(requiredSources, QNAME_TO_SOURCE_ID_FUNCTION); + } + + public Collection 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 listener; + private final NetconfDeviceCapabilities capabilities; + + public RecursiveSchemaSetup(final DeviceSources deviceSources, final NetconfSessionPreferences remoteSessionCapabilities, final RemoteDeviceCommunicator 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 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 schemaBuilderFuture = schemaContextFactory.createSchemaContext(requiredSources); + + final FutureCallback RecursiveSchemaBuilderCallback = new FutureCallback() { + + @Override + public void onSuccess(final SchemaContext result) { + LOG.debug("{}: Schema context built successfully from {}", id, requiredSources); + final Collection 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 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 stripMissingSource(final Collection requiredSources, final SourceIdentifier sIdToRemove) { + final LinkedList 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 getQNameFromSourceIdentifiers(final Collection identifiers) { + final Collection qNames = Collections2.transform(identifiers, new Function() { + @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 index 0000000000..e2158ce214 --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfStateSchemas.java @@ -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.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 availableYangSchemas; + + public NetconfStateSchemas(final Set availableYangSchemas) { + this.availableYangSchemas = availableYangSchemas; + } + + public Set getAvailableYangSchemas() { + return availableYangSchemas; + } + + public Set getAvailableYangSchemasQNames() { + return Sets.newHashSet(Collections2.transform(getAvailableYangSchemas(), new Function() { + @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> 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> findSchemasNode(final NormalizedNode result) { + if(result == null) { + return Optional.absent(); + } + final Optional> dataNode = ((DataContainerNode) result).getChild(toId(NETCONF_DATA_QNAME)); + if(dataNode.isPresent() == false) { + return Optional.absent(); + } + + final Optional> 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 availableYangSchemas = Sets.newHashSet(); + + final Optional> 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 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 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 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 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 getAllChildNodeValues(final DataContainerNode schemaNode, final QName childNodeQName) { + final Set extractedValues = Sets.newHashSet(); + final Optional> 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 getSingleChildNodeValue(final DataContainerNode schemaNode, final QName childNode) { + final Optional> node = schemaNode.getChild(toId(childNode)); + Preconditions.checkArgument(node.isPresent(), "Child node %s not present", childNode); + return getValueOfSimpleNode(node.get()); + } + + private static Optional getValueOfSimpleNode(final NormalizedNode node) { + final Object value = node.getValue(); + return value == null || Strings.isNullOrEmpty(value.toString()) ? Optional.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 index 0000000000..6a0d8984e9 --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NotificationHandler.java @@ -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 queue = new LinkedList<>(); + private final RemoteDeviceId id; + private boolean passNotifications = false; + + private NotificationFilter filter; + private MessageTransformer 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 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 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 index 0000000000..8f30a5c63a --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/listener/NetconfDeviceCapabilities.java @@ -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 unresolvedCapabilites; + private final Set resolvedCapabilities; + + private final Set 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 capabilities, FailureReason reason) { + for (QName s : capabilities) { + unresolvedCapabilites.put(s, reason); + } + } + + public void addCapabilities(Collection availableSchemas) { + resolvedCapabilities.addAll(availableSchemas); + } + + public void addNonModuleBasedCapabilities(Collection nonModuleCapabilities) { + this.nonModuleBasedCapabilities.addAll(nonModuleCapabilities); + } + + public Set getNonModuleBasedCapabilities() { + return nonModuleBasedCapabilities; + } + + public Map getUnresolvedCapabilites() { + return unresolvedCapabilites; + } + + public Set 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 index 0000000000..8ed845b542 --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/listener/NetconfDeviceCommunicator.java @@ -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 { + + private static final Logger LOG = LoggerFactory.getLogger(NetconfDeviceCommunicator.class); + + private final RemoteDevice remoteDevice; + private final Optional overrideNetconfCapabilities; + private final RemoteDeviceId id; + private final Lock sessionLock = new ReentrantLock(); + + // TODO implement concurrent message limit + private final Queue requests = new ArrayDeque<>(); + private NetconfClientSession session; + private Future initFuture; + + public NetconfDeviceCommunicator(final RemoteDeviceId id, final RemoteDevice remoteDevice, + final NetconfSessionPreferences NetconfSessionPreferences) { + this(id, remoteDevice, Optional.of(NetconfSessionPreferences)); + } + + public NetconfDeviceCommunicator(final RemoteDeviceId id, + final RemoteDevice remoteDevice) { + this(id, remoteDevice, Optional.absent()); + } + + private NetconfDeviceCommunicator(final RemoteDeviceId id, final RemoteDevice remoteDevice, + final Optional 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>(){ + + @Override + public void operationComplete(Future 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>> 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 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> future: futuresToCancel ) { + if( Strings.isNullOrEmpty( reason ) ) { + future.set( createSessionDownRpcResult() ); + } else { + future.set( createErrorRpcResult( RpcError.ErrorType.TRANSPORT, reason ) ); + } + } + } + + private RpcResult createSessionDownRpcResult() { + return createErrorRpcResult( RpcError.ErrorType.TRANSPORT, + String.format( "The netconf session to %1$s is disconnected", id.getName() ) ); + } + + private RpcResult createErrorRpcResult( RpcError.ErrorType errorType, String message ) { + return RpcResultBuilder.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.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.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> sendRequest(final NetconfMessage message, final QName rpc) { + sessionLock.lock(); + try { + return sendRequestWithLock( message, rpc ); + } finally { + sessionLock.unlock(); + } + } + + private ListenableFuture> 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>(true), + message ); + requests.add(req); + + session.sendMessage(req.request).addListener(new FutureListener() { + @Override + public void operationComplete(final Future 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> future; + final NetconfMessage request; + + private Request(final UncancellableFuture> 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 index 0000000000..7ff48e35f8 --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/listener/NetconfSessionPreferences.java @@ -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 predicate; + private final int skipLength; + + ParameterMatcher(final String name) { + predicate = new Predicate() { + @Override + public boolean apply(final String input) { + return input.startsWith(name); + } + }; + + this.skipLength = name.length(); + } + + private String from(final Iterable params) { + final Optional 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 CONTAINS_REVISION = new Predicate() { + @Override + public boolean apply(final String input) { + return input.contains("revision="); + } + }; + + private final Set moduleBasedCaps; + private final Set nonModuleCaps; + + private NetconfSessionPreferences(final Set nonModuleCaps, final Set moduleBasedCaps) { + this.nonModuleCaps = Preconditions.checkNotNull(nonModuleCaps); + this.moduleBasedCaps = Preconditions.checkNotNull(moduleBasedCaps); + } + + public Set getModuleBasedCaps() { + return moduleBasedCaps; + } + + public Set 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 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 capabilities) { + final Set moduleBasedCaps = new HashSet<>(); + final Set 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 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 moduleBasedCaps, final Set 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 index 0000000000..6219c4c68e --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/listener/UncancellableFuture.java @@ -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 extends AbstractFuture { + @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 index 0000000000..2c0a83d319 --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/package-info.java @@ -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 index 0000000000..6c29f1d338 --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/KeepaliveSalFacade.java @@ -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 { + + 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 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 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 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 { + + @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 { + @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 invokeRpc(@Nonnull final SchemaPath type, final NormalizedNode input) { + final CheckedFuture domRpcResultDOMRpcExceptionCheckedFuture = deviceRpc.invokeRpc(type, input); + Futures.addCallback(domRpcResultDOMRpcExceptionCheckedFuture, resetKeepaliveTask); + return domRpcResultDOMRpcExceptionCheckedFuture; + } + + @Override + public ListenerRegistration 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 index 0000000000..34e81339a3 --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceDataBroker.java @@ -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 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, 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 index 0000000000..b27430f5e3 --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceNotificationService.java @@ -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 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 ListenerRegistration registerNotificationListener(@Nonnull final T listener, @Nonnull final Collection 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() { + @Override + public void close() { + for (final SchemaPath type : types) { + listeners.remove(type, listener); + } + } + + @Override + public T getInstance() { + return listener; + } + }; + } + + @Override + public synchronized ListenerRegistration 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 index 0000000000..178b0502ed --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceRpc.java @@ -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 RPC_TO_RPC_IDENTIFIER = new Function() { + @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 listener; + private final MessageTransformer transformer; + private final Collection availableRpcs; + + public NetconfDeviceRpc(final SchemaContext schemaContext, final RemoteDeviceCommunicator listener, final MessageTransformer transformer) { + this.listener = listener; + this.transformer = transformer; + + availableRpcs = Collections2.transform(schemaContext.getOperations(), RPC_TO_RPC_IDENTIFIER); + } + + @Nonnull + @Override + public CheckedFuture invokeRpc(@Nonnull final SchemaPath type, @Nullable final NormalizedNode input) { + final NetconfMessage message = transformer.toRpcRequest(type, input); + final ListenableFuture> delegateFutureWithPureResult = listener.sendRequest(message, type.getLastComponent()); + + final ListenableFuture transformed = Futures.transform(delegateFutureWithPureResult, new Function, DOMRpcResult>() { + @Override + public DOMRpcResult apply(final RpcResult 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() { + @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 ListenerRegistration registerRpcListener(@Nonnull final T listener) { + + listener.onRpcAvailable(availableRpcs); + + return new ListenerRegistration() { + @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 index 0000000000..96b0d43349 --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceSalFacade.java @@ -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 { + + private static final Logger LOG = LoggerFactory.getLogger(NetconfDeviceSalFacade.class); + + private final RemoteDeviceId id; + private final NetconfDeviceSalProvider salProvider; + private final long defaultRequestTimeoutMillis; + + private final List 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 index 0000000000..f39c0c030d --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceSalProvider.java @@ -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 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 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 index 0000000000..3be30f4e22 --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceTopologyAdapter.java @@ -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, UnavailableCapability> UNAVAILABLE_CAPABILITY_TRANSFORMER = new Function, UnavailableCapability>() { + @Override + public UnavailableCapability apply(final Entry input) { + return new UnavailableCapabilityBuilder() + .setCapability(input.getKey().toString()) + .setFailureReason(input.getValue()).build(); + } + }; + public static final Function AVAILABLE_CAPABILITY_TRANSFORMER = new Function() { + @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 networkTopologyPath; + private final KeyedInstanceIdentifier 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 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 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 result = transaction.submit(); + + Futures.addCallback(result, new FutureCallback() { + @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 index 0000000000..c7c0c0208f --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/AbstractWriteTx.java @@ -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> 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.>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.>fromNullable(data), Optional.absent(), path), Optional.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.>absent(), Optional.of(ModifyAction.DELETE), path), Optional.of(ModifyAction.NONE)); + } catch (final NetconfDocumentedException e) { + handleDeleteException(path, e); + } + } + + @Override + public final ListenableFuture> commit() { + checkNotFinished(); + finished = true; + + return performCommit(); + } + + protected abstract ListenableFuture> 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 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 index 0000000000..b28b0e72a4 --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/ReadOnlyTx.java @@ -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 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() { + @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>, ReadFailedException> readConfigurationData( + final YangInstanceIdentifier path) { + final ListenableFuture configRunning = netconfOps.getConfigRunning(loggingCallback, Optional.fromNullable(path)); + + final ListenableFuture>> transformedFuture = Futures.transform(configRunning, new Function>>() { + @Override + public Optional> apply(final DOMRpcResult result) { + checkReadSuccess(result, path); + + final DataContainerChild dataNode = findDataNode(result); + return NormalizedNodes.findNode(dataNode, path.getPathArguments()); + } + }); + + return MappingCheckedFuture.create(transformedFuture, ReadFailedException.MAPPER); + } + + private DataContainerChild 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>, ReadFailedException> readOperationalData( + final YangInstanceIdentifier path) { + final ListenableFuture configCandidate = netconfOps.get(loggingCallback, Optional.fromNullable(path)); + + // Find data node and normalize its content + final ListenableFuture>> transformedFuture = Futures.transform(configCandidate, new Function>>() { + @Override + public Optional> apply(final DOMRpcResult result) { + checkReadSuccess(result, path); + + final DataContainerChild dataNode = findDataNode(result); + return NormalizedNodes.findNode(dataNode, path.getPathArguments()); + } + }); + + return MappingCheckedFuture.create(transformedFuture, ReadFailedException.MAPPER); + } + + @Override + public void close() { + // NOOP + } + + @Override + public CheckedFuture>, 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 exists(final LogicalDatastoreType store, final YangInstanceIdentifier path) { + final CheckedFuture>, 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 index 0000000000..54db24c393 --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/ReadWriteTx.java @@ -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 submit() { + return delegateWriteTx.submit(); + } + + @Override + public ListenableFuture> commit() { + return delegateWriteTx.commit(); + } + + @Override + public CheckedFuture>, ReadFailedException> read( + final LogicalDatastoreType store, final YangInstanceIdentifier path) { + return delegateReadTx.read(store, path); + } + + @Override public CheckedFuture exists( + final LogicalDatastoreType store, + final YangInstanceIdentifier path) { + final CheckedFuture>, 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 index 0000000000..afd26ffdef --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/WriteCandidateRunningTx.java @@ -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: + *
    + *
  • Running datastore is locked as the first thing and this lock has to succeed
  • + *
+ */ +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>() { + @Override + public ListenableFuture 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 index 0000000000..5c83366f2b --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/WriteCandidateTx.java @@ -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: + *
    + *
  1. Lock candidate datastore on tx construction + *
      + *
    • Lock has to succeed, if it does not, an attempt to discard changes is made + *
    • Discard changes has to succeed + *
    • If discard is successful, lock is reattempted + *
    • Second lock attempt has to succeed + *
    + *
  2. Edit-config in candidate N times + *
      + *
    • If any issue occurs during edit, datastore is discarded using discard-changes rpc, unlocked and an exception is thrown async + *
    + *
  3. Commit and Unlock candidate datastore async + *
+ */ +public class WriteCandidateTx extends AbstractWriteTx { + + private static final Logger LOG = LoggerFactory.getLogger(WriteCandidateTx.class); + + private static final Function> RPC_RESULT_TO_TX_STATUS = new Function>() { + @Override + public RpcResult apply(final DOMRpcResult input) { + if (isSuccess(input)) { + return RpcResultBuilder.success(TransactionStatus.COMMITED).build(); + } else { + final RpcResultBuilder 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>() { + @Override + public ListenableFuture 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 submit() { + final ListenableFuture commitFutureAsVoid = Futures.transform(commit(), new Function, Void>() { + @Override + public Void apply(final RpcResult input) { + Preconditions.checkArgument(input.isSuccessful() && input.getErrors().isEmpty(), "Submit failed with errors: %s", input.getErrors()); + return null; + } + }); + + return Futures.makeChecked(commitFutureAsVoid, new Function() { + @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> performCommit() { + final ListenableFuture 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 defaultOperation) throws NetconfDocumentedException { + invokeBlocking("Edit candidate", new Function>() { + @Override + public ListenableFuture 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 index 0000000000..dc82e860bf --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/WriteRunningTx.java @@ -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: + *
    + *
  1. Lock running datastore on tx construction + *
      + *
    • Lock has to succeed, if it does not, transaction is failed + *
    + *
  2. Edit-config in running N times + *
      + *
    • If any issue occurs during edit, datastore is unlocked and an exception is thrown + *
    + *
  3. Unlock running datastore on tx commit + *
+ */ +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>() { + @Override + public ListenableFuture 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 submit() { + final ListenableFuture commmitFutureAsVoid = Futures.transform(commit(), new Function, Void>() { + @Override + public Void apply(final RpcResult input) { + return null; + } + }); + + return Futures.makeChecked(commmitFutureAsVoid, new Function() { + @Override + public TransactionCommitFailedException apply(final Exception input) { + return new TransactionCommitFailedException("Submit of transaction " + getIdentifier() + " failed", input); + } + }); + } + + @Override + public synchronized ListenableFuture> performCommit() { + unlock(); + return Futures.immediateFuture(RpcResultBuilder.success(TransactionStatus.COMMITED).build()); + } + + @Override + protected void editConfig(final DataContainerChild editStructure, final Optional defaultOperation) throws NetconfDocumentedException { + invokeBlocking("Edit running", new Function>() { + @Override + public ListenableFuture 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>() { + @Override + public ListenableFuture 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 index 0000000000..4a7af8277e --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/schema/NetconfRemoteSchemaYangSourceProvider.java @@ -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 { + + private static final Logger LOG = LoggerFactory.getLogger(NetconfRemoteSchemaYangSourceProvider.class); + + private static final ExceptionMapper MAPPER = new ExceptionMapper( + "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 revision) { + final QName identifierQName = QName.cachedReference(QName.create(NetconfMessageTransformUtil.GET_SCHEMA_QNAME, "identifier")); + final YangInstanceIdentifier.NodeIdentifier identifierId = new YangInstanceIdentifier.NodeIdentifier(identifierQName); + final LeafNode identifier = Builders.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 format = Builders.leafBuilder().withNodeIdentifier(formatId).withValue(Yang.QNAME).build(); + + final DataContainerNodeAttrBuilder 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 revisionNode = Builders.leafBuilder().withNodeIdentifier(revisionId).withValue(revision.get()).build(); + + builder.withChild(revisionNode); + } + + return builder.build(); + } + + private static Optional 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> 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 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 revision = Optional.fromNullable(formattedRevision); + final NormalizedNode getSchemaRequest = createGetSchemaRequest(moduleName, revision); + + LOG.trace("{}: Loading YANG schema source for {}:{}", id, moduleName, + revision); + + final ListenableFuture transformed = Futures.transform( + rpc.invokeRpc(SchemaPath.create(true, NetconfMessageTransformUtil.GET_SCHEMA_QNAME), getSchemaRequest), + new ResultToYangSourceTransformer(id, sourceIdentifier, moduleName, revision)); + + final CheckedFuture 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 { + + private final RemoteDeviceId id; + private final SourceIdentifier sourceIdentifier; + private final String moduleName; + private final Optional revision; + + public ResultToYangSourceTransformer(final RemoteDeviceId id, final SourceIdentifier sourceIdentifier, + final String moduleName, final Optional 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 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 schemaString; + + public NetconfYangTextSchemaSource(final RemoteDeviceId id, final SourceIdentifier sId, final Optional 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 index 0000000000..d210a77751 --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/schema/mapping/NetconfMessageTransformer.java @@ -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 { + + public static final String MESSAGE_ID_PREFIX = "m"; + + private static final Logger LOG= LoggerFactory.getLogger(NetconfMessageTransformer.class); + + + private static final Function QNAME_FUNCTION = new Function() { + @Override + public QName apply(final SchemaNode rpcDefinition) { + return rpcDefinition.getQName(); + } + }; + + private static final Function QNAME_NOREV_FUNCTION = new Function() { + @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 MAPPED_BASE_RPCS = Maps.uniqueIndex(BASE_NETCONF_CTX.getOperations(), QNAME_FUNCTION); + + private final SchemaContext schemaContext; + private final MessageCounter counter; + private final Map mappedRpcs; + private final Multimap 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 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 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 EVENT_TIME_FORMAT = new ThreadLocal() { + 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 stripNotification(final NetconfMessage message) { + final XmlElement xmlElement = XmlElement.fromDomDocument(message.getDocument()); + final List 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 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> 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 documentElement = Collections.singleton(message.getDocument().getDocumentElement()); + + Map 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 index 0000000000..9cf1d2c47a --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/util/NetconfBaseOps.java @@ -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 lock(final FutureCallback callback, final QName datastore) { + Preconditions.checkNotNull(callback); + Preconditions.checkNotNull(datastore); + + final ListenableFuture future = rpc.invokeRpc(toPath(NETCONF_LOCK_QNAME), getLockContent(datastore)); + Futures.addCallback(future, callback); + return future; + } + + public ListenableFuture lockCandidate(final FutureCallback callback) { + final ListenableFuture future = rpc.invokeRpc(toPath(NETCONF_LOCK_QNAME), getLockContent(NETCONF_CANDIDATE_QNAME)); + Futures.addCallback(future, callback); + return future; + } + + + public ListenableFuture lockRunning(final FutureCallback callback) { + final ListenableFuture future = rpc.invokeRpc(toPath(NETCONF_LOCK_QNAME), getLockContent(NETCONF_RUNNING_QNAME)); + Futures.addCallback(future, callback); + return future; + } + + public ListenableFuture unlock(final FutureCallback callback, final QName datastore) { + Preconditions.checkNotNull(callback); + Preconditions.checkNotNull(datastore); + + final ListenableFuture future = rpc.invokeRpc(toPath(NETCONF_UNLOCK_QNAME), getUnLockContent(datastore)); + Futures.addCallback(future, callback); + return future; + } + + public ListenableFuture unlockRunning(final FutureCallback callback) { + final ListenableFuture future = rpc.invokeRpc(toPath(NETCONF_UNLOCK_QNAME), getUnLockContent(NETCONF_RUNNING_QNAME)); + Futures.addCallback(future, callback); + return future; + } + + public ListenableFuture unlockCandidate(final FutureCallback callback) { + final ListenableFuture future = rpc.invokeRpc(toPath(NETCONF_UNLOCK_QNAME), getUnLockContent(NETCONF_CANDIDATE_QNAME)); + Futures.addCallback(future, callback); + return future; + } + + public ListenableFuture discardChanges(final FutureCallback callback) { + Preconditions.checkNotNull(callback); + + final ListenableFuture future = rpc.invokeRpc(toPath(NETCONF_DISCARD_CHANGES_QNAME), null); + Futures.addCallback(future, callback); + return future; + } + + public ListenableFuture commit(final FutureCallback callback) { + Preconditions.checkNotNull(callback); + + final ListenableFuture future = rpc.invokeRpc(toPath(NetconfMessageTransformUtil.NETCONF_COMMIT_QNAME), NetconfMessageTransformUtil.COMMIT_RPC_CONTENT); + Futures.addCallback(future, callback); + return future; + } + + public ListenableFuture validate(final FutureCallback callback, final QName datastore) { + Preconditions.checkNotNull(callback); + Preconditions.checkNotNull(datastore); + + final ListenableFuture future = rpc.invokeRpc(toPath(NetconfMessageTransformUtil.NETCONF_VALIDATE_QNAME), getValidateContent(datastore)); + Futures.addCallback(future, callback); + return future; + } + + public ListenableFuture validateCandidate(final FutureCallback callback) { + return validate(callback, NETCONF_CANDIDATE_QNAME); + } + + + public ListenableFuture validateRunning(final FutureCallback callback) { + return validate(callback, NETCONF_RUNNING_QNAME); + } + + public ListenableFuture copyConfig(final FutureCallback callback, final QName source, final QName target) { + Preconditions.checkNotNull(callback); + Preconditions.checkNotNull(source); + Preconditions.checkNotNull(target); + + final ListenableFuture future = rpc.invokeRpc(toPath(NetconfMessageTransformUtil.NETCONF_COPY_CONFIG_QNAME), getCopyConfigContent(source, target)); + Futures.addCallback(future, callback); + return future; + } + + public ListenableFuture copyRunningToCandidate(final FutureCallback callback) { + return copyConfig(callback, NETCONF_RUNNING_QNAME, NETCONF_CANDIDATE_QNAME); + } + + public ListenableFuture getConfig(final FutureCallback callback, final QName datastore, final Optional filterPath) { + Preconditions.checkNotNull(callback); + Preconditions.checkNotNull(datastore); + + final ListenableFuture 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 getConfigRunning(final FutureCallback callback, final Optional filterPath) { + return getConfig(callback, NETCONF_RUNNING_QNAME, filterPath); + } + + public ListenableFuture getConfigCandidate(final FutureCallback callback, final Optional filterPath) { + return getConfig(callback, NETCONF_CANDIDATE_QNAME, filterPath); + } + + public ListenableFuture get(final FutureCallback callback, final Optional filterPath) { + Preconditions.checkNotNull(callback); + + final ListenableFuture 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 filterPath) { + return filterPath.isPresent() && !filterPath.get().isEmpty(); + } + + public ListenableFuture editConfigCandidate(final FutureCallback callback, final DataContainerChild editStructure, final ModifyAction modifyAction, final boolean rollback) { + return editConfig(callback, NETCONF_CANDIDATE_QNAME, editStructure, Optional.of(modifyAction), rollback); + } + + public ListenableFuture editConfigCandidate(final FutureCallback callback, final DataContainerChild editStructure, final boolean rollback) { + return editConfig(callback, NETCONF_CANDIDATE_QNAME, editStructure, Optional.absent(), rollback); + } + + public ListenableFuture editConfigRunning(final FutureCallback callback, final DataContainerChild editStructure, final ModifyAction modifyAction, final boolean rollback) { + return editConfig(callback, NETCONF_RUNNING_QNAME, editStructure, Optional.of(modifyAction), rollback); + } + + public ListenableFuture editConfigRunning(final FutureCallback callback, final DataContainerChild editStructure, final boolean rollback) { + return editConfig(callback, NETCONF_RUNNING_QNAME, editStructure, Optional.absent(), rollback); + } + + public ListenableFuture editConfig(final FutureCallback callback, final QName datastore, final DataContainerChild editStructure, final Optional modifyAction, final boolean rollback) { + Preconditions.checkNotNull(editStructure); + Preconditions.checkNotNull(callback); + Preconditions.checkNotNull(datastore); + + final ListenableFuture future = rpc.invokeRpc(toPath(NETCONF_EDIT_CONFIG_QNAME), getEditConfigContent(datastore, editStructure, modifyAction, rollback)); + + Futures.addCallback(future, callback); + return future; + } + + public DataContainerChild createEditConfigStrcture(final Optional> lastChild, final Optional operation, final YangInstanceIdentifier dataPath) { + return NetconfMessageTransformUtil.createEditConfigStructure(schemaContext, dataPath, operation, lastChild); + } + + private ContainerNode getEditConfigContent(final QName datastore, final DataContainerChild editStructure, final Optional defaultOperation, final boolean rollback) { + final DataContainerNodeAttrBuilder 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 index 0000000000..c345580e8b --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/util/NetconfMessageTransformUtil.java @@ -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 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 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 errorInfo = ImmutableMap.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 errorInfo = ex.getErrorInfo(); + if(errorInfo != null) { + for( final Entry e: errorInfo.entrySet() ) { + infoBuilder.append( '<' ).append( e.getKey() ).append( '>' ).append( e.getValue() ) + .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 operation, final Optional> 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 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 index 0000000000..48fd469755 --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/util/NetconfRpcFutureCallback.java @@ -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 { + 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 index 0000000000..23e2137026 --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/util/NodeContainerProxy.java @@ -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 childNodes; + private final QName qName; + private final Set availableAugmentations; + + public NodeContainerProxy(final QName qName, final Map childNodes, final Set availableAugmentations) { + this.availableAugmentations = availableAugmentations; + this.childNodes = Preconditions.checkNotNull(childNodes, "childNodes"); + this.qName = qName; + } + + public NodeContainerProxy(final QName qName, final Collection childNodes) { + this(qName, asMap(childNodes), Collections.emptySet()); + } + + public NodeContainerProxy(final QName qName, final Collection childNodes, final Set availableAugmentations) { + this(qName, asMap(childNodes), availableAugmentations); + } + + private static Map asMap(final Collection childNodes) { + return Maps.uniqueIndex(childNodes, new Function() { + @Override + public QName apply(final DataSchemaNode input) { + return input.getQName(); + } + }); + } + + @Override + public Set> getTypeDefinitions() { + return Collections.emptySet(); + } + + @Override + public Set getChildNodes() { + return Sets.newHashSet(childNodes.values()); + } + + @Override + public Set 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 getUses() { + return Collections.emptySet(); + } + + @Override + public boolean isPresenceContainer() { + throw new UnsupportedOperationException(); + } + + @Override + public Set 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 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 index 0000000000..738682f54a --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/util/MessageCounter.java @@ -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 index 0000000000..d5d9da1bed --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/util/RemoteDeviceId.java @@ -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 bindingPath; + private final NodeKey key; + private final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier topologyPath; + private final InstanceIdentifier 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 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 createBindingPathForTopology(final NodeKey key) { + final InstanceIdentifier networkTopology = InstanceIdentifier.builder(NetworkTopology.class).build(); + final KeyedInstanceIdentifier 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 getBindingPath() { + return bindingPath; + } + + public org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier getPath() { + return path; + } + + public NodeKey getBindingKey() { + return key; + } + + public InstanceIdentifier 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 index 0000000000..57f4cbb9aa --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/util/package-info.java @@ -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 index 0000000000..11bf6a549c --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/src/main/yang/netconf-node-topology.yang @@ -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 index 0000000000..799c9c8999 --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/src/main/yang/odl-sal-netconf-connector-cfg.yang @@ -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 index 0000000000..9c15b6091e --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceTest.java @@ -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 + "&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" + "&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 capList = Lists.newArrayList(TEST_CAPABILITY); + + final RemoteDeviceHandler 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.emptyList(), HashMultimap.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 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() { + @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 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 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 + "&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 modelsToParse = Lists.newArrayList( + NetconfDeviceTest.class.getResourceAsStream("/schemas/test-module.yang") + ); + final Set models = parser.parseYangModelsFromStreams(modelsToParse); + return parser.resolveSchemaContext(models); + } + + private RemoteDeviceHandler getFacade() throws Exception { + final RemoteDeviceHandler 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 mockCloseableClass(final Class remoteDeviceHandlerClass) throws Exception { + final T mock = mockClass(remoteDeviceHandlerClass); + doNothing().when(mock).close(); + return mock; + } + + private static T mockClass(final Class 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 getMessageTransformer() throws Exception { + final MessageTransformer 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 additionalCapabilities) { + final ArrayList 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 index 0000000000..768b59ac21 --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/NetconfStateSchemasTest.java @@ -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 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 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 index 0000000000..2b876d263c --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/NetconfToNotificationTest.java @@ -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 modelsToParse = Collections.singletonList(loadClass.getResourceAsStream("/schemas/user-notification.yang")); + final YangContextParser parser = new YangParserImpl(); + final Set 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 index 0000000000..afc5a5fb58 --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/NetconfToRpcRequestTest.java @@ -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 modelsToParse = Collections + .singletonList(NetconfToRpcRequestTest.class.getResourceAsStream("/schemas/rpc-notification-subscription.yang")); + YangContextParser parser = new YangParserImpl(); + final Set notifModules = parser.parseYangModelsFromStreams(modelsToParse); + assertTrue(!notifModules.isEmpty()); + + modelsToParse = Collections + .singletonList(NetconfToRpcRequestTest.class.getResourceAsStream("/schemas/config-test-rpc.yang")); + parser = new YangParserImpl(); + final Set configModules = parser.parseYangModelsFromStreams(modelsToParse); + cfgCtx = parser.resolveSchemaContext(Sets.union(configModules, notifModules)); + assertNotNull(cfgCtx); + + messageTransformer = new NetconfMessageTransformer(cfgCtx, true); + } + + private LeafNode buildLeaf(final QName running, final Object value) { + return Builders.leafBuilder().withNodeIdentifier(toId(running)).withValue(value).build(); + } + + @Test + public void testUserDefinedRpcCall() throws Exception { + final DataContainerNodeAttrBuilder 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( + "\n" + + "" + + "module schema" + + "\n" + + "\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 index 0000000000..04475356d6 --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/listener/NetconfDeviceCommunicatorTest.java @@ -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 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.emptySet()).when(mockSession).getServerCapabilities(); + doNothing().when(mockDevice).onRemoteSessionUp(any(NetconfSessionPreferences.class), + any(NetconfDeviceCommunicator.class)); + communicator.onSessionUp(mockSession); + } + + private ListenableFuture> sendRequest() throws Exception { + return sendRequest( UUID.randomUUID().toString() ); + } + + @SuppressWarnings("unchecked") + private ListenableFuture> 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> 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 serverCapabilities = + Sets.newHashSet( NetconfMessageTransformUtil.NETCONF_ROLLBACK_ON_ERROR_URI.toString(), + NetconfMessageTransformUtil.IETF_NETCONF_MONITORING.getNamespace().toString(), + testCapability ); + doReturn( serverCapabilities ).when( mockSession ).getServerCapabilities(); + + ArgumentCaptor 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> resultFuture1 = sendRequest(); + ListenableFuture> 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> 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 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> resultFuture = communicator.sendRequest( message, rpc ); + + verify( mockSession ).sendMessage( same( message ) ); + + assertNotNull( "ListenableFuture is null", resultFuture ); + + verify( mockChannelFuture ).addListener( futureListener.capture() ); + Future 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> resultFuture = communicator.sendRequest( message, rpc ); + + assertNotNull( "ListenableFuture is null", resultFuture ); + + // Should have an immediate result + RpcResult 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 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> resultFuture = communicator.sendRequest( message, rpc ); + + assertNotNull( "ListenableFuture is null", resultFuture ); + + verify( mockChannelFuture ).addListener( futureListener.capture() ); + + Future 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 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> resultFuture1 = sendRequest( messageID1 ); + + String messageID2 = UUID.randomUUID().toString(); + ListenableFuture> resultFuture2 = sendRequest( messageID2 ); + + String messageID3 = UUID.randomUUID().toString(); + ListenableFuture> 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> resultFuture1 = sendRequest( messageID1 ); + + String messageID2 = UUID.randomUUID().toString(); + ListenableFuture> 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> 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( "foo" ) ); + assertEquals( "Error info contains \"bar\"", true, + errorInfo.contains( "bar" ) ); + } + + /** + * Test whether reconnect is scheduled properly + */ + @Test + public void testNetconfDeviceReconnectInCommunicator() throws Exception { + final RemoteDevice 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 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> 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" + + " missing-attribute" + + " error" + + " Missing attribute" + + " " + + " foo" + + " bar" + + " " + + " " + + ""; + + ByteArrayInputStream bis = new ByteArrayInputStream( xmlStr.getBytes() ); + Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse( bis ); + return new NetconfMessage( doc ); + } + + private void verifyResponseMessage( RpcResult rpcResult, String dataText ) { + assertNotNull( "RpcResult is null", rpcResult ); + assertEquals( "isSuccessful", true, rpcResult.isSuccessful() ); + NetconfMessage messageResult = rpcResult.getResult(); + assertNotNull( "getResult", messageResult ); +// List> nodes = messageResult.getSimpleNodesByName( +// QName.create( URI.create( "ns" ), null, "data" ) ); +// assertNotNull( "getSimpleNodesByName", nodes ); +// assertEquals( "List> size", 1, nodes.size() ); +// assertEquals( "SimpleNode value", dataText, nodes.iterator().next().getValue() ); + } + + private RpcError verifyErrorRpcResult( RpcResult 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 index 0000000000..fcee141bbf --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/listener/NetconfSessionPreferencesTest.java @@ -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 caps1 = Lists.newArrayList( + "namespace:1?module=module1&revision=2012-12-12", + "namespace:2?module=module2&revision=2012-12-12", + "urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring?module=ietf-netconf-monitoring&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 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 caps1 = Lists.newArrayList( + "namespace:2?module=module2", + "namespace:2?module=module2&revision=2012-12-12", + "namespace:2?module=module1&RANDOMSTRING;revision=2013-12-12", + "namespace:2?module=module2&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 index 0000000000..71d1b831f0 --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/sal/KeepaliveSalFacadeTest.java @@ -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 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 index 0000000000..158c4c43f0 --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceTopologyAdapterTest.java @@ -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 index 0000000000..f6a7e6a04d --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/NetconfDeviceWriteOnlyTxTest.java @@ -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 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 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 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 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 index 0000000000..e8587d609d --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/ReadOnlyTxTest.java @@ -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 index 0000000000..b1e74775d6 --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/schema/mapping/NetconfMessageTransformerTest.java @@ -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(""; + + 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("\n" + + "\n" + + "yang\n" + + "module\n" + + "2012-12-12\n" + + "\n" + + ""); + } + + @Test + public void tesGetSchemaResponse() throws Exception { + final NetconfMessageTransformer netconfMessageTransformer = getTransformer(getSchema(true)); + final NetconfMessage response = new NetconfMessage(XmlUtil.readXmlToDocument( + "\n" + + "\n" + + "\n" + + "Random YANG SCHEMA\n" + + "\n" + + "\n" + + "" + )); + 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("\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "module\n" + + "2012-12-12\n" + + "x:yang\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "")); + + 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> values = Lists.newArrayList( + NetconfRemoteSchemaYangSourceProvider.createGetSchemaRequest("module", Optional.of("2012-12-12")).getValue()); + + final Map keys = Maps.newHashMap(); + for (final DataContainerChild 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, "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "" + + "\n" + + "\n" + + "\n" + + "\n" + + "" + + ""); + } + + @Test + public void testEditConfigRequest() throws Exception { + final List> values = Lists.newArrayList( + NetconfRemoteSchemaYangSourceProvider.createGetSchemaRequest("module", Optional.of("2012-12-12")).getValue()); + + final Map keys = Maps.newHashMap(); + for (final DataContainerChild 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.absent(), Optional.>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, "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "module\n" + + "2012-12-12\n" + + "yang\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + ""); + } + + 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, "" + + "\n" + + "\n" + + "\n" + + "\n" + + "a:b:c\n" + + "\n" + + "" + + "\n" + + "" + + ""); + } + + private NetconfMessageTransformer getTransformer(final SchemaContext schema) { + return new NetconfMessageTransformer(schema, true); + } + + @Test + public void testCommitResponse() throws Exception { + final NetconfMessage response = new NetconfMessage(XmlUtil.readXmlToDocument( + "" + )); + 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 index 0000000000..0213415f8d --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/src/test/resources/netconf-state.schemas.payload.xml @@ -0,0 +1,514 @@ + + + urn:opendaylight:params:xml:ns:yang:controller:threadpool + NETCONF + threadpool + prefix:yang + 2013-04-09 + + + urn:opendaylight:params:xml:ns:yang:controller:logback:config + NETCONF + config-logging + prefix:yang + 2013-07-16 + + + urn:opendaylight:model:statistics:types + NETCONF + opendaylight-statistics-types + prefix:yang + 2013-09-25 + + + urn:opendaylight:params:xml:ns:yang:controller:md:sal:core:spi:config-dom-store + NETCONF + opendaylight-config-dom-datastore + prefix:yang + 2014-06-17 + + + urn:opendaylight:flow:table:statistics + NETCONF + opendaylight-flow-table-statistics + prefix:yang + 2013-12-15 + + + urn:opendaylight:meter:service + NETCONF + sal-meter + prefix:yang + 2013-09-18 + + + urn:opendaylight:params:xml:ns:yang:controller:config:toaster-provider:impl + NETCONF + toaster-provider-impl + prefix:yang + 2014-01-31 + + + urn:opendaylight:table:types + NETCONF + opendaylight-table-types + prefix:yang + 2013-10-26 + + + urn:opendaylight:table:service + NETCONF + sal-table + prefix:yang + 2013-10-26 + + + urn:opendaylight:params:xml:ns:yang:controller:shutdown + NETCONF + shutdown + prefix:yang + 2013-12-18 + + + urn:opendaylight:port:service + NETCONF + sal-port + prefix:yang + 2013-11-07 + + + urn:opendaylight:params:xml:ns:yang:controller:netty:eventexecutor + NETCONF + netty-event-executor + prefix:yang + 2013-11-12 + + + urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote + NETCONF + sal-remote + prefix:yang + 2014-01-14 + + + urn:opendaylight:model:topology:view + NETCONF + opendaylight-topology-view + prefix:yang + 2013-10-30 + + + urn:opendaylight:params:xml:ns:yang:controller:netty:threadgroup + NETCONF + threadgroup + prefix:yang + 2013-11-07 + + + urn:TBD:params:xml:ns:yang:network-topology + NETCONF + network-topology + prefix:yang + 2013-07-12 + + + urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:fixed + NETCONF + threadpool-impl-fixed + prefix:yang + 2013-12-01 + + + urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl + NETCONF + opendaylight-sal-binding-broker-impl + prefix:yang + 2013-10-28 + + + urn:ietf:params:xml:ns:yang:ietf-restconf + NETCONF + ietf-restconf + prefix:yang + 2013-10-19 + + + urn:opendaylight:node:error:service + NETCONF + node-error + prefix:yang + 2014-04-10 + + + urn:opendaylight:flow:errors + NETCONF + flow-errors + prefix:yang + 2013-11-16 + + + urn:opendaylight:flow:service + NETCONF + sal-flow + prefix:yang + 2013-08-19 + + + urn:ietf:params:xml:ns:yang:rpc-context + NETCONF + rpc-context + prefix:yang + 2013-06-17 + + + urn:opendaylight:params:xml:ns:yang:controller:md:sal:core:spi:operational-dom-store + + NETCONF + opendaylight-operational-dom-datastore + prefix:yang + 2014-06-17 + + + urn:opendaylight:flow:types:queue + NETCONF + opendaylight-queue-types + prefix:yang + 2013-09-25 + + + urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring + NETCONF + ietf-netconf-monitoring + prefix:yang + 2010-10-04 + + + urn:opendaylight:netconf-node-inventory + NETCONF + netconf-node-inventory + prefix:yang + 2014-01-08 + + + urn:ietf:params:xml:ns:yang:ietf-yang-types + NETCONF + ietf-yang-types + prefix:yang + 2013-07-15 + + + urn:opendaylight:meter:statistics + NETCONF + opendaylight-meter-statistics + prefix:yang + 2013-11-11 + + + urn:opendaylight:flow:inventory + NETCONF + flow-node-inventory + prefix:yang + 2013-08-19 + + + urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf + NETCONF + odl-sal-netconf-connector-cfg + prefix:yang + 2013-10-28 + + + urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:scheduled + NETCONF + threadpool-impl-scheduled + prefix:yang + 2013-12-01 + + + urn:TBD:params:xml:ns:yang:network-topology + NETCONF + network-topology + prefix:yang + 2013-10-21 + + + http://netconfcentral.org/ns/toaster + NETCONF + toaster + prefix:yang + 2009-11-20 + + + urn:opendaylight:params:xml:ns:yang:controller:config:netconf + NETCONF + odl-netconf-cfg + prefix:yang + 2014-04-08 + + + urn:opendaylight:meter:types + NETCONF + opendaylight-meter-types + prefix:yang + 2013-09-18 + + + urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl + NETCONF + opendaylight-sal-dom-broker-impl + prefix:yang + 2013-10-28 + + + urn:opendaylight:flow:topology:discovery + NETCONF + flow-topology-discovery + prefix:yang + 2013-08-19 + + + urn:opendaylight:yang:extension:yang-ext + NETCONF + yang-ext + prefix:yang + 2013-07-09 + + + urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl + NETCONF + threadpool-impl + prefix:yang + 2013-04-05 + + + urn:opendaylight:flow:types:port + NETCONF + opendaylight-port-types + prefix:yang + 2013-09-25 + + + urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding + NETCONF + opendaylight-md-sal-binding + prefix:yang + 2013-10-28 + + + urn:opendaylight:packet:service + NETCONF + packet-processing + prefix:yang + 2013-07-09 + + + urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:flexible + NETCONF + threadpool-impl-flexible + prefix:yang + 2013-12-01 + + + urn:opendaylight:queue:service + NETCONF + sal-queue + prefix:yang + 2013-11-07 + + + urn:ietf:params:xml:ns:yang:ietf-inet-types + NETCONF + ietf-inet-types + prefix:yang + 2010-09-24 + + + urn:opendaylight:params:xml:ns:yang:controller:md:sal:rest:connector + NETCONF + opendaylight-rest-connector + prefix:yang + 2014-07-24 + + + urn:opendaylight:flow:transaction + NETCONF + flow-capable-transaction + prefix:yang + 2013-11-03 + + + urn:opendaylight:flow:statistics + NETCONF + opendaylight-flow-statistics + prefix:yang + 2013-08-19 + + + urn:opendaylight:params:xml:ns:yang:controller:protocol:framework + NETCONF + protocol-framework + prefix:yang + 2014-03-13 + + + urn:opendaylight:model:match:types + NETCONF + opendaylight-match-types + prefix:yang + 2013-10-26 + + + urn:ietf:params:xml:ns:yang:ietf-yang-types + NETCONF + ietf-yang-types + prefix:yang + 2010-09-24 + + + urn:opendaylight:group:service + NETCONF + sal-group + prefix:yang + 2013-09-18 + + + urn:opendaylight:params:xml:ns:yang:controller:inmemory-datastore-provider + NETCONF + opendaylight-inmemory-datastore-provider + prefix:yang + 2014-06-17 + + + urn:opendaylight:params:xml:ns:yang:controller:netty:timer + NETCONF + netty-timer + prefix:yang + 2013-11-19 + + + urn:opendaylight:group:statistics + NETCONF + opendaylight-group-statistics + prefix:yang + 2013-11-11 + + + urn:opendaylight:params:xml:ns:yang:controller:config + NETCONF + config + prefix:yang + 2013-04-05 + + + urn:opendaylight:params:xml:ns:yang:controller:config:netconf:client:dispatcher + NETCONF + odl-netconfig-client-cfg + prefix:yang + 2014-04-08 + + + urn:opendaylight:l2:types + NETCONF + opendaylight-l2-types + prefix:yang + 2013-08-27 + + + urn:opendaylight:action:types + NETCONF + opendaylight-action-types + prefix:yang + 2013-11-12 + + + urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom + NETCONF + opendaylight-md-sal-dom + prefix:yang + 2013-10-28 + + + urn:opendaylight:params:xml:ns:yang:controller:md:sal:common + NETCONF + opendaylight-md-sal-common + prefix:yang + 2013-10-28 + + + urn:opendaylight:group:types + NETCONF + opendaylight-group-types + prefix:yang + 2013-10-18 + + + urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring-extension + NETCONF + ietf-netconf-monitoring-extension + prefix:yang + 2013-12-10 + + + urn:opendaylight:inventory + NETCONF + opendaylight-inventory + prefix:yang + 2013-08-19 + + + urn:opendaylight:params:xml:ns:yang:controller:netty + NETCONF + netty + prefix:yang + 2013-11-19 + + + urn:opendaylight:model:topology:general + NETCONF + opendaylight-topology + prefix:yang + 2013-10-30 + + + urn:opendaylight:port:statistics + NETCONF + opendaylight-port-statistics + prefix:yang + + + + urn:opendaylight:queue:statistics + NETCONF + opendaylight-queue-statistics + prefix:yang + 2013-12-16 + + + urn:opendaylight:params:xml:ns:yang:controller:config:kitchen-service:impl + NETCONF + kitchen-service-impl + prefix:yang + 2014-01-31 + + + urn:opendaylight:flow:types + NETCONF + opendaylight-flow-types + prefix:yang + 2013-10-26 + + + urn:opendaylight:params:xml:ns:yang:controller:shutdown:impl + NETCONF + shutdown-impl + prefix:yang + 2013-12-18 + + + urn:opendaylight:model:topology:inventory + NETCONF + opendaylight-topology-inventory + prefix:yang + 2013-10-30 + + \ 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 index 0000000000..431787d34c --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/src/test/resources/notification-payload.xml @@ -0,0 +1,14 @@ + +2007-07-08T00:01:00Z + + ui:public-user + 172.23.29.104 + 00:11:00:ff:dd:02 + Chrome 35.0.1916.153 m + + Slovakia + UTC/GMT+2 + + 2014-07-08 11:20:48 + + \ 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 index 0000000000..18a4ead1b5 --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/src/test/resources/schemas/config-test-rpc.yang @@ -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 + and protocol operations, then the + following unqualified XML attribute is supported + within the element, within a or + 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 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 index 0000000000..b13d90f202 --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/src/test/resources/schemas/rpc-notification-subscription.yang @@ -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 index 0000000000..cd732fca70 --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/src/test/resources/schemas/test-module.yang @@ -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 index 0000000000..50d220689f --- /dev/null +++ b/opendaylight/netconf/sal-netconf-connector/src/test/resources/schemas/user-notification.yang @@ -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 diff --git a/opendaylight/netconf/netconf-cli/.gitignore b/opendaylight/netconf/tools/netconf-cli/.gitignore similarity index 100% rename from opendaylight/netconf/netconf-cli/.gitignore rename to opendaylight/netconf/tools/netconf-cli/.gitignore diff --git a/opendaylight/netconf/netconf-cli/README b/opendaylight/netconf/tools/netconf-cli/README similarity index 100% rename from opendaylight/netconf/netconf-cli/README rename to opendaylight/netconf/tools/netconf-cli/README diff --git a/opendaylight/netconf/netconf-cli/README_ODL b/opendaylight/netconf/tools/netconf-cli/README_ODL similarity index 100% rename from opendaylight/netconf/netconf-cli/README_ODL rename to opendaylight/netconf/tools/netconf-cli/README_ODL diff --git a/opendaylight/netconf/netconf-cli/pom.xml b/opendaylight/netconf/tools/netconf-cli/pom.xml similarity index 98% rename from opendaylight/netconf/netconf-cli/pom.xml rename to opendaylight/netconf/tools/netconf-cli/pom.xml index 2d47df078e..14de621b68 100644 --- a/opendaylight/netconf/netconf-cli/pom.xml +++ b/opendaylight/netconf/tools/netconf-cli/pom.xml @@ -9,7 +9,7 @@ org.opendaylight.controller - netconf-subsystem + netconf-tools 0.4.0-SNAPSHOT netconf-cli diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/Cli.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/Cli.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/Cli.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/Cli.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/CommandArgHandlerRegistry.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/CommandArgHandlerRegistry.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/CommandArgHandlerRegistry.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/CommandArgHandlerRegistry.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/Main.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/Main.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/Main.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/Main.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/NetconfDeviceConnectionHandler.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/NetconfDeviceConnectionHandler.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/NetconfDeviceConnectionHandler.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/NetconfDeviceConnectionHandler.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/NetconfDeviceConnectionManager.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/NetconfDeviceConnectionManager.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/NetconfDeviceConnectionManager.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/NetconfDeviceConnectionManager.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/SchemaContextRegistry.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/SchemaContextRegistry.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/SchemaContextRegistry.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/SchemaContextRegistry.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/AbstractCommand.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/AbstractCommand.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/AbstractCommand.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/AbstractCommand.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/Command.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/Command.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/Command.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/Command.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/CommandConstants.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/CommandConstants.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/CommandConstants.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/CommandConstants.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/CommandDispatcher.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/CommandDispatcher.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/CommandDispatcher.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/CommandDispatcher.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/CommandInvocationException.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/CommandInvocationException.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/CommandInvocationException.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/CommandInvocationException.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/input/Input.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/input/Input.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/input/Input.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/input/Input.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/input/InputDefinition.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/input/InputDefinition.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/input/InputDefinition.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/input/InputDefinition.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/local/Close.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/local/Close.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/local/Close.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/local/Close.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/local/Connect.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/local/Connect.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/local/Connect.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/local/Connect.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/local/Disconnect.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/local/Disconnect.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/local/Disconnect.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/local/Disconnect.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/local/Help.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/local/Help.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/local/Help.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/local/Help.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/output/Output.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/output/Output.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/output/Output.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/output/Output.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/output/OutputDefinition.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/output/OutputDefinition.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/output/OutputDefinition.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/output/OutputDefinition.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/remote/RemoteCommand.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/remote/RemoteCommand.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/remote/RemoteCommand.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/remote/RemoteCommand.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/io/BaseConsoleContext.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/io/BaseConsoleContext.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/io/BaseConsoleContext.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/io/BaseConsoleContext.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/io/ConsoleContext.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/io/ConsoleContext.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/io/ConsoleContext.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/io/ConsoleContext.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/io/ConsoleIO.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/io/ConsoleIO.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/io/ConsoleIO.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/io/ConsoleIO.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/io/ConsoleIOImpl.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/io/ConsoleIOImpl.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/io/ConsoleIOImpl.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/io/ConsoleIOImpl.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/io/IOUtil.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/io/IOUtil.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/io/IOUtil.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/io/IOUtil.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/AbstractReader.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/AbstractReader.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/AbstractReader.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/AbstractReader.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/GenericListEntryReader.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/GenericListEntryReader.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/GenericListEntryReader.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/GenericListEntryReader.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/Reader.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/Reader.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/Reader.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/Reader.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/ReadingException.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/ReadingException.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/ReadingException.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/ReadingException.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/custom/ConfigReader.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/custom/ConfigReader.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/custom/ConfigReader.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/custom/ConfigReader.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/custom/EditContentReader.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/custom/EditContentReader.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/custom/EditContentReader.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/custom/EditContentReader.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/custom/FilterReader.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/custom/FilterReader.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/custom/FilterReader.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/custom/FilterReader.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/custom/PasswordReader.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/custom/PasswordReader.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/custom/PasswordReader.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/custom/PasswordReader.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/AnyXmlReader.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/AnyXmlReader.java similarity index 98% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/AnyXmlReader.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/AnyXmlReader.java index a8d2590f56..e4c1fa5649 100644 --- a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/AnyXmlReader.java +++ b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/AnyXmlReader.java @@ -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; diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/BasicDataHolderReader.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/BasicDataHolderReader.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/BasicDataHolderReader.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/BasicDataHolderReader.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/ChoiceReader.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/ChoiceReader.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/ChoiceReader.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/ChoiceReader.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/ContainerReader.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/ContainerReader.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/ContainerReader.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/ContainerReader.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/DecisionReader.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/DecisionReader.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/DecisionReader.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/DecisionReader.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/GenericListReader.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/GenericListReader.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/GenericListReader.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/GenericListReader.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/GenericReader.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/GenericReader.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/GenericReader.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/GenericReader.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/LeafListEntryReader.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/LeafListEntryReader.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/LeafListEntryReader.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/LeafListEntryReader.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/LeafReader.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/LeafReader.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/LeafReader.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/LeafReader.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/ListEntryReader.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/ListEntryReader.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/ListEntryReader.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/ListEntryReader.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/SeparatedNodes.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/SeparatedNodes.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/SeparatedNodes.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/SeparatedNodes.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/UnionTypeReader.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/UnionTypeReader.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/UnionTypeReader.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/reader/impl/UnionTypeReader.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/OutFormatter.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/OutFormatter.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/OutFormatter.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/OutFormatter.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/WriteException.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/WriteException.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/WriteException.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/WriteException.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/Writer.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/Writer.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/Writer.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/Writer.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/custom/DataWriter.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/custom/DataWriter.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/custom/DataWriter.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/custom/DataWriter.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/AbstractWriter.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/AbstractWriter.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/AbstractWriter.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/AbstractWriter.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/AugmentationNodeCliSerializer.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/AugmentationNodeCliSerializer.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/AugmentationNodeCliSerializer.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/AugmentationNodeCliSerializer.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/ChoiceNodeCliSerializer.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/ChoiceNodeCliSerializer.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/ChoiceNodeCliSerializer.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/ChoiceNodeCliSerializer.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/CliOutputFromNormalizedNodeSerializerFactory.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/CliOutputFromNormalizedNodeSerializerFactory.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/CliOutputFromNormalizedNodeSerializerFactory.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/CliOutputFromNormalizedNodeSerializerFactory.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/ContainerNodeCliSerializer.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/ContainerNodeCliSerializer.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/ContainerNodeCliSerializer.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/ContainerNodeCliSerializer.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/LeafNodeCliSerializer.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/LeafNodeCliSerializer.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/LeafNodeCliSerializer.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/LeafNodeCliSerializer.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/LeafSetEntryNodeCliSerializer.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/LeafSetEntryNodeCliSerializer.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/LeafSetEntryNodeCliSerializer.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/LeafSetEntryNodeCliSerializer.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/LeafSetNodeCliSerializer.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/LeafSetNodeCliSerializer.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/LeafSetNodeCliSerializer.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/LeafSetNodeCliSerializer.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/MapEntryNodeCliSerializer.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/MapEntryNodeCliSerializer.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/MapEntryNodeCliSerializer.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/MapEntryNodeCliSerializer.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/MapNodeCliSerializer.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/MapNodeCliSerializer.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/MapNodeCliSerializer.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/MapNodeCliSerializer.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/NodeCliSerializerDispatcher.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/NodeCliSerializerDispatcher.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/NodeCliSerializerDispatcher.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/NodeCliSerializerDispatcher.java diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/NormalizedNodeWriter.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/NormalizedNodeWriter.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/NormalizedNodeWriter.java rename to opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/writer/impl/NormalizedNodeWriter.java diff --git a/opendaylight/netconf/netconf-cli/src/main/resources/logback.xml b/opendaylight/netconf/tools/netconf-cli/src/main/resources/logback.xml similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/resources/logback.xml rename to opendaylight/netconf/tools/netconf-cli/src/main/resources/logback.xml diff --git a/opendaylight/netconf/netconf-cli/src/main/resources/schema/common/ietf-inet-types.yang b/opendaylight/netconf/tools/netconf-cli/src/main/resources/schema/common/ietf-inet-types.yang similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/resources/schema/common/ietf-inet-types.yang rename to opendaylight/netconf/tools/netconf-cli/src/main/resources/schema/common/ietf-inet-types.yang diff --git a/opendaylight/netconf/netconf-cli/src/main/resources/schema/common/netconf-cli-ext.yang b/opendaylight/netconf/tools/netconf-cli/src/main/resources/schema/common/netconf-cli-ext.yang similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/resources/schema/common/netconf-cli-ext.yang rename to opendaylight/netconf/tools/netconf-cli/src/main/resources/schema/common/netconf-cli-ext.yang diff --git a/opendaylight/netconf/netconf-cli/src/main/resources/schema/local/netconf-cli.yang b/opendaylight/netconf/tools/netconf-cli/src/main/resources/schema/local/netconf-cli.yang similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/resources/schema/local/netconf-cli.yang rename to opendaylight/netconf/tools/netconf-cli/src/main/resources/schema/local/netconf-cli.yang diff --git a/opendaylight/netconf/netconf-cli/src/main/resources/schema/remote/ietf-netconf.yang b/opendaylight/netconf/tools/netconf-cli/src/main/resources/schema/remote/ietf-netconf.yang similarity index 100% rename from opendaylight/netconf/netconf-cli/src/main/resources/schema/remote/ietf-netconf.yang rename to opendaylight/netconf/tools/netconf-cli/src/main/resources/schema/remote/ietf-netconf.yang diff --git a/opendaylight/netconf/netconf-cli/src/test/java/org/opendaylight/controller/netconf/cli/ConsoleIOTestImpl.java b/opendaylight/netconf/tools/netconf-cli/src/test/java/org/opendaylight/controller/netconf/cli/ConsoleIOTestImpl.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/test/java/org/opendaylight/controller/netconf/cli/ConsoleIOTestImpl.java rename to opendaylight/netconf/tools/netconf-cli/src/test/java/org/opendaylight/controller/netconf/cli/ConsoleIOTestImpl.java diff --git a/opendaylight/netconf/netconf-cli/src/test/java/org/opendaylight/controller/netconf/cli/NetconfCliTest.java b/opendaylight/netconf/tools/netconf-cli/src/test/java/org/opendaylight/controller/netconf/cli/NetconfCliTest.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/test/java/org/opendaylight/controller/netconf/cli/NetconfCliTest.java rename to opendaylight/netconf/tools/netconf-cli/src/test/java/org/opendaylight/controller/netconf/cli/NetconfCliTest.java diff --git a/opendaylight/netconf/netconf-cli/src/test/java/org/opendaylight/controller/netconf/cli/ValueForMessages.java b/opendaylight/netconf/tools/netconf-cli/src/test/java/org/opendaylight/controller/netconf/cli/ValueForMessages.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/test/java/org/opendaylight/controller/netconf/cli/ValueForMessages.java rename to opendaylight/netconf/tools/netconf-cli/src/test/java/org/opendaylight/controller/netconf/cli/ValueForMessages.java diff --git a/opendaylight/netconf/netconf-cli/src/test/java/org/opendaylight/controller/netconf/cli/io/IOUtilTest.java b/opendaylight/netconf/tools/netconf-cli/src/test/java/org/opendaylight/controller/netconf/cli/io/IOUtilTest.java similarity index 100% rename from opendaylight/netconf/netconf-cli/src/test/java/org/opendaylight/controller/netconf/cli/io/IOUtilTest.java rename to opendaylight/netconf/tools/netconf-cli/src/test/java/org/opendaylight/controller/netconf/cli/io/IOUtilTest.java diff --git a/opendaylight/netconf/netconf-cli/src/test/resources/schema-context/ietf-inet-types.yang b/opendaylight/netconf/tools/netconf-cli/src/test/resources/schema-context/ietf-inet-types.yang similarity index 100% rename from opendaylight/netconf/netconf-cli/src/test/resources/schema-context/ietf-inet-types.yang rename to opendaylight/netconf/tools/netconf-cli/src/test/resources/schema-context/ietf-inet-types.yang diff --git a/opendaylight/netconf/netconf-cli/src/test/resources/schema-context/ietf-netconf.yang b/opendaylight/netconf/tools/netconf-cli/src/test/resources/schema-context/ietf-netconf.yang similarity index 100% rename from opendaylight/netconf/netconf-cli/src/test/resources/schema-context/ietf-netconf.yang rename to opendaylight/netconf/tools/netconf-cli/src/test/resources/schema-context/ietf-netconf.yang diff --git a/opendaylight/netconf/netconf-cli/src/test/resources/schema-context/model1.yang b/opendaylight/netconf/tools/netconf-cli/src/test/resources/schema-context/model1.yang similarity index 100% rename from opendaylight/netconf/netconf-cli/src/test/resources/schema-context/model1.yang rename to opendaylight/netconf/tools/netconf-cli/src/test/resources/schema-context/model1.yang diff --git a/opendaylight/netconf/netconf-cli/src/test/resources/schema-context/model2.yang b/opendaylight/netconf/tools/netconf-cli/src/test/resources/schema-context/model2.yang similarity index 100% rename from opendaylight/netconf/netconf-cli/src/test/resources/schema-context/model2.yang rename to opendaylight/netconf/tools/netconf-cli/src/test/resources/schema-context/model2.yang diff --git a/opendaylight/netconf/netconf-testtool/edit.txt b/opendaylight/netconf/tools/netconf-testtool/edit.txt similarity index 100% rename from opendaylight/netconf/netconf-testtool/edit.txt rename to opendaylight/netconf/tools/netconf-testtool/edit.txt diff --git a/opendaylight/netconf/netconf-testtool/pom.xml b/opendaylight/netconf/tools/netconf-testtool/pom.xml similarity index 99% rename from opendaylight/netconf/netconf-testtool/pom.xml rename to opendaylight/netconf/tools/netconf-testtool/pom.xml index bce0db04e0..36063c054f 100644 --- a/opendaylight/netconf/netconf-testtool/pom.xml +++ b/opendaylight/netconf/tools/netconf-testtool/pom.xml @@ -13,7 +13,7 @@ org.opendaylight.controller - netconf-subsystem + netconf-tools 0.4.0-SNAPSHOT diff --git a/opendaylight/netconf/netconf-testtool/src/main/assembly/stress-client.xml b/opendaylight/netconf/tools/netconf-testtool/src/main/assembly/stress-client.xml similarity index 100% rename from opendaylight/netconf/netconf-testtool/src/main/assembly/stress-client.xml rename to opendaylight/netconf/tools/netconf-testtool/src/main/assembly/stress-client.xml diff --git a/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/AcceptingAuthProvider.java b/opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/AcceptingAuthProvider.java similarity index 100% rename from opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/AcceptingAuthProvider.java rename to opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/AcceptingAuthProvider.java diff --git a/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/DummyMonitoringService.java b/opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/DummyMonitoringService.java similarity index 96% rename from opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/DummyMonitoringService.java rename to opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/DummyMonitoringService.java index e96be6c7ae..c13af4e76a 100644 --- a/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/DummyMonitoringService.java +++ b/opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/DummyMonitoringService.java @@ -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 addedCaps) { - - } - - @Override - public void onCapabilitiesRemoved(Set 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 added, Set removed) { } } diff --git a/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/FakeModuleBuilderCapability.java b/opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/FakeModuleBuilderCapability.java similarity index 100% rename from opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/FakeModuleBuilderCapability.java rename to opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/FakeModuleBuilderCapability.java diff --git a/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/Main.java b/opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/Main.java 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 e273254e0e..c6004835f6 100644 --- a/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/Main.java +++ b/opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/Main.java @@ -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; diff --git a/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/ModuleBuilderCapability.java b/opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/ModuleBuilderCapability.java similarity index 93% rename from opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/ModuleBuilderCapability.java rename to opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/ModuleBuilderCapability.java index fdff6d510e..82cb32b4ea 100644 --- a/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/ModuleBuilderCapability.java +++ b/opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/ModuleBuilderCapability.java @@ -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; diff --git a/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/NetconfDeviceSimulator.java b/opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/NetconfDeviceSimulator.java similarity index 97% rename from opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/NetconfDeviceSimulator.java rename to opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/NetconfDeviceSimulator.java index 3476b11fbe..a3450e8151 100644 --- a/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/NetconfDeviceSimulator.java +++ b/opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/NetconfDeviceSimulator.java @@ -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 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.emptySet()); return new AutoCloseable() { @Override public void close() throws Exception {} diff --git a/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/TestToolUtils.java b/opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/TestToolUtils.java similarity index 100% rename from opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/TestToolUtils.java rename to opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/TestToolUtils.java diff --git a/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/http/perf/AsyncExecutionStrategy.java b/opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/http/perf/AsyncExecutionStrategy.java similarity index 100% rename from opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/http/perf/AsyncExecutionStrategy.java rename to opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/http/perf/AsyncExecutionStrategy.java diff --git a/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/http/perf/Parameters.java b/opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/http/perf/Parameters.java similarity index 100% rename from opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/http/perf/Parameters.java rename to opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/http/perf/Parameters.java diff --git a/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/http/perf/PerfClientCallable.java b/opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/http/perf/PerfClientCallable.java similarity index 100% rename from opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/http/perf/PerfClientCallable.java rename to opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/http/perf/PerfClientCallable.java diff --git a/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/http/perf/RestPerfClient.java b/opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/http/perf/RestPerfClient.java similarity index 100% rename from opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/http/perf/RestPerfClient.java rename to opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/http/perf/RestPerfClient.java diff --git a/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/http/perf/SyncExecutionStrategy.java b/opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/http/perf/SyncExecutionStrategy.java similarity index 100% rename from opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/http/perf/SyncExecutionStrategy.java rename to opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/http/perf/SyncExecutionStrategy.java diff --git a/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/AsyncExecutionStrategy.java b/opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/AsyncExecutionStrategy.java similarity index 98% rename from opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/AsyncExecutionStrategy.java rename to opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/AsyncExecutionStrategy.java index af352b1c2e..20f57a7556 100644 --- a/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/AsyncExecutionStrategy.java +++ b/opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/AsyncExecutionStrategy.java @@ -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; diff --git a/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/ConfigurableClientDispatcher.java b/opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/ConfigurableClientDispatcher.java similarity index 100% rename from opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/ConfigurableClientDispatcher.java rename to opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/ConfigurableClientDispatcher.java diff --git a/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/ExecutionStrategy.java b/opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/ExecutionStrategy.java similarity index 100% rename from opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/ExecutionStrategy.java rename to opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/ExecutionStrategy.java diff --git a/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/Parameters.java b/opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/Parameters.java similarity index 100% rename from opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/Parameters.java rename to opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/Parameters.java diff --git a/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/StressClient.java b/opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/StressClient.java similarity index 99% rename from opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/StressClient.java rename to opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/StressClient.java index 36b947aac4..e2b23d4265 100644 --- a/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/StressClient.java +++ b/opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/StressClient.java @@ -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; diff --git a/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/StressClientCallable.java b/opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/StressClientCallable.java similarity index 100% rename from opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/StressClientCallable.java rename to opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/StressClientCallable.java diff --git a/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/SyncExecutionStrategy.java b/opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/SyncExecutionStrategy.java similarity index 98% rename from opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/SyncExecutionStrategy.java rename to opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/SyncExecutionStrategy.java index 40f39022e6..401e25d833 100644 --- a/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/SyncExecutionStrategy.java +++ b/opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/SyncExecutionStrategy.java @@ -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; diff --git a/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/DataList.java b/opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/DataList.java similarity index 92% rename from opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/DataList.java rename to opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/DataList.java index abc954e807..25ead718a6 100644 --- a/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/DataList.java +++ b/opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/DataList.java @@ -10,7 +10,7 @@ package org.opendaylight.controller.netconf.test.tool.rpc; import java.util.Collections; import java.util.List; -import org.opendaylight.controller.netconf.util.xml.XmlElement; +import org.opendaylight.controller.config.util.xml.XmlElement; public class DataList { diff --git a/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedCommit.java b/opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedCommit.java similarity index 79% rename from opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedCommit.java rename to opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedCommit.java index cb91319699..3b98de65fa 100644 --- a/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedCommit.java +++ b/opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedCommit.java @@ -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.absent()); } diff --git a/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedCreateSubscription.java b/opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedCreateSubscription.java similarity index 96% rename from opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedCreateSubscription.java rename to opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedCreateSubscription.java index 2aa92b8339..8dd2c8884f 100644 --- a/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedCreateSubscription.java +++ b/opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedCreateSubscription.java @@ -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 : notifications.entrySet()) { diff --git a/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedEditConfig.java b/opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedEditConfig.java similarity index 89% rename from opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedEditConfig.java rename to opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedEditConfig.java index 9ba73f4e3a..a0b573d0d7 100644 --- a/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedEditConfig.java +++ b/opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedEditConfig.java @@ -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); diff --git a/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedGet.java b/opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedGet.java similarity index 83% rename from opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedGet.java rename to opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedGet.java index 24d2fcc35e..9474e5e7d5 100644 --- a/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedGet.java +++ b/opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedGet.java @@ -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.absent()); for(final XmlElement e : storage.getConfigList()) { diff --git a/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedGetConfig.java b/opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedGetConfig.java similarity index 84% rename from opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedGetConfig.java rename to opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedGetConfig.java index 985cb4015e..ac17e8f8f0 100644 --- a/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedGetConfig.java +++ b/opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedGetConfig.java @@ -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.absent()); for(final XmlElement e : storage.getConfigList()) { diff --git a/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedLock.java b/opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedLock.java similarity index 79% rename from opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedLock.java rename to opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedLock.java index 71b77a0825..831be73733 100644 --- a/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedLock.java +++ b/opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedLock.java @@ -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.absent()); } diff --git a/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedUnLock.java b/opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedUnLock.java similarity index 79% rename from opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedUnLock.java rename to opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedUnLock.java index 9d970b7bb5..a2528c1332 100644 --- a/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedUnLock.java +++ b/opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/rpc/SimulatedUnLock.java @@ -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.absent()); } diff --git a/opendaylight/netconf/netconf-testtool/src/main/resources/99-netconf-connector-simulated.xml b/opendaylight/netconf/tools/netconf-testtool/src/main/resources/99-netconf-connector-simulated.xml similarity index 100% rename from opendaylight/netconf/netconf-testtool/src/main/resources/99-netconf-connector-simulated.xml rename to opendaylight/netconf/tools/netconf-testtool/src/main/resources/99-netconf-connector-simulated.xml diff --git a/opendaylight/netconf/netconf-testtool/src/main/resources/logback.xml b/opendaylight/netconf/tools/netconf-testtool/src/main/resources/logback.xml similarity index 100% rename from opendaylight/netconf/netconf-testtool/src/main/resources/logback.xml rename to opendaylight/netconf/tools/netconf-testtool/src/main/resources/logback.xml diff --git a/opendaylight/netconf/netconf-testtool/src/main/resources/org.ops4j.pax.url.mvn.cfg b/opendaylight/netconf/tools/netconf-testtool/src/main/resources/org.ops4j.pax.url.mvn.cfg similarity index 100% rename from opendaylight/netconf/netconf-testtool/src/main/resources/org.ops4j.pax.url.mvn.cfg rename to opendaylight/netconf/tools/netconf-testtool/src/main/resources/org.ops4j.pax.url.mvn.cfg diff --git a/opendaylight/netconf/tools/pom.xml b/opendaylight/netconf/tools/pom.xml new file mode 100644 index 0000000000..a8bdd24c21 --- /dev/null +++ b/opendaylight/netconf/tools/pom.xml @@ -0,0 +1,106 @@ + + + 4.0.0 + + + org.opendaylight.controller + netconf-subsystem + 0.4.0-SNAPSHOT + ../ + + netconf-tools + + 0.4.0-SNAPSHOT + pom + ${project.artifactId} + + + netconf-cli + netconf-testtool + + + + + + + org.apache.felix + maven-bundle-plugin + true + + + ${project.groupId}.${project.artifactId} + + + + + org.opendaylight.yangtools + yang-maven-plugin + ${yangtools.version} + + + org.opendaylight.yangtools + maven-sal-api-gen-plugin + ${yangtools.version} + + + + + + generate-sources + + + src/main/yang + + + org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl + ${salGeneratorPath} + + + org.opendaylight.yangtools.yang.unified.doc.generator.maven.DocumentationGeneratorImpl + ${project.build.directory}/site/models + + + true + + + + + + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + + false + true + checkstyle-logging.xml + true + true + ${project.basedir} + **\/*.java,**\/*.xml,**\/*.ini,**\/*.sh,**\/*.bat,**\/*.yang + **\/target\/,**\/bin\/,**\/target-ide\/,**\/${jmxGeneratorPath}\/,**\/${salGeneratorPath}\/,**\/netconf\/test\/tool\/Main.java, **\/netconf\/test\/tool\/client\/stress\/StressClient.java + + + + org.opendaylight.yangtools + checkstyle-logging + ${yangtools.version} + + + + + + check + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + -- 2.36.6