Merge changes I4a9861ed,I61c130b9
authorEd Warnicke <eaw@cisco.com>
Thu, 1 May 2014 11:16:13 +0000 (11:16 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Thu, 1 May 2014 11:16:13 +0000 (11:16 +0000)
* changes:
  Bug 509: Fixed DataTransactionListener support.
  Bug 509: Fixed Backwards compatibility bugs with datastore.

260 files changed:
opendaylight/commons/opendaylight/pom.xml
opendaylight/commons/protocol-framework/src/test/java/org/opendaylight/controller/config/yang/protocol/framework/NeverReconnectStrategyModuleTest.java
opendaylight/commons/protocol-framework/src/test/java/org/opendaylight/controller/config/yang/protocol/framework/ReconnectImmediatelyStrategyModuleTest.java
opendaylight/commons/protocol-framework/src/test/java/org/opendaylight/controller/config/yang/protocol/framework/TimedReconnectStrategyModuleTest.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/CloseableServiceReferenceReadableRegistry.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigRegistryImpl.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionControllerImpl.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionControllerInternal.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/DeadlockMonitor.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ModuleInternalInfo.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/SearchableServiceReferenceWritableRegistry.java [new file with mode: 0644]
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ServiceReferenceRegistryImpl.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/dependencyresolver/DependencyResolverManager.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/dependencyresolver/ModuleInternalTransactionalInfo.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/factoriesresolver/HierarchicalConfigMBeanFactoriesHolder.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/jmx/ServiceReference.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/BeanToOsgiServiceManager.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/util/InterfacesHelper.java
opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/ConfigRegistryImplTest.java
opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/AbstractConfigTest.java
opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionControllerImplTest.java
opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionManagerImplTest.java
opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/ServiceReferenceRegistryImplTest.java
opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/dependencyresolver/DependencyResolverManagerTest.java
opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/factoriesresolver/HardcodedModuleFactoriesResolver.java
opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/parallelapsp/test/DependentWiringTest.java
opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/parallelapsp/test/MockedDependenciesTest.java
opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/scheduledthreadpool/test/AbstractScheduledTest.java
opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/threadpool/TestingFixedThreadPool.java
opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/threadpool/test/ShutdownTest.java [new file with mode: 0644]
opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/threadpool/test/SimpleConfigurationTest.java
opendaylight/config/config-persister-api/src/main/java/org/opendaylight/controller/config/persist/api/PropertiesProvider.java
opendaylight/config/config-persister-api/src/test/java/org/opendaylight/controller/config/persist/test/PropertiesProviderTest.java
opendaylight/config/logback-config/src/test/java/org/opendaylight/controller/config/yang/logback/config/LogbackModuleTest.java
opendaylight/config/logback-config/src/test/java/org/opendaylight/controller/config/yang/logback/config/LogbackModuleWithInitialConfigurationTest.java
opendaylight/config/logback-config/src/test/java/org/opendaylight/controller/config/yang/logback/config/LogbackWithXmlConfigModuleTest.java
opendaylight/config/netty-event-executor-config/src/test/java/org/opendaylight/controller/config/yang/netty/eventexecutor/GlobalEventExecutorModuleTest.java
opendaylight/config/netty-threadgroup-config/src/test/java/org/opendaylight/controller/config/yang/netty/threadgroup/NettyThreadgroupModuleTest.java
opendaylight/config/shutdown-impl/src/main/java/org/opendaylight/controller/config/yang/shutdown/impl/ShutdownServiceImpl.java
opendaylight/config/shutdown-impl/src/test/java/org/opendaylight/controller/config/yang/shutdown/impl/ShutdownTest.java
opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/async/AsyncEventBusConfigBeanTest.java
opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/eventbus/SyncEventBusConfigBeanTest.java
opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/fixed/FixedThreadPoolConfigBeanTest.java
opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/flexible/FlexibleThreadPoolConfigBeanTest.java
opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/naming/NamingThreadPoolFactoryConfigBeanTest.java
opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/scheduled/ScheduledThreadPoolConfigBeanTest.java
opendaylight/config/yang-jmx-generator-it/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/it/ITTest.java
opendaylight/config/yang-jmx-generator-plugin/pom.xml
opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/gofactory/AbsFactoryGeneratedObjectFactory.groovy [deleted file]
opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/gofactory/AbsFactoryGeneratedObjectFactory.java [new file with mode: 0644]
opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/gofactory/AbsModuleGeneratedObjectFactory.groovy [deleted file]
opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/gofactory/AbsModuleGeneratedObjectFactory.java [new file with mode: 0644]
opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/gofactory/GenericGeneratedObjectFactory.groovy [deleted file]
opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/gofactory/GenericGeneratedObjectFactory.java [new file with mode: 0644]
opendaylight/config/yang-test-plugin/src/main/java/org/opendaylight/controller/config/yang/test/plugin/ProcessSources.java
opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/DepTestImplModule.java
opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/DepTestImplModuleFactory.java
opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/IdentityTestModule.java
opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/IdentityTestModuleFactory.java
opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModule.java
opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleFactory.java
opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleUtil.java
opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/TestImplModule.java
opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/TestImplModuleFactory.java
opendaylight/config/yang-test/src/test/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleTest.java
opendaylight/distribution/opendaylight/src/main/resources/configuration/config.ini
opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/01-md-sal.xml
opendaylight/md-sal/forwardingrules-manager/pom.xml
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/AbstractChangeListener.java [new file with mode: 0644]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/AbstractTransaction.xtend [deleted file]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/FRMActivator.java [new file with mode: 0644]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/FRMActivator.xtend [deleted file]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowChangeListener.java [new file with mode: 0644]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowCommitHandler.xtend [deleted file]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowProvider.java [new file with mode: 0644]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowProvider.xtend [deleted file]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowTransaction.xtend [deleted file]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowTransactionValidator.java
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupChangeListener.java [new file with mode: 0644]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupCommitHandler.xtend [deleted file]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupProvider.java [new file with mode: 0644]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupProvider.xtend [deleted file]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupTransaction.xtend [deleted file]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupTransactionValidator.java
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterChangeListener.java [new file with mode: 0644]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterCommitHandler.xtend [deleted file]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterProvider.java [new file with mode: 0644]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterProvider.xtend [deleted file]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterTransaction.xtend [deleted file]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterTransactionValidator.java
opendaylight/md-sal/sal-binding-dom-it/pom.xml
opendaylight/md-sal/sal-binding-it/src/test/java/org/opendaylight/controller/test/sal/binding/it/NotificationTest.java [moved from opendaylight/md-sal/sal-binding-it/src/test/java/org/opendaylight/controller/test/sal/binding/it/NoficationTest.java with 99% similarity]
opendaylight/md-sal/sal-binding-it/src/test/resources/controller.xml
opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/service/ImmutableDataChangeEvent.java
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDevice.java
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceListener.java
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfMapping.java
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfRemoteSchemaSourceProvider.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonReader.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/RestUtil.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/XmlReader.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/IdentityValuesDTO.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestCodec.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.xtend
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/XmlAndJsonToCnSnLeafRefTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/leafref/json/jsondata.json [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/leafref/xml/xmldata.xml [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/leafref/yang/leafref-module.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/leafref/yang/referenced-module.yang [new file with mode: 0644]
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/AbstractListeningStatsTracker.java
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/AbstractStatsTracker.java
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowStatsTracker.java
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowTableStatsTracker.java
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/GroupDescStatsTracker.java
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/GroupStatsTracker.java
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/MeterConfigStatsTracker.java
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/MeterStatsTracker.java
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/NodeConnectorStatsTracker.java
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/NodeStatisticsHandler.java
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/QueueStatsTracker.java
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsProvider.java
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsRequestScheduler.java [new file with mode: 0644]
opendaylight/md-sal/topology-lldp-discovery/pom.xml
opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPActivator.java [new file with mode: 0644]
opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPActivator.xtend [deleted file]
opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPDiscoveryProvider.java [new file with mode: 0644]
opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPDiscoveryProvider.xtend [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/AttributeIfcSwitchStatement.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/AttributeConfigElement.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ObjectNameAttributeReadingStrategy.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ObjectXmlReader.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleIdentityRefAttributeReadingStrategy.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ArrayAttributeMappingStrategy.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/CompositeAttributeMappingStrategy.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectMapper.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectNameAttributeMappingStrategy.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/SimpleAttributeMappingStrategy.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/UnionCompositeAttributeMappingStrategy.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ArrayAttributeResolvingStrategy.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/AttributeResolvingStrategy.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/CompositeAttributeResolvingStrategy.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectResolver.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/SimpleAttributeResolvingStrategy.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/UnionCompositeAttributeResolvingStrategy.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/AbstractAttributeWritingStrategy.java [new file with mode: 0644]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/CompositeAttributeWritingStrategy.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/ObjectXmlWriter.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/RuntimeBeanEntryWritingStrategy.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleAttributeWritingStrategy.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleBinaryAttributeWritingStrategy.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleIdentityRefAttributeWritingStrategy.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Config.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfig.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleConfig.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ServiceRegistryWrapper.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Services.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/rpc/ModuleRpcs.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/InstanceRuntime.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/ModuleRuntime.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/Runtime.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/AbstractConfigNetconfOperation.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/DeleteEditConfigStrategy.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfig.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigXmlParser.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditStrategyType.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MergeEditConfigStrategy.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/ReplaceEditConfigStrategy.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/get/Get.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/getconfig/GetConfig.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpc.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpcElementResolved.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/Activator.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationProvider.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationServiceFactoryImpl.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationServiceImpl.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/transactions/TransactionProvider.java
opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java
opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/ConfigPersisterNotificationHandler.java
opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/PersisterAggregator.java
opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/PropertiesProviderAdapterImpl.java
opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/osgi/ConfigPersisterActivator.java
opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/osgi/ConfigPersisterTest.java
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
opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClient.java [new file with mode: 0644]
opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClientDispatcher.java
opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClientSession.java
opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClientSessionNegotiator.java
opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClientSessionNegotiatorFactory.java
opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/SimpleNetconfClientSessionListener.java
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/CapabilityProviderImpl.java
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/DefaultCommitNotificationProducer.java
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionListener.java
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionNegotiator.java
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionNegotiatorFactory.java
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultCommit.java
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfImplActivator.java
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfMonitoringServiceImpl.java
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfOperationRouterImpl.java
opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/ConcurrentClientsTest.java
opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/chunked1.txt [deleted file]
opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/chunked2.txt [deleted file]
opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/chunked3.txt [deleted file]
opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/chunked4.txt [deleted file]
opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/chunked5.txt [deleted file]
opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/listener/databaseinteractions/jolokia_config_bean_response.txt [deleted file]
opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/listener/databaseinteractions/jolokia_lookupConfigBeans.txt [deleted file]
opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/notused/client_commit.xml [deleted file]
opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/notused/client_lock_candidate.xml [deleted file]
opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/notused/client_lock_running.xml [deleted file]
opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/notused/client_modify_candidate.xml [deleted file]
opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/notused/client_unlock_candidate.xml [deleted file]
opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/notused/client_unlock_running.xml [deleted file]
opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/notused/server_error_missing_attribute.xml [deleted file]
opendaylight/netconf/netconf-impl/src/test/resources/testConfigs/input.json [deleted file]
opendaylight/netconf/netconf-impl/src/test/resources/testConfigs/input.xml [deleted file]
opendaylight/netconf/netconf-impl/src/test/resources/testConfigs/inputList.xml [deleted file]
opendaylight/netconf/netconf-impl/src/test/resources/testConfigs/inputMap.xml [deleted file]
opendaylight/netconf/netconf-impl/src/test/resources/testConfigs/inputMultiple.xml [deleted file]
opendaylight/netconf/netconf-impl/src/test/resources/testConfigs/inputSetter.xml [deleted file]
opendaylight/netconf/netconf-impl/src/test/resources/testConfigs/inputSetterList.xml [deleted file]
opendaylight/netconf/netconf-impl/src/test/resources/testConfigs/inputSetterMap.xml [deleted file]
opendaylight/netconf/netconf-impl/src/test/resources/testConfigs/map.json [deleted file]
opendaylight/netconf/netconf-it/pom.xml
opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfConfigPersisterITTest.java
opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITSecureTest.java
opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java
opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfMonitoringITTest.java
opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/pax/IdentityRefNetconfTest.java
opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/HandlingPriority.java
opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/Get.java
opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/MonitoringConstants.java
opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/osgi/NetconfMonitoringActivator.java
opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/osgi/NetconfMonitoringOperationService.java
opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/NetconfSSHServer.java
opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/AuthProvider.java
opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/AuthProviderInterface.java
opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/osgi/NetconfSSHActivator.java
opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/threads/SocketThread.java
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/AbstractNetconfSession.java
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/AbstractNetconfSessionNegotiator.java
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/ChunkedFramingMechanismEncoder.java
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/EOMFramingMechanismEncoder.java
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/FramingMechanismHandlerFactory.java
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/NetconfChunkAggregator.java
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/NetconfEOMAggregator.java
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/NetconfEXIToMessageDecoder.java
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/NetconfXMLToHelloMessageDecoder.java
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/NetconfXMLToMessageDecoder.java
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/ssh/authentication/LoginPassword.java
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/ssh/client/SshClient.java
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/ssh/client/SshClientAdapter.java
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/ssh/virtualsocket/ChannelInputStream.java
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/messages/NetconfHelloMessage.java
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/messages/NetconfMessageConstants.java
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/messages/SendErrorExceptionUtil.java
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/osgi/NetconfConfigUtil.java
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlElement.java
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlNetconfConstants.java
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlUtil.java
opendaylight/switchmanager/implementation/src/main/java/org/opendaylight/controller/switchmanager/internal/SwitchManager.java

index f30d4b005ad54e0e87d31a102faa8b5961b1513e..e0891662ea95b8204e318f5214ccb169de5c0c61 100644 (file)
         <artifactId>jersey-core</artifactId>
         <version>${jersey.version}</version>
       </dependency>
-      <dependency>
-        <groupId>javax.ws.rs</groupId>
-        <artifactId>jsr311-api</artifactId>
-        <version>${jsr311.api.version}</version>
-      </dependency>
       <dependency>
         <groupId>com.sun.jersey</groupId>
         <artifactId>jersey-server</artifactId>
         <artifactId>netty-transport</artifactId>
         <version>${netty.version}</version>
       </dependency>
+      <dependency>
+        <groupId>javax.ws.rs</groupId>
+        <artifactId>jsr311-api</artifactId>
+        <version>${jsr311.api.version}</version>
+      </dependency>
       <dependency>
         <groupId>orbit</groupId>
         <artifactId>javax.activation</artifactId>
index d77c9aa962c21ed5267f30b49662d26bbb9cd775..1148c6bebe5f381d825be0003c6904b3b3e12153 100644 (file)
@@ -7,12 +7,6 @@
  */
 package org.opendaylight.controller.config.yang.protocol.framework;
 
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.ObjectName;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.opendaylight.controller.config.api.ConflictingVersionException;
@@ -23,6 +17,12 @@ import org.opendaylight.controller.config.manager.impl.factoriesresolver.Hardcod
 import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
 import org.opendaylight.controller.config.yang.netty.eventexecutor.GlobalEventExecutorModuleFactory;
 
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.ObjectName;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
 public class NeverReconnectStrategyModuleTest extends AbstractConfigTest {
 
     private static final String INSTANCE_NAME = "never-reconect-strategy-factory-impl";
@@ -30,7 +30,7 @@ public class NeverReconnectStrategyModuleTest extends AbstractConfigTest {
 
     @Before
     public void setUp() throws Exception {
-        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(
+        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,
                 new NeverReconnectStrategyFactoryModuleFactory(), new GlobalEventExecutorModuleFactory()));
     }
 
index 24a0e912a3263d676c9757b6f92583c2358ca5ee..9beadc4dbb2b7f8aa34a0390e9aa65614168d666 100644 (file)
@@ -29,7 +29,7 @@ public class ReconnectImmediatelyStrategyModuleTest extends AbstractConfigTest {
 
     @Before
     public void setUp() throws Exception {
-        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(
+        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,
                 new ReconnectImmediatelyStrategyFactoryModuleFactory(), new GlobalEventExecutorModuleFactory()));
     }
 
index d051a00a12f09a66ffb8c16db4b059f72d46e3c2..a8cdff711905ead55193384baed9362d1f7df909 100644 (file)
@@ -7,15 +7,6 @@
  */
 package org.opendaylight.controller.config.yang.protocol.framework;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.math.BigDecimal;
-
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.ObjectName;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.opendaylight.controller.config.api.ConflictingVersionException;
@@ -26,6 +17,14 @@ import org.opendaylight.controller.config.manager.impl.factoriesresolver.Hardcod
 import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
 import org.opendaylight.controller.config.yang.netty.eventexecutor.GlobalEventExecutorModuleFactory;
 
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.ObjectName;
+import java.math.BigDecimal;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
 public class TimedReconnectStrategyModuleTest extends AbstractConfigTest {
 
     private static final String INSTANCE_NAME = "timed-reconect-stategy-facotry-impl";
@@ -33,7 +32,7 @@ public class TimedReconnectStrategyModuleTest extends AbstractConfigTest {
 
     @Before
     public void setUp() throws Exception {
-        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(
+        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,
                 new TimedReconnectStrategyFactoryModuleFactory(), new GlobalEventExecutorModuleFactory()));
     }
 
index 8c325079d30e185200398fbc537550d0d9b37682..bf010bb3a603e46d995bc8656a0d5f52ca368f31 100644 (file)
@@ -9,9 +9,12 @@ package org.opendaylight.controller.config.manager.impl;
 
 import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry;
 
+/**
+ * Interface exposing some internal state on top of ServiceReferenceReadableRegistry. This will
+ * not be exposed via JMX.
+ */
 public interface CloseableServiceReferenceReadableRegistry  extends AutoCloseable, ServiceReferenceReadableRegistry {
 
-
     void close();
 
 }
index e914162671e811682271d42bcbccbe4e89c47947..8f85972d050cd9d3dc0e8460c21baf3506913db8 100644 (file)
@@ -11,8 +11,8 @@ import com.google.common.collect.Maps;
 import org.opendaylight.controller.config.api.ConflictingVersionException;
 import org.opendaylight.controller.config.api.ModuleIdentifier;
 import org.opendaylight.controller.config.api.RuntimeBeanRegistratorAwareModule;
-import org.opendaylight.controller.config.api.ServiceReferenceWritableRegistry;
 import org.opendaylight.controller.config.api.ValidationException;
+import org.opendaylight.controller.config.api.annotations.ServiceInterfaceAnnotation;
 import org.opendaylight.controller.config.api.jmx.CommitStatus;
 import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
 import org.opendaylight.controller.config.manager.impl.dependencyresolver.DestroyedModule;
@@ -159,13 +159,24 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
             }
         };
 
-        Map<String, Map.Entry<ModuleFactory, BundleContext>> allCurrentFactories = Collections.unmodifiableMap(
+        Map<String, Map.Entry<ModuleFactory, BundleContext>> allCurrentFactories = new HashMap<>(
                 resolver.getAllFactories());
 
+        // add all factories that disappeared from SR but are still committed
+        for (ModuleInternalInfo moduleInternalInfo : currentConfig.getEntries()) {
+            String name = moduleInternalInfo.getModuleFactory().getImplementationName();
+            if (allCurrentFactories.containsKey(name) == false) {
+                logger.trace("Factory {} not found in SR, using reference from previous commit", name);
+                allCurrentFactories.put(name,
+                        Maps.immutableEntry(moduleInternalInfo.getModuleFactory(), moduleInternalInfo.getBundleContext()));
+            }
+        }
+        allCurrentFactories = Collections.unmodifiableMap(allCurrentFactories);
+
         // closed by transaction controller
         ConfigTransactionLookupRegistry txLookupRegistry = new ConfigTransactionLookupRegistry(new TransactionIdentifier(
                 transactionName), factory, allCurrentFactories);
-        ServiceReferenceWritableRegistry writableRegistry = ServiceReferenceRegistryImpl.createSRWritableRegistry(
+        SearchableServiceReferenceWritableRegistry writableRegistry = ServiceReferenceRegistryImpl.createSRWritableRegistry(
                 readableSRRegistry, txLookupRegistry, allCurrentFactories);
 
         ConfigTransactionControllerInternal transactionController = new ConfigTransactionControllerImpl(
@@ -216,16 +227,14 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
         // non recoverable from here:
         try {
             return secondPhaseCommit(configTransactionController, commitInfo, configTransactionControllerEntry.getValue());
-        } catch (Throwable t) { // some libs throw Errors: e.g.
+        } catch (Error | RuntimeException t) { // some libs throw Errors: e.g.
             // javax.xml.ws.spi.FactoryFinder$ConfigurationError
             isHealthy = false;
             logger.error("Configuration Transaction failed on 2PC, server is unhealthy", t);
             if (t instanceof RuntimeException) {
                 throw (RuntimeException) t;
-            } else if (t instanceof Error) {
-                throw (Error) t;
             } else {
-                throw new RuntimeException(t);
+                throw (Error) t;
             }
         }
     }
@@ -344,24 +353,20 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
 
             // register to JMX
             try {
-                newModuleJMXRegistrator.registerMBean(newReadableConfigBean,
-                        primaryReadOnlyON);
+                newModuleJMXRegistrator.registerMBean(newReadableConfigBean, primaryReadOnlyON);
             } catch (InstanceAlreadyExistsException e) {
-                throw new IllegalStateException(e);
+                throw new IllegalStateException("Possible code error, already registered:" + primaryReadOnlyON,e);
             }
 
-            // register to OSGi
+            // register services to OSGi
+            Map<String, ServiceInterfaceAnnotation> annotationMapping = configTransactionController.getWritableRegistry().findServiceInterfaces(moduleIdentifier);
+            BundleContext bc = configTransactionController.getModuleFactoryBundleContext(
+                    entry.getModuleFactory().getImplementationName());
             if (osgiRegistration == null) {
-                ModuleFactory moduleFactory = entry.getModuleFactory();
-                if (moduleFactory != null) {
-                    BundleContext bc = configTransactionController.
-                            getModuleFactoryBundleContext(moduleFactory.getImplementationName());
-                    osgiRegistration = beanToOsgiServiceManager.registerToOsgi(realModule.getClass(),
-                            newReadableConfigBean.getInstance(), entry.getIdentifier(), bc);
-                } else {
-                    throw new NullPointerException(entry.getIdentifier().getFactoryName() + " ModuleFactory not found.");
-                }
-
+                osgiRegistration = beanToOsgiServiceManager.registerToOsgi(
+                        newReadableConfigBean.getInstance(), moduleIdentifier, bc, annotationMapping);
+            } else {
+                osgiRegistration.updateRegistrations(annotationMapping, bc, instance);
             }
 
             RootRuntimeBeanRegistratorImpl runtimeBeanRegistrator = runtimeRegistrators
@@ -369,7 +374,7 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
             ModuleInternalInfo newInfo = new ModuleInternalInfo(
                     entry.getIdentifier(), newReadableConfigBean, osgiRegistration,
                     runtimeBeanRegistrator, newModuleJMXRegistrator,
-                    orderingIdx, entry.isDefaultBean());
+                    orderingIdx, entry.isDefaultBean(), entry.getModuleFactory(), entry.getBundleContext());
 
             newConfigEntries.put(realModule, newInfo);
             orderingIdx++;
index bc4de5cc156580741caf9e5abcbfbd32e07556ce..3e231201821619d36c95b0cc481938b5eda042f4 100644 (file)
@@ -7,9 +7,25 @@
  */
 package org.opendaylight.controller.config.manager.impl;
 
+import static java.lang.String.format;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.GuardedBy;
+import javax.management.DynamicMBean;
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.InstanceNotFoundException;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
 import org.opendaylight.controller.config.api.DependencyResolver;
 import org.opendaylight.controller.config.api.ModuleIdentifier;
-import org.opendaylight.controller.config.api.ServiceReferenceWritableRegistry;
 import org.opendaylight.controller.config.api.ValidationException;
 import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
 import org.opendaylight.controller.config.manager.impl.dependencyresolver.DependencyResolverManager;
@@ -28,25 +44,7 @@ import org.osgi.framework.BundleContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import javax.annotation.Nullable;
-import javax.annotation.concurrent.GuardedBy;
-import javax.management.DynamicMBean;
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.InstanceNotFoundException;
-import javax.management.MBeanServer;
-import javax.management.ObjectName;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicBoolean;
-
 import static com.google.common.base.Preconditions.checkNotNull;
-import static java.lang.String.format;
-
 /**
  * This is a JMX bean representing current transaction. It contains
  * transaction identifier, unique version and parent version for
@@ -82,13 +80,13 @@ class ConfigTransactionControllerImpl implements
     private final boolean blankTransaction;
 
     @GuardedBy("this")
-    private final ServiceReferenceWritableRegistry writableSRRegistry;
+    private final SearchableServiceReferenceWritableRegistry writableSRRegistry;
 
     public ConfigTransactionControllerImpl(ConfigTransactionLookupRegistry txLookupRegistry,
                                            long parentVersion, CodecRegistry codecRegistry, long currentVersion,
                                            Map<String, Entry<ModuleFactory, BundleContext>> currentlyRegisteredFactories,
                                            MBeanServer transactionsMBeanServer, MBeanServer configMBeanServer,
-                                           boolean blankTransaction, ServiceReferenceWritableRegistry writableSRRegistry) {
+                                           boolean blankTransaction, SearchableServiceReferenceWritableRegistry  writableSRRegistry) {
         this.txLookupRegistry = txLookupRegistry;
         String transactionName = txLookupRegistry.getTransactionIdentifier().getName();
         this.controllerON = ObjectNameUtil.createTransactionControllerON(transactionName);
@@ -139,14 +137,16 @@ class ConfigTransactionControllerImpl implements
         }
         // add default modules
         for (ModuleFactory moduleFactory : toBeAdded) {
+            BundleContext bundleContext = getModuleFactoryBundleContext(moduleFactory.getImplementationName());
             Set<? extends Module> defaultModules = moduleFactory.getDefaultModules(dependencyResolverManager,
-                    getModuleFactoryBundleContext(moduleFactory.getImplementationName()));
+                    bundleContext);
             for (Module module : defaultModules) {
                 // ensure default module to be registered to jmx even if its module factory does not use dependencyResolverFactory
                 DependencyResolver dependencyResolver = dependencyResolverManager.getOrCreate(module.getIdentifier());
                 try {
                     boolean defaultBean = true;
-                    putConfigBeanToJMXAndInternalMaps(module.getIdentifier(), module, moduleFactory, null, dependencyResolver, defaultBean);
+                    putConfigBeanToJMXAndInternalMaps(module.getIdentifier(), module, moduleFactory, null,
+                            dependencyResolver, defaultBean, bundleContext);
                 } catch (InstanceAlreadyExistsException e) {
                     throw new IllegalStateException(e);
                 }
@@ -163,21 +163,26 @@ class ConfigTransactionControllerImpl implements
     }
 
 
-    private synchronized void copyExistingModule(
-            ModuleInternalInfo oldConfigBeanInfo)
-            throws InstanceAlreadyExistsException {
+    private synchronized void copyExistingModule(ModuleInternalInfo oldConfigBeanInfo) throws InstanceAlreadyExistsException {
+
         transactionStatus.checkNotCommitStarted();
         transactionStatus.checkNotAborted();
         ModuleIdentifier moduleIdentifier = oldConfigBeanInfo.getIdentifier();
         dependencyResolverManager.assertNotExists(moduleIdentifier);
 
-        ModuleFactory moduleFactory = factoriesHolder
-                .findByModuleName(moduleIdentifier.getFactoryName());
+        ModuleFactory moduleFactory;
+        BundleContext bc;
+        try {
+            moduleFactory = factoriesHolder.findByModuleName(moduleIdentifier.getFactoryName());
+            bc = getModuleFactoryBundleContext(moduleFactory.getImplementationName());
+        } catch (InstanceNotFoundException e) {
+            throw new IllegalStateException(e);
+        }
 
         Module module;
         DependencyResolver dependencyResolver = dependencyResolverManager.getOrCreate(moduleIdentifier);
         try {
-            BundleContext bc = getModuleFactoryBundleContext(moduleFactory.getImplementationName());
+
             module = moduleFactory.createModule(
                     moduleIdentifier.getInstanceName(), dependencyResolver,
                     oldConfigBeanInfo.getReadableModule(), bc);
@@ -187,7 +192,7 @@ class ConfigTransactionControllerImpl implements
                     oldConfigBeanInfo, moduleFactory), e);
         }
         putConfigBeanToJMXAndInternalMaps(moduleIdentifier, module, moduleFactory, oldConfigBeanInfo, dependencyResolver,
-                oldConfigBeanInfo.isDefaultBean());
+                oldConfigBeanInfo.isDefaultBean(), bc);
     }
 
     @Override
@@ -200,19 +205,26 @@ class ConfigTransactionControllerImpl implements
         dependencyResolverManager.assertNotExists(moduleIdentifier);
 
         // find factory
-        ModuleFactory moduleFactory = factoriesHolder.findByModuleName(factoryName);
+        ModuleFactory moduleFactory;
+        try {
+            moduleFactory = factoriesHolder.findByModuleName(factoryName);
+        } catch (InstanceNotFoundException e) {
+            throw new IllegalArgumentException(e);
+        }
         DependencyResolver dependencyResolver = dependencyResolverManager.getOrCreate(moduleIdentifier);
+        BundleContext bundleContext = getModuleFactoryBundleContext(moduleFactory.getImplementationName());
         Module module = moduleFactory.createModule(instanceName, dependencyResolver,
-                getModuleFactoryBundleContext(moduleFactory.getImplementationName()));
+                bundleContext);
         boolean defaultBean = false;
         return putConfigBeanToJMXAndInternalMaps(moduleIdentifier, module,
-                moduleFactory, null, dependencyResolver, defaultBean);
+                moduleFactory, null, dependencyResolver, defaultBean, bundleContext);
     }
 
     private synchronized ObjectName putConfigBeanToJMXAndInternalMaps(
             ModuleIdentifier moduleIdentifier, Module module,
             ModuleFactory moduleFactory,
-            @Nullable ModuleInternalInfo maybeOldConfigBeanInfo, DependencyResolver dependencyResolver, boolean isDefaultBean)
+            @Nullable ModuleInternalInfo maybeOldConfigBeanInfo, DependencyResolver dependencyResolver,
+            boolean isDefaultBean, BundleContext bundleContext)
             throws InstanceAlreadyExistsException {
 
         logger.debug("Adding module {} to transaction {}", moduleIdentifier, this);
@@ -237,7 +249,7 @@ class ConfigTransactionControllerImpl implements
 
         dependencyResolverManager.put(
                 moduleIdentifier, module, moduleFactory,
-                maybeOldConfigBeanInfo, transactionModuleJMXRegistration, isDefaultBean);
+                maybeOldConfigBeanInfo, transactionModuleJMXRegistration, isDefaultBean, bundleContext);
         return writableON;
     }
 
@@ -263,14 +275,15 @@ class ConfigTransactionControllerImpl implements
         logger.debug("Destroying module {} in transaction {}", moduleIdentifier, this);
         transactionStatus.checkNotAborted();
 
+        ModuleInternalTransactionalInfo found = dependencyResolverManager.findModuleInternalTransactionalInfo(moduleIdentifier);
         if (blankTransaction == false) {
-            ModuleInternalTransactionalInfo found =
-                    dependencyResolverManager.findModuleInternalTransactionalInfo(moduleIdentifier);
+
             if (found.isDefaultBean()) {
                 logger.warn("Warning: removing default bean. This will be forbidden in next version of config-subsystem");
             }
         }
         // first remove refNames, it checks for objectname existence
+
         try {
             writableSRRegistry.removeServiceReferences(
                     ObjectNameUtil.createTransactionModuleON(getTransactionName(), moduleIdentifier));
@@ -570,7 +583,7 @@ class ConfigTransactionControllerImpl implements
     }
 
     @Override
-    public ServiceReferenceWritableRegistry getWritableRegistry() {
+    public SearchableServiceReferenceWritableRegistry  getWritableRegistry() {
         return writableSRRegistry;
     }
 
index f6164e32561d7ad5688abde93ac6cb4bc96cbec1..c9df3409db46366acbae22d44166e05202e844fc 100644 (file)
@@ -7,17 +7,15 @@
  */
 package org.opendaylight.controller.config.manager.impl;
 
-import java.util.Collection;
-import java.util.List;
-
-import javax.management.ObjectName;
-
 import org.opendaylight.controller.config.api.ModuleIdentifier;
-import org.opendaylight.controller.config.api.ServiceReferenceWritableRegistry;
 import org.opendaylight.controller.config.api.ValidationException;
 import org.opendaylight.controller.config.spi.ModuleFactory;
 import org.osgi.framework.BundleContext;
 
+import javax.management.ObjectName;
+import java.util.Collection;
+import java.util.List;
+
 /**
  * Defines contract between {@link ConfigTransactionControllerImpl} (producer)
  * and {@link ConfigRegistryImpl} (consumer).
@@ -73,7 +71,7 @@ interface ConfigTransactionControllerInternal extends
 
     BundleContext getModuleFactoryBundleContext(String factoryName);
 
-    ServiceReferenceWritableRegistry getWritableRegistry();
+    SearchableServiceReferenceWritableRegistry  getWritableRegistry();
 
     TransactionIdentifier getTransactionIdentifier();
 
index ba7ab7fcba924743c4ea579797f1dffbd117c7cb..d34a739703e8f8eba7d60a90ca6fa713a301f802 100644 (file)
@@ -6,6 +6,8 @@ import org.slf4j.LoggerFactory;
 
 import javax.annotation.Nullable;
 import javax.annotation.concurrent.GuardedBy;
+import java.util.Deque;
+import java.util.LinkedList;
 import java.util.concurrent.TimeUnit;
 
 public class DeadlockMonitor implements AutoCloseable {
@@ -16,7 +18,9 @@ public class DeadlockMonitor implements AutoCloseable {
     private final TransactionIdentifier transactionIdentifier;
     private final DeadlockMonitorRunnable thread;
     @GuardedBy("this")
-    private ModuleIdentifierWithNanos moduleIdentifierWithNanos = new ModuleIdentifierWithNanos();
+    private final Deque<ModuleIdentifierWithNanos> moduleIdentifierWithNanosStack = new LinkedList<>();
+    @GuardedBy("this")
+    private ModuleIdentifierWithNanos top = ModuleIdentifierWithNanos.EMPTY;
 
     public DeadlockMonitor(TransactionIdentifier transactionIdentifier) {
         this.transactionIdentifier = transactionIdentifier;
@@ -25,7 +29,21 @@ public class DeadlockMonitor implements AutoCloseable {
     }
 
     public synchronized void setCurrentlyInstantiatedModule(ModuleIdentifier currentlyInstantiatedModule) {
-        this.moduleIdentifierWithNanos = new ModuleIdentifierWithNanos(currentlyInstantiatedModule);
+
+        boolean popping = currentlyInstantiatedModule == null;
+        if (popping) {
+            moduleIdentifierWithNanosStack.pop();
+            if (moduleIdentifierWithNanosStack.isEmpty()) {
+                top = ModuleIdentifierWithNanos.EMPTY;
+            } else {
+                top = moduleIdentifierWithNanosStack.peekLast();
+            }
+        } else {
+            ModuleIdentifierWithNanos current = new ModuleIdentifierWithNanos(currentlyInstantiatedModule);
+            moduleIdentifierWithNanosStack.push(current);
+            top = current;
+        }
+        logger.trace("setCurrentlyInstantiatedModule {}, top {}", currentlyInstantiatedModule, top);
     }
 
     public boolean isAlive() {
@@ -52,11 +70,11 @@ public class DeadlockMonitor implements AutoCloseable {
         public void run() {
             ModuleIdentifierWithNanos old = new ModuleIdentifierWithNanos(); // null moduleId
             while (this.isInterrupted() == false) {
-                ModuleIdentifierWithNanos copy = new ModuleIdentifierWithNanos(DeadlockMonitor.this.moduleIdentifierWithNanos);
-                if (old.moduleIdentifier == null) {
+                ModuleIdentifierWithNanos copy = new ModuleIdentifierWithNanos(DeadlockMonitor.this.top);
+                if (old.moduleIdentifier == null || old.equals(copy) == false) {
                     // started
                     old = copy;
-                } else if (old.moduleIdentifier != null && old.equals(copy)) {
+                } else {
                     // is the getInstance() running longer than WARN_AFTER_MILLIS ?
                     long runningTime = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - copy.nanoTime);
                     if (runningTime > WARN_AFTER_MILLIS) {
@@ -78,14 +96,18 @@ public class DeadlockMonitor implements AutoCloseable {
         }
     }
 
-    private class ModuleIdentifierWithNanos {
+
+
+
+    private static class ModuleIdentifierWithNanos {
+        private static ModuleIdentifierWithNanos EMPTY = new ModuleIdentifierWithNanos();
         @Nullable
         private final ModuleIdentifier moduleIdentifier;
+
         private final long nanoTime;
 
         private ModuleIdentifierWithNanos() {
-            moduleIdentifier = null;
-            nanoTime = System.nanoTime();
+            this((ModuleIdentifier)null);
         }
 
         private ModuleIdentifierWithNanos(ModuleIdentifier moduleIdentifier) {
@@ -118,5 +140,12 @@ public class DeadlockMonitor implements AutoCloseable {
             result = 31 * result + (int) (nanoTime ^ (nanoTime >>> 32));
             return result;
         }
+
+        @Override
+        public String toString() {
+            return "ModuleIdentifierWithNanos{" +
+                    moduleIdentifier +
+                    '}';
+        }
     }
 }
index fd6262cb8cf34f222b70c0e643bf9edc688d46b5..76299e67a287fc922dbd034bddeeecd8df361602 100644 (file)
@@ -15,7 +15,9 @@ import org.opendaylight.controller.config.manager.impl.dynamicmbean.DynamicReada
 import org.opendaylight.controller.config.manager.impl.jmx.ModuleJMXRegistrator;
 import org.opendaylight.controller.config.manager.impl.jmx.RootRuntimeBeanRegistratorImpl;
 import org.opendaylight.controller.config.manager.impl.osgi.BeanToOsgiServiceManager.OsgiRegistration;
+import org.opendaylight.controller.config.spi.ModuleFactory;
 import org.opendaylight.yangtools.concepts.Identifiable;
+import org.osgi.framework.BundleContext;
 
 /**
  * Provides metadata about Module from controller to registry.
@@ -37,13 +39,15 @@ public class ModuleInternalInfo implements Comparable<ModuleInternalInfo>,
     private final ModuleJMXRegistrator moduleJMXRegistrator;
     private final int orderingIdx;
     private final boolean isDefaultBean;
+    private final ModuleFactory moduleFactory;
+    private final BundleContext bundleContext;
 
     public ModuleInternalInfo(ModuleIdentifier name,
             @Nullable DynamicReadableWrapper readableModule,
             OsgiRegistration osgiRegistration,
             RootRuntimeBeanRegistratorImpl runtimeBeanRegistrator,
             ModuleJMXRegistrator moduleJMXRegistrator, int orderingIdx,
-            boolean isDefaultBean) {
+            boolean isDefaultBean, ModuleFactory moduleFactory, BundleContext bundleContext) {
 
         if (osgiRegistration == null) {
             throw new IllegalArgumentException(
@@ -60,6 +64,8 @@ public class ModuleInternalInfo implements Comparable<ModuleInternalInfo>,
         this.moduleJMXRegistrator = moduleJMXRegistrator;
         this.orderingIdx = orderingIdx;
         this.isDefaultBean = isDefaultBean;
+        this.moduleFactory = moduleFactory;
+        this.bundleContext = bundleContext;
     }
 
     public DynamicReadableWrapper getReadableModule() {
@@ -120,4 +126,12 @@ public class ModuleInternalInfo implements Comparable<ModuleInternalInfo>,
     public boolean isDefaultBean() {
         return isDefaultBean;
     }
+
+    public ModuleFactory getModuleFactory() {
+        return moduleFactory;
+    }
+
+    public BundleContext getBundleContext() {
+        return bundleContext;
+    }
 }
diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/SearchableServiceReferenceWritableRegistry.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/SearchableServiceReferenceWritableRegistry.java
new file mode 100644 (file)
index 0000000..7a41a3b
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.config.manager.impl;
+
+import java.util.Map;
+import org.opendaylight.controller.config.api.ModuleIdentifier;
+import org.opendaylight.controller.config.api.ServiceReferenceWritableRegistry;
+import org.opendaylight.controller.config.api.annotations.ServiceInterfaceAnnotation;
+
+public interface SearchableServiceReferenceWritableRegistry extends ServiceReferenceWritableRegistry {
+    /**
+     * Return mapping between service ref names and service interface annotation for given
+     * module.
+     *
+     * @throws java.lang.IllegalArgumentException if any of service qNames is not found
+     * @throws java.lang.NullPointerException     if parameter is null
+     */
+    Map<String /* service ref */, ServiceInterfaceAnnotation> findServiceInterfaces(ModuleIdentifier moduleIdentifier);
+
+}
index bf35fd1ed86f6b8249dcb4a7ca386d85ad2a53d1..ceea99415471d1ecd48a0d2cd17f469174aa792a 100644 (file)
@@ -7,6 +7,17 @@
  */
 package org.opendaylight.controller.config.manager.impl;
 
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.InstanceNotFoundException;
+import javax.management.ObjectName;
 import org.opendaylight.controller.config.api.LookupRegistry;
 import org.opendaylight.controller.config.api.ModuleIdentifier;
 import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry;
@@ -26,17 +37,7 @@ import org.osgi.framework.BundleContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.InstanceNotFoundException;
-import javax.management.ObjectName;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceReadableRegistry, ServiceReferenceWritableRegistry {
+public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceReadableRegistry, SearchableServiceReferenceWritableRegistry {
     private static final Logger logger = LoggerFactory.getLogger(ServiceReferenceRegistryImpl.class);
 
     private final Map<String, ModuleFactory> factories;
@@ -46,8 +47,11 @@ public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceRe
     private final ServiceReferenceRegistrator serviceReferenceRegistrator;
     // helper method for getting QName of SI from namespace + local name
     private final Map<String /* namespace */, Map<String /* local name */, ServiceInterfaceAnnotation>> namespacesToAnnotations;
+    private final Map<String /* service qName */, ServiceInterfaceAnnotation> serviceQNamesToAnnotations;
     // all Service Interface qNames for sanity checking
     private final Set<String /* qName */> allQNames;
+    Map<ModuleIdentifier, Map<String /* service ref name */, ServiceInterfaceAnnotation >> modulesToServiceRef = new HashMap<>();
+
 
     // actual reference database
     private final Map<ServiceReference, ModuleIdentifier> refNames = new HashMap<>();
@@ -124,7 +128,7 @@ public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceRe
     /**
      * Static constructor for transaction controller. Take current state as seen by config registry, allow writing new data.
      */
-    public static ServiceReferenceWritableRegistry createSRWritableRegistry(ServiceReferenceReadableRegistry oldReadableRegistry,
+    public static SearchableServiceReferenceWritableRegistry createSRWritableRegistry(ServiceReferenceReadableRegistry oldReadableRegistry,
                                                     ConfigTransactionLookupRegistry txLookupRegistry,
                                                     Map<String, Map.Entry<ModuleFactory, BundleContext>> currentlyRegisteredFactories) {
 
@@ -198,16 +202,15 @@ public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceRe
         Map<String, Set<String /* QName */>> modifiableFactoryNamesToQNames = new HashMap<>();
         Set<ServiceInterfaceAnnotation> allAnnotations = new HashSet<>();
         Set<String /* qName */> allQNames = new HashSet<>();
+
+
         for (Entry<String, ModuleFactory> entry : factories.entrySet()) {
             if (entry.getKey().equals(entry.getValue().getImplementationName()) == false) {
                 logger.error("Possible error in code: Mismatch between supplied and actual name of {}", entry);
                 throw new IllegalArgumentException("Possible error in code: Mismatch between supplied and actual name of " + entry);
             }
             Set<ServiceInterfaceAnnotation> siAnnotations = InterfacesHelper.getServiceInterfaceAnnotations(entry.getValue());
-            Set<String> qNames = new HashSet<>();
-            for (ServiceInterfaceAnnotation sia: siAnnotations) {
-                qNames.add(sia.value());
-            }
+            Set<String> qNames = InterfacesHelper.getQNames(siAnnotations);
             allAnnotations.addAll(siAnnotations);
             allQNames.addAll(qNames);
             modifiableFactoryNamesToQNames.put(entry.getKey(), Collections.unmodifiableSet(qNames));
@@ -217,6 +220,7 @@ public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceRe
         // fill namespacesToAnnotations
         Map<String /* namespace */, Map<String /* localName */, ServiceInterfaceAnnotation>> modifiableNamespacesToAnnotations =
                 new HashMap<>();
+        Map<String /* service qName*/, ServiceInterfaceAnnotation> modifiableServiceQNamesToAnnotations = new HashMap<>();
         for (ServiceInterfaceAnnotation sia : allAnnotations) {
             Map<String, ServiceInterfaceAnnotation> ofNamespace = modifiableNamespacesToAnnotations.get(sia.namespace());
             if (ofNamespace == null) {
@@ -229,12 +233,21 @@ public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceRe
                 throw new IllegalArgumentException("Conflict between local names in " + sia.namespace() + " : " + sia.localName());
             }
             ofNamespace.put(sia.localName(), sia);
+            modifiableServiceQNamesToAnnotations.put(sia.value(), sia);
         }
         this.namespacesToAnnotations = Collections.unmodifiableMap(modifiableNamespacesToAnnotations);
-        // copy refNames
+        this.serviceQNamesToAnnotations = Collections.unmodifiableMap(modifiableServiceQNamesToAnnotations);
         logger.trace("factoryNamesToQNames:{}", this.factoryNamesToQNames);
     }
 
+    @Override
+    public Map<String /* service ref */, ServiceInterfaceAnnotation> findServiceInterfaces(ModuleIdentifier moduleIdentifier) {
+        Map<String, ServiceInterfaceAnnotation> result = modulesToServiceRef.get(moduleIdentifier);
+        if (result == null) {
+            return Collections.emptyMap();
+        }
+        return Collections.unmodifiableMap(result);
+    }
 
     @Override
     public synchronized Set<String> lookupServiceInterfaceNames(ObjectName objectName) throws InstanceNotFoundException {
@@ -271,7 +284,7 @@ public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceRe
     public synchronized Map<String /* serviceInterfaceName */, Map<String/* refName */, ObjectName>> getServiceMapping() {
         Map<String /* serviceInterfaceName */, Map<String/* refName */, ObjectName>> result = new HashMap<>();
         for (Entry<ServiceReference, ModuleIdentifier> entry: refNames.entrySet()) {
-            String qName = entry.getKey().getServiceInterfaceName();
+            String qName = entry.getKey().getServiceInterfaceQName();
             Map<String /* refName */, ObjectName> innerMap = result.get(qName);
             if (innerMap == null) {
                 innerMap = new HashMap<>();
@@ -379,9 +392,9 @@ public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceRe
             throw new IllegalStateException("Possible error in code: cannot find annotations of existing factory " + moduleIdentifier.getFactoryName());
         }
         // supplied serviceInterfaceName must exist in this collection
-        if (serviceInterfaceQNames.contains(serviceReference.getServiceInterfaceName()) == false) {
-            logger.error("Cannot find qName {} with factory name {}, found {}", serviceReference.getServiceInterfaceName(), moduleIdentifier.getFactoryName(), serviceInterfaceQNames);
-            throw new IllegalArgumentException("Cannot find service interface " + serviceReference.getServiceInterfaceName() + " within factory " + moduleIdentifier.getFactoryName());
+        if (serviceInterfaceQNames.contains(serviceReference.getServiceInterfaceQName()) == false) {
+            logger.error("Cannot find qName {} with factory name {}, found {}", serviceReference.getServiceInterfaceQName(), moduleIdentifier.getFactoryName(), serviceInterfaceQNames);
+            throw new IllegalArgumentException("Cannot find service interface " + serviceReference.getServiceInterfaceQName() + " within factory " + moduleIdentifier.getFactoryName());
         }
 
 
@@ -404,6 +417,15 @@ public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceRe
         }
         // save to refNames
         refNames.put(serviceReference, moduleIdentifier);
+        Map<String, ServiceInterfaceAnnotation> refNamesToAnnotations = modulesToServiceRef.get(moduleIdentifier);
+        if (refNamesToAnnotations == null){
+            refNamesToAnnotations = new HashMap<>();
+            modulesToServiceRef.put(moduleIdentifier, refNamesToAnnotations);
+        }
+
+        ServiceInterfaceAnnotation annotation = serviceQNamesToAnnotations.get(serviceReference.getServiceInterfaceQName());
+        checkNotNull(annotation, "Possible error in code, cannot find annotation for " + serviceReference);
+        refNamesToAnnotations.put(serviceReference.getRefName(), annotation);
         return result;
     }
 
@@ -430,9 +452,9 @@ public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceRe
     private ObjectName getServiceON(ServiceReference serviceReference) {
         if (writable) {
             return ObjectNameUtil.createTransactionServiceON(serviceReferenceRegistrator.getNullableTransactionName(),
-                    serviceReference.getServiceInterfaceName(), serviceReference.getRefName());
+                    serviceReference.getServiceInterfaceQName(), serviceReference.getRefName());
         } else {
-            return ObjectNameUtil.createReadOnlyServiceON(serviceReference.getServiceInterfaceName(), serviceReference.getRefName());
+            return ObjectNameUtil.createReadOnlyServiceON(serviceReference.getServiceInterfaceQName(), serviceReference.getRefName());
         }
     }
 
@@ -446,13 +468,13 @@ public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceRe
         logger.debug("Removing service reference {} from {}", serviceReference, this);
         assertWritable();
         // is the qName known?
-        if (allQNames.contains(serviceReference.getServiceInterfaceName()) == false) {
-            logger.error("Cannot find qname {} in {}", serviceReference.getServiceInterfaceName(), allQNames);
-            throw new IllegalArgumentException("Cannot find service interface " + serviceReference.getServiceInterfaceName());
+        if (allQNames.contains(serviceReference.getServiceInterfaceQName()) == false) {
+            logger.error("Cannot find qname {} in {}", serviceReference.getServiceInterfaceQName(), allQNames);
+            throw new IllegalArgumentException("Cannot find service interface " + serviceReference.getServiceInterfaceQName());
         }
         ModuleIdentifier removed = refNames.remove(serviceReference);
         if (removed == null){
-            throw new InstanceNotFoundException("Cannot find " + serviceReference.getServiceInterfaceName());
+            throw new InstanceNotFoundException("Cannot find " + serviceReference.getServiceInterfaceQName());
         }
         Entry<ServiceReferenceMXBeanImpl, ServiceReferenceJMXRegistration> entry = mBeans.remove(serviceReference);
         if (entry == null) {
@@ -475,21 +497,28 @@ public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceRe
 
     @Override
     public synchronized boolean removeServiceReferences(ObjectName moduleObjectName) throws InstanceNotFoundException {
+        lookupRegistry.checkConfigBeanExists(moduleObjectName);
+        String factoryName = ObjectNameUtil.getFactoryName(moduleObjectName);
+        // check that service interface name exist
+        Set<String> serviceInterfaceQNames = factoryNamesToQNames.get(factoryName);
+        return removeServiceReferences(moduleObjectName, serviceInterfaceQNames);
+    }
+
+
+    private boolean removeServiceReferences(ObjectName moduleObjectName, Set<String> qNames) throws InstanceNotFoundException {
+        ObjectNameUtil.checkType(moduleObjectName, ObjectNameUtil.TYPE_MODULE);
         assertWritable();
-        Set<ServiceReference> serviceReferencesLinkingTo = findServiceReferencesLinkingTo(moduleObjectName);
+        Set<ServiceReference> serviceReferencesLinkingTo = findServiceReferencesLinkingTo(moduleObjectName, qNames);
         for (ServiceReference sr : serviceReferencesLinkingTo) {
             removeServiceReference(sr);
         }
         return serviceReferencesLinkingTo.isEmpty() == false;
     }
 
-    private synchronized Set<ServiceReference> findServiceReferencesLinkingTo(ObjectName moduleObjectName)  throws InstanceNotFoundException {
-        lookupRegistry.checkConfigBeanExists(moduleObjectName);
+    private Set<ServiceReference> findServiceReferencesLinkingTo(ObjectName moduleObjectName, Set<String> serviceInterfaceQNames) {
         String factoryName = ObjectNameUtil.getFactoryName(moduleObjectName);
-        // check that service interface name exist
-        Set<String> serviceInterfaceQNames = factoryNamesToQNames.get(factoryName);
         if (serviceInterfaceQNames == null) {
-            logger.error("Possible error in code: cannot find factoryName {} in {}, object name {}", factoryName, factoryNamesToQNames, moduleObjectName);
+            logger.warn("Possible error in code: cannot find factoryName {} in {}, object name {}", factoryName, factoryNamesToQNames, moduleObjectName);
             throw new IllegalStateException("Possible error in code: cannot find annotations of existing factory " + factoryName);
         }
         String instanceName = ObjectNameUtil.getInstanceName(moduleObjectName);
@@ -503,7 +532,6 @@ public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceRe
         return result;
     }
 
-
     @Override
     public String toString() {
         return "ServiceReferenceRegistryImpl{" +
index b99bf8330e5be412a6965ff78ccad4bb4b520c14..0c1531728fb1b58488fe6623047c0fd804528824 100644 (file)
@@ -7,8 +7,19 @@
  */
 package org.opendaylight.controller.config.manager.impl.dependencyresolver;
 
+import static com.google.common.base.Preconditions.checkState;
+
 import com.google.common.reflect.AbstractInvocationHandler;
 import com.google.common.reflect.Reflection;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.annotation.concurrent.GuardedBy;
+import javax.management.InstanceAlreadyExistsException;
 import org.opendaylight.controller.config.api.DependencyResolver;
 import org.opendaylight.controller.config.api.DependencyResolverFactory;
 import org.opendaylight.controller.config.api.JmxAttribute;
@@ -24,18 +35,7 @@ import org.opendaylight.controller.config.manager.impl.jmx.TransactionModuleJMXR
 import org.opendaylight.controller.config.spi.Module;
 import org.opendaylight.controller.config.spi.ModuleFactory;
 import org.opendaylight.yangtools.yang.data.impl.codec.CodecRegistry;
-
-import javax.annotation.concurrent.GuardedBy;
-import javax.management.InstanceAlreadyExistsException;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import static com.google.common.base.Preconditions.checkState;
+import org.osgi.framework.BundleContext;
 
 /**
  * Holds information about modules being created and destroyed within this
@@ -117,7 +117,7 @@ public class DependencyResolverManager implements DependencyResolverFactory, Aut
             ModuleFactory moduleFactory,
             ModuleInternalInfo maybeOldInternalInfo,
             TransactionModuleJMXRegistration transactionModuleJMXRegistration,
-            boolean isDefaultBean) {
+            boolean isDefaultBean, BundleContext bundleContext) {
         transactionStatus.checkNotCommitted();
 
         Class<? extends Module> moduleClass = Module.class;
@@ -159,7 +159,7 @@ public class DependencyResolverManager implements DependencyResolverFactory, Aut
 
         ModuleInternalTransactionalInfo moduleInternalTransactionalInfo = new ModuleInternalTransactionalInfo(
                 moduleIdentifier, proxiedModule, moduleFactory,
-                maybeOldInternalInfo, transactionModuleJMXRegistration, isDefaultBean, module);
+                maybeOldInternalInfo, transactionModuleJMXRegistration, isDefaultBean, module, bundleContext);
         modulesHolder.put(moduleInternalTransactionalInfo);
     }
 
index e9f573a05def40ec079dc3a45522698358ed8ee0..13424a60eb016cd1bfc1fb892d3c72da36cf8f35 100644 (file)
@@ -16,6 +16,7 @@ import org.opendaylight.controller.config.spi.ModuleFactory;
 import org.opendaylight.yangtools.concepts.Identifiable;
 
 import javax.annotation.Nullable;
+import org.osgi.framework.BundleContext;
 
 public class ModuleInternalTransactionalInfo implements Identifiable<ModuleIdentifier> {
     private final ModuleIdentifier name;
@@ -25,12 +26,13 @@ public class ModuleInternalTransactionalInfo implements Identifiable<ModuleIdent
     private final ModuleInternalInfo maybeOldInternalInfo;
     private final TransactionModuleJMXRegistration transactionModuleJMXRegistration;
     private final boolean isDefaultBean;
+    private final BundleContext bundleContext;
 
     public ModuleInternalTransactionalInfo(ModuleIdentifier name, Module proxiedModule,
                                            ModuleFactory moduleFactory,
                                            ModuleInternalInfo maybeOldInternalInfo,
                                            TransactionModuleJMXRegistration transactionModuleJMXRegistration,
-                                           boolean isDefaultBean, Module realModule) {
+                                           boolean isDefaultBean, Module realModule, BundleContext bundleContext) {
         this.name = name;
         this.proxiedModule = proxiedModule;
         this.moduleFactory = moduleFactory;
@@ -38,6 +40,7 @@ public class ModuleInternalTransactionalInfo implements Identifiable<ModuleIdent
         this.transactionModuleJMXRegistration = transactionModuleJMXRegistration;
         this.isDefaultBean = isDefaultBean;
         this.realModule = realModule;
+        this.bundleContext = bundleContext;
     }
 
 
@@ -90,4 +93,8 @@ public class ModuleInternalTransactionalInfo implements Identifiable<ModuleIdent
     public Module getRealModule() {
         return realModule;
     }
+
+    public BundleContext getBundleContext() {
+        return bundleContext;
+    }
 }
index adc8168af5d85b0aee22e717cb59cda7b8939b8f..c212300fa6bb0642c3a665d7552b62857edff4d4 100644 (file)
@@ -8,17 +8,16 @@
 package org.opendaylight.controller.config.manager.impl.factoriesresolver;
 
 
-import org.opendaylight.controller.config.spi.ModuleFactory;
-import org.osgi.framework.BundleContext;
-
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
-import java.util.Map.Entry;
 import java.util.Set;
 import java.util.TreeSet;
+import javax.management.InstanceNotFoundException;
+import org.opendaylight.controller.config.spi.ModuleFactory;
+import org.osgi.framework.BundleContext;
 
 /**
  * Hold sorted ConfigMBeanFactories by their module names. Check that module
@@ -56,10 +55,10 @@ public class HierarchicalConfigMBeanFactoriesHolder {
      * @throws IllegalArgumentException
      *             if factory is not found
      */
-    public ModuleFactory findByModuleName(String moduleName) {
+    public ModuleFactory findByModuleName(String moduleName) throws InstanceNotFoundException {
         Map.Entry<ModuleFactory, BundleContext> result = moduleNamesToConfigBeanFactories.get(moduleName);
         if (result == null) {
-            throw new IllegalArgumentException(
+            throw new InstanceNotFoundException(
                     "ModuleFactory not found with module name: " + moduleName);
         }
         return result.getKey();
@@ -73,7 +72,4 @@ public class HierarchicalConfigMBeanFactoriesHolder {
         return moduleFactories;
     }
 
-    public Map<String, Entry<ModuleFactory, BundleContext>> getModuleNamesToConfigBeanFactories() {
-        return moduleNamesToConfigBeanFactories;
-    }
 }
index cd74ddf7565a32fd74e650cde1d50e720966d506..3ad35ac5b5f48d27041244f795a35f32ca781972 100644 (file)
@@ -15,7 +15,7 @@ public class ServiceReference {
         this.refName = refName;
     }
 
-    public String getServiceInterfaceName() {
+    public String getServiceInterfaceQName() {
         return serviceInterfaceName;
     }
 
@@ -50,4 +50,12 @@ public class ServiceReference {
         result = 31 * result + refName.hashCode();
         return result;
     }
+
+    @Override
+    public String toString() {
+        return "ServiceReference{" +
+                "serviceInterfaceName='" + serviceInterfaceName + '\'' +
+                ", refName='" + refName + '\'' +
+                '}';
+    }
 }
index 41f577844af5ed448a322a9a21f2f410782632cd..fbc7eb6cbe7925ef6da5a96ad69e8c1a38433007 100644 (file)
  */
 package org.opendaylight.controller.config.manager.impl.osgi;
 
-import org.opendaylight.controller.config.api.ModuleIdentifier;
-import org.opendaylight.controller.config.api.annotations.ServiceInterfaceAnnotation;
-import org.opendaylight.controller.config.manager.impl.util.InterfacesHelper;
-import org.opendaylight.controller.config.spi.Module;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceRegistration;
+import static com.google.common.base.Preconditions.checkState;
 
 import java.util.Dictionary;
 import java.util.HashSet;
 import java.util.Hashtable;
+import java.util.Map;
+import java.util.Map.Entry;
 import java.util.Set;
+import javax.annotation.concurrent.GuardedBy;
+import org.opendaylight.controller.config.api.ModuleIdentifier;
+import org.opendaylight.controller.config.api.annotations.ServiceInterfaceAnnotation;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * Registers instantiated beans as OSGi services and unregisters these services
  * if beans are destroyed.
  */
 public class BeanToOsgiServiceManager {
-    // name of properties submitted to osgi
-    static final String INSTANCE_NAME_OSGI_PROP = "instanceName";
-    static final String IMPLEMENTATION_NAME_OSGI_PROP = "implementationName";
+    private static final String SERVICE_NAME_OSGI_PROP = "name";
 
     /**
      * To be called for every created, reconfigured and recreated config bean.
      * It is expected that before using this method OSGi service registry will
      * be cleaned from previous registrations.
      */
-    public OsgiRegistration registerToOsgi(
-            Class<? extends Module> configBeanClass, AutoCloseable instance,
-            ModuleIdentifier moduleIdentifier, BundleContext bundleContext) {
-        try {
-            final Set<Class<?>> configuresInterfaces = InterfacesHelper
-                    .getOsgiRegistrationTypes(configBeanClass);
-            checkInstanceImplementing(instance, configuresInterfaces);
-
-            // bundleContext.registerService blows up with empty 'clazzes'
-            if (configuresInterfaces.isEmpty() == false) {
-                final Dictionary<String, ?> propertiesForOsgi = getPropertiesForOsgi(moduleIdentifier);
-                final ServiceRegistration<?> serviceRegistration = bundleContext
-                        .registerService(classesToNames(configuresInterfaces), instance, propertiesForOsgi);
-                return new OsgiRegistration(serviceRegistration);
-            } else {
-                return new OsgiRegistration();
-            }
-        } catch (IllegalStateException e) {
-            throw new IllegalStateException(
-                    "Error while registering instance into OSGi Service Registry: "
-                            + moduleIdentifier, e);
-        }
+    public OsgiRegistration registerToOsgi(AutoCloseable instance, ModuleIdentifier moduleIdentifier,
+                                           BundleContext bundleContext,
+                                           Map<String, ServiceInterfaceAnnotation> serviceNamesToAnnotations) {
+        return new OsgiRegistration(instance, moduleIdentifier, bundleContext, serviceNamesToAnnotations);
     }
 
-    private static String[] classesToNames(Set<Class<?>> cfgs) {
-        String[] result = new String[cfgs.size()];
-        int i = 0;
-        for (Class<?> cfg : cfgs) {
-            result[i] = cfg.getName();
-            i++;
-        }
+    private static Dictionary<String, String> createProps(String serviceName) {
+        Hashtable<String, String> result = new Hashtable<>();
+        result.put(SERVICE_NAME_OSGI_PROP, serviceName);
         return result;
     }
 
-    private void checkInstanceImplementing(AutoCloseable instance,
-            Set<Class<?>> configures) {
-        Set<Class<?>> missing = new HashSet<>();
-        for (Class<?> requiredIfc : configures) {
-            if (requiredIfc.isInstance(instance) == false) {
-                missing.add(requiredIfc);
-            }
-        }
-        if (missing.isEmpty() == false) {
-            throw new IllegalStateException(
-                    instance.getClass()
-                            + " does not implement following interfaces as announced by "
-                            + ServiceInterfaceAnnotation.class.getName()
-                            + " annotation :" + missing);
-        }
-    }
-
-    private static Dictionary<String, ?> getPropertiesForOsgi(
-            ModuleIdentifier moduleIdentifier) {
-        Hashtable<String, String> table = new Hashtable<>();
-        table.put(IMPLEMENTATION_NAME_OSGI_PROP,
-                moduleIdentifier.getFactoryName());
-        table.put(INSTANCE_NAME_OSGI_PROP, moduleIdentifier.getInstanceName());
-        return table;
-    }
 
     public static class OsgiRegistration implements AutoCloseable {
-        private final ServiceRegistration<?> serviceRegistration;
+        private static final Logger logger = LoggerFactory.getLogger(OsgiRegistration.class);
 
-        public OsgiRegistration(ServiceRegistration<?> serviceRegistration) {
-            this.serviceRegistration = serviceRegistration;
+        @GuardedBy("this")
+        private AutoCloseable instance;
+        private final ModuleIdentifier moduleIdentifier;
+        @GuardedBy("this")
+        private final Set<ServiceRegistration<?>> serviceRegistrations;
+        @GuardedBy("this")
+        private final Map<String, ServiceInterfaceAnnotation> serviceNamesToAnnotations;
+
+        public OsgiRegistration(AutoCloseable instance, ModuleIdentifier moduleIdentifier,
+                                BundleContext bundleContext,
+                                Map<String, ServiceInterfaceAnnotation> serviceNamesToAnnotations) {
+            this.instance = instance;
+            this.moduleIdentifier = moduleIdentifier;
+            this.serviceNamesToAnnotations = serviceNamesToAnnotations;
+            this.serviceRegistrations = registerToSR(instance, bundleContext, serviceNamesToAnnotations);
         }
 
-        public OsgiRegistration() {
-            this.serviceRegistration = null;
+        private static Set<ServiceRegistration<?>> registerToSR(AutoCloseable instance, BundleContext bundleContext,
+                                                                Map<String, ServiceInterfaceAnnotation> serviceNamesToAnnotations) {
+            Set<ServiceRegistration<?>> serviceRegistrations = new HashSet<>();
+            for (Entry<String, ServiceInterfaceAnnotation> entry : serviceNamesToAnnotations.entrySet()) {
+                Class<?> requiredInterface = entry.getValue().osgiRegistrationType();
+                checkState(requiredInterface.isInstance(instance), instance.getClass().getName() +
+                        " instance should implement " + requiredInterface.getName());
+                Dictionary<String, String> propertiesForOsgi = createProps(entry.getKey());
+                ServiceRegistration<?> serviceRegistration = bundleContext
+                        .registerService(requiredInterface.getName(), instance, propertiesForOsgi);
+                serviceRegistrations.add(serviceRegistration);
+            }
+            return serviceRegistrations;
         }
 
         @Override
-        public void close() {
-            if (serviceRegistration != null) {
-                serviceRegistration.unregister();
+        public synchronized void close() {
+            for (ServiceRegistration<?> serviceRegistration : serviceRegistrations) {
+                try {
+                    serviceRegistration.unregister();
+                } catch(IllegalStateException e) {
+                    logger.trace("Cannot unregister {}", serviceRegistration, e);
+                }
             }
+            serviceRegistrations.clear();
         }
-    }
 
+        public synchronized void updateRegistrations(Map<String, ServiceInterfaceAnnotation> newAnnotationMapping,
+                                                     BundleContext bundleContext, AutoCloseable newInstance) {
+            boolean notEquals = this.instance != newInstance;
+            notEquals |= newAnnotationMapping.equals(serviceNamesToAnnotations) == false;
+            if (notEquals) {
+                // FIXME: changing from old state to new state can be improved by computing the diff
+                logger.debug("Detected change in service registrations for {}: old: {}, new: {}", moduleIdentifier,
+                        serviceNamesToAnnotations, newAnnotationMapping);
+                close();
+                this.instance = newInstance;
+                Set<ServiceRegistration<?>> newRegs = registerToSR(instance, bundleContext, newAnnotationMapping);
+                serviceRegistrations.clear();
+                serviceRegistrations.addAll(newRegs);
+            }
+        }
+    }
 }
index 033f7222fcc7fd64103e25336a3b81f669d14adc..a6e9b1ba965b8532eb2e688742ca6ec66c5d5e10 100644 (file)
@@ -120,6 +120,13 @@ public class InterfacesHelper {
         return result;
     }
 
+    public static Set<String> getQNames(Set<ServiceInterfaceAnnotation> siAnnotations) {
+        Set<String> qNames = new HashSet<>();
+        for (ServiceInterfaceAnnotation sia: siAnnotations) {
+            qNames.add(sia.value());
+        }
+        return Collections.unmodifiableSet(qNames);
+    }
 
     public static Set<ServiceInterfaceAnnotation> getServiceInterfaceAnnotations(ModuleFactory factory) {
         Set<Class<? extends AbstractServiceInterface>> implementedServiceIntefaces = Collections.unmodifiableSet(factory.getImplementedServiceIntefaces());
@@ -136,7 +143,7 @@ public class InterfacesHelper {
                 result.add(annotation);
             }
         }
-        return result;
+        return Collections.unmodifiableSet(result);
     }
 
     static Set<Class<? extends AbstractServiceInterface>> getAllAbstractServiceInterfaceClasses(
index 9178dc40d0707501ef8696d279a7cfa1af6c22d1..7efd3ee0309fdfec46fbe9378975403637b43ff2 100644 (file)
@@ -7,13 +7,6 @@
  */
 package org.opendaylight.controller.config.manager;
 
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verifyZeroInteractions;
-
-import java.lang.management.ManagementFactory;
-
 import org.junit.Test;
 import org.opendaylight.controller.config.manager.impl.AbstractLockedPlatformMBeanServerTest;
 import org.opendaylight.controller.config.manager.impl.ConfigRegistryImpl;
@@ -25,6 +18,13 @@ import org.osgi.framework.BundleContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.lang.management.ManagementFactory;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verifyZeroInteractions;
+
 public class ConfigRegistryImplTest extends
         AbstractLockedPlatformMBeanServerTest {
     private static final Logger logger = LoggerFactory
@@ -36,7 +36,7 @@ public class ConfigRegistryImplTest extends
         BundleContext context = mock(BundleContext.class);
         ConfigRegistryImpl configRegistry = null;
         try {
-            ModuleFactoriesResolver resolver = new HardcodedModuleFactoriesResolver(
+            ModuleFactoriesResolver resolver = new HardcodedModuleFactoriesResolver(mock(BundleContext.class),
                     factory, factory);
 
             configRegistry = new ConfigRegistryImpl(resolver,
index 001af7525bb28a915e7b9ec0306bbd03046f24f1..63a37de0c3783179ffaaf33ab535281dcab62290 100644 (file)
@@ -8,9 +8,11 @@
 package org.opendaylight.controller.config.manager.impl;
 
 import com.google.common.base.Preconditions;
-import junit.framework.Assert;
 import org.junit.After;
+import org.junit.Before;
 import org.mockito.Matchers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
 import org.opendaylight.controller.config.api.jmx.CommitStatus;
@@ -26,24 +28,18 @@ import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
 import org.opendaylight.yangtools.yang.data.impl.codec.CodecRegistry;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceRegistration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import javax.management.InstanceAlreadyExistsException;
 import javax.management.MBeanServer;
 import javax.management.ObjectName;
 import javax.management.RuntimeMBeanException;
-import java.io.Closeable;
-import java.io.InputStream;
 import java.lang.management.ManagementFactory;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Proxy;
 import java.util.Dictionary;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Set;
 
@@ -69,29 +65,58 @@ public abstract class AbstractConfigTest extends
     protected ConfigRegistryJMXClient configRegistryClient;
     protected BaseJMXRegistrator baseJmxRegistrator;
     protected InternalJMXRegistrator internalJmxRegistrator;
-    protected BundleContext mockedContext = mock(BundleContext.class);
+    @Mock
+    protected BundleContext mockedContext;
+    @Mock
     protected ServiceRegistration<?> mockedServiceRegistration;
 
-    private static final Logger logger = LoggerFactory.getLogger(AbstractConfigTest.class);
+    @Before
+    public void setUpMocks() {
+        MockitoAnnotations.initMocks(this);
+    }
+
 
     // Default handler for OSGi service registration
-    private static final BundleContextServiceRegistrationHandler noopServiceRegHandler = new BundleContextServiceRegistrationHandler() {
+    protected static class RecordingBundleContextServiceRegistrationHandler implements BundleContextServiceRegistrationHandler {
+        private final List<RegistrationHolder> registrations = new LinkedList<>();
         @Override
-        public void handleServiceRegistration(Object serviceInstance) {}
-    };
+        public void handleServiceRegistration(Class<?> clazz, Object serviceInstance, Dictionary<String, ?> props) {
+
+            registrations.add(new RegistrationHolder(clazz, serviceInstance, props));
+        }
+
+        public List<RegistrationHolder> getRegistrations() {
+            return registrations;
+        }
+
+        protected static class RegistrationHolder {
+            protected final Class<?> clazz;
+            protected final Object instance;
+            protected final Dictionary<String, ?> props;
+
+            public RegistrationHolder(Class<?> clazz, Object instance, Dictionary<String, ?> props) {
+                this.clazz = clazz;
+                this.instance = instance;
+                this.props = props;
+            }
+        }
+
+    }
+
+    protected BundleContextServiceRegistrationHandler currentBundleContextServiceRegistrationHandler;
 
     protected BundleContextServiceRegistrationHandler getBundleContextServiceRegistrationHandler(Class<?> serviceType) {
-        return noopServiceRegHandler;
+        return currentBundleContextServiceRegistrationHandler;
     }
 
     // this method should be called in @Before
     protected void initConfigTransactionManagerImpl(
             ModuleFactoriesResolver resolver) {
+
         final MBeanServer platformMBeanServer = ManagementFactory
                 .getPlatformMBeanServer();
 
-        configRegistryJMXRegistrator = new ConfigRegistryJMXRegistrator(
-                platformMBeanServer);
+        configRegistryJMXRegistrator = new ConfigRegistryJMXRegistrator(platformMBeanServer);
         initBundleContext();
 
         internalJmxRegistrator = new InternalJMXRegistrator(platformMBeanServer);
@@ -106,35 +131,14 @@ public abstract class AbstractConfigTest extends
             throw new RuntimeException(e);
         }
         configRegistryClient = new ConfigRegistryJMXClient(platformMBeanServer);
+        currentBundleContextServiceRegistrationHandler = new RecordingBundleContextServiceRegistrationHandler();
     }
 
     private void initBundleContext() {
-        this.mockedServiceRegistration = mock(ServiceRegistration.class);
         doNothing().when(mockedServiceRegistration).unregister();
-
         RegisterServiceAnswer answer = new RegisterServiceAnswer();
-
-        doAnswer(answer).when(mockedContext).registerService(Matchers.any(String[].class),
-                any(Closeable.class), Matchers.<Dictionary<String, ?>>any());
-        doAnswer(answer).when(mockedContext).registerService(Matchers.<Class<Closeable>>any(), any(Closeable.class),
-                Matchers.<Dictionary<String, ?>>any());
-    }
-
-
-    public Collection<InputStream> getFilesAsInputStreams(List<String> paths) {
-        final Collection<InputStream> resources = new ArrayList<>();
-        List<String> failedToFind = new ArrayList<>();
-        for (String path : paths) {
-            InputStream resourceAsStream = getClass().getResourceAsStream(path);
-            if (resourceAsStream == null) {
-                failedToFind.add(path);
-            } else {
-                resources.add(resourceAsStream);
-            }
-        }
-        Assert.assertEquals("Some files were not found", Collections.<String>emptyList(), failedToFind);
-
-        return resources;
+        doAnswer(answer).when(mockedContext).registerService(Matchers.<String>any(), any(), Matchers.<Dictionary<String, ?>>any());
+        doAnswer(answer).when(mockedContext).registerService(Matchers.<Class>any(), any(), Matchers.<Dictionary<String, ?>>any());
     }
 
     @After
@@ -161,13 +165,6 @@ public abstract class AbstractConfigTest extends
         transaction.commit();
     }
 
-    protected void assertSame(ObjectName oN1, ObjectName oN2) {
-        assertEquals(oN1.getKeyProperty("instanceName"),
-                oN2.getKeyProperty("instanceName"));
-        assertEquals(oN1.getKeyProperty("interfaceName"),
-                oN2.getKeyProperty("interfaceName"));
-    }
-
     protected void assertStatus(CommitStatus status, int expectedNewInstances,
             int expectedRecreatedInstances, int expectedReusedInstances) {
         assertEquals("New instances mismatch in " + status, expectedNewInstances, status.getNewInstances().size());
@@ -177,25 +174,12 @@ public abstract class AbstractConfigTest extends
                 .size());
     }
 
-    protected ObjectName createTestConfigBean(
-            ConfigTransactionJMXClient transaction, String implementationName,
-            String name) throws InstanceAlreadyExistsException {
-        return transaction.createModule(implementationName,
-                name);
-    }
 
     protected void assertBeanCount(int i, String configMXBeanName) {
         assertEquals(i, configRegistry.lookupConfigBeans(configMXBeanName)
                 .size());
     }
 
-    protected void assertBeanExists(int count, String moduleName,
-            String instanceName) {
-        assertEquals(1,
-                configRegistry.lookupConfigBeans(moduleName, instanceName)
-                        .size());
-    }
-
     /**
      *
      * @param configBeanClass
@@ -215,7 +199,7 @@ public abstract class AbstractConfigTest extends
 
     public static interface BundleContextServiceRegistrationHandler {
 
-       void handleServiceRegistration(Object serviceInstance);
+       void handleServiceRegistration(Class<?> clazz, Object serviceInstance, Dictionary<String, ?> props);
 
     }
 
@@ -229,32 +213,40 @@ public abstract class AbstractConfigTest extends
 
             Object serviceTypeRaw = args[0];
             Object serviceInstance = args[1];
+            Dictionary<String, ?> props = (Dictionary) args[2];
 
             if (serviceTypeRaw instanceof Class) {
                 Class<?> serviceType = (Class<?>) serviceTypeRaw;
-                invokeServiceHandler(serviceInstance, serviceType);
+                invokeServiceHandler(serviceInstance, serviceType, props);
 
             } else if(serviceTypeRaw instanceof String[]) {
                 for (String className : (String[]) serviceTypeRaw) {
-                    try {
-                        Class<?> serviceType = Class.forName(className);
-                        invokeServiceHandler(serviceInstance, serviceType);
-                    } catch (ClassNotFoundException e) {
-                        logger.warn("Not handling service registration of type {} ", className, e);
-                    }
+                    invokeServiceHandler(serviceInstance, className, props);
                 }
+            } else if (serviceTypeRaw instanceof String) {
+                invokeServiceHandler(serviceInstance, (String) serviceTypeRaw, props);
+            } else {
+                throw new IllegalStateException("Not handling service registration of type, Unknown type" +  serviceTypeRaw);
+            }
 
-            } else
-                logger.debug("Not handling service registration of type {}, Unknown type", serviceTypeRaw);
 
             return mockedServiceRegistration;
         }
 
-        private void invokeServiceHandler(Object serviceInstance, Class<?> serviceType) {
+        public void invokeServiceHandler(Object serviceInstance, String className, Dictionary<String, ?> props) {
+            try {
+                Class<?> serviceType = Class.forName(className);
+                invokeServiceHandler(serviceInstance, serviceType, props);
+            } catch (ClassNotFoundException e) {
+                throw new IllegalStateException("Not handling service registration of type " +  className, e);
+            }
+        }
+
+        private void invokeServiceHandler(Object serviceInstance, Class<?> serviceType, Dictionary<String, ?> props) {
             BundleContextServiceRegistrationHandler serviceRegistrationHandler = getBundleContextServiceRegistrationHandler(serviceType);
 
             if (serviceRegistrationHandler != null) {
-                serviceRegistrationHandler.handleServiceRegistration(serviceType.cast(serviceInstance));
+                serviceRegistrationHandler.handleServiceRegistration(serviceType, serviceInstance, props);
             }
         }
     }
index 09aea0895fe6e4c6b965d68605e7f86d5ae6fc03..5a3747ee142c7fd35ddef29bde078aef134d290c 100644 (file)
@@ -11,7 +11,6 @@ import com.google.common.collect.Sets;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
-import org.opendaylight.controller.config.api.ServiceReferenceWritableRegistry;
 import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
 import org.opendaylight.controller.config.manager.impl.jmx.BaseJMXRegistrator;
 import org.opendaylight.controller.config.manager.impl.jmx.TransactionJMXRegistrator;
@@ -70,7 +69,7 @@ public class ConfigTransactionControllerImplTest extends
             }
         }, currentlyRegisteredFactories);
 
-        ServiceReferenceWritableRegistry writableRegistry = ServiceReferenceRegistryImpl.createSRWritableRegistry(
+        SearchableServiceReferenceWritableRegistry writableRegistry = ServiceReferenceRegistryImpl.createSRWritableRegistry(
                 ServiceReferenceRegistryImpl.createInitialSRLookupRegistry(), txLookupRegistry, currentlyRegisteredFactories);
 
 
index bbb3784b33b02e49be8929d39e983e2c4cb7d33a..9595e60ff64ccc325f7d8079cd64fd51ba26ed3c 100644 (file)
@@ -23,7 +23,7 @@ public class ConfigTransactionManagerImplTest extends
 
     @Before
     public void setUp() {
-        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver());
+        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext));
 
     }
 
index 6d0b340cd3c1c0720fbe78ee6823098bf92b17ca..3e7b65e1bdcf8f25cfe6c255e43072edc2382f6a 100644 (file)
@@ -11,6 +11,7 @@ import com.google.common.collect.ImmutableMap;
 import org.junit.Before;
 import org.junit.Test;
 import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
+import org.opendaylight.controller.config.manager.impl.AbstractConfigTest.RecordingBundleContextServiceRegistrationHandler.RegistrationHolder;
 import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
 import org.opendaylight.controller.config.manager.impl.jmx.ServiceReferenceMXBean;
 import org.opendaylight.controller.config.manager.testingservices.parallelapsp.TestingParallelAPSPModuleFactory;
@@ -18,6 +19,7 @@ import org.opendaylight.controller.config.manager.testingservices.parallelapsp.t
 import org.opendaylight.controller.config.manager.testingservices.scheduledthreadpool.TestingScheduledThreadPoolModuleFactory;
 import org.opendaylight.controller.config.manager.testingservices.seviceinterface.TestingThreadPoolServiceInterface;
 import org.opendaylight.controller.config.manager.testingservices.threadpool.TestingFixedThreadPoolModuleFactory;
+import org.opendaylight.controller.config.manager.testingservices.threadpool.TestingThreadPoolIfc;
 import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
 
 import javax.management.Attribute;
@@ -27,7 +29,7 @@ import javax.management.JMX;
 import javax.management.MBeanException;
 import javax.management.ObjectName;
 import javax.management.ReflectionException;
-
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
@@ -41,6 +43,7 @@ public class ServiceReferenceRegistryImplTest extends AbstractParallelAPSPTest {
     @Before
     public void setUp() {
         super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(
+                mockedContext,
                 new TestingFixedThreadPoolModuleFactory(),
                 new TestingParallelAPSPModuleFactory(),
                 new TestingScheduledThreadPoolModuleFactory()));
@@ -71,11 +74,19 @@ public class ServiceReferenceRegistryImplTest extends AbstractParallelAPSPTest {
         // create apsp-parallel
         createParallelAPSP(transaction1, serviceReference);
         transaction1.commit();
+
         // check fixed1 is used
         ServiceReferenceMXBean serviceReferenceMXBean = JMX.newMXBeanProxy(platformMBeanServer,
                 withoutTransactionName(serviceReference), ServiceReferenceMXBean.class);
         assertEquals(withoutTransactionName(fixedTPTransactionON), serviceReferenceMXBean.getCurrentImplementation());
         checkApspThreadCount(fixedNrOfThreads);
+        // check OSGi SR
+        List<RegistrationHolder> registrations =
+                ((RecordingBundleContextServiceRegistrationHandler) currentBundleContextServiceRegistrationHandler).getRegistrations();
+        assertEquals(1, registrations.size());
+        RegistrationHolder record = registrations.get(0);
+        assertEquals(TestingThreadPoolIfc.class, record.clazz);
+        assertEquals(ImmutableMap.of("name","ref"), (Map<String, String>) record.props);
 
         // switch reference to scheduled
         ConfigTransactionJMXClient transaction2 = configRegistryClient.createTransaction();
index 123e52f6759e2ec9321c81aa36c6e655ddcb9c7f..d5d3823ef0e84f5e0d9e0d678d38b2094544a92b 100644 (file)
@@ -7,6 +7,14 @@
  */
 package org.opendaylight.controller.config.manager.impl.dependencyresolver;
 
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.reset;
+
+import java.util.Arrays;
+import java.util.List;
 import org.junit.Before;
 import org.junit.Test;
 import org.opendaylight.controller.config.api.JmxAttribute;
@@ -19,15 +27,7 @@ import org.opendaylight.controller.config.manager.impl.TransactionStatus;
 import org.opendaylight.controller.config.manager.impl.jmx.TransactionModuleJMXRegistrator.TransactionModuleJMXRegistration;
 import org.opendaylight.controller.config.spi.Module;
 import org.opendaylight.controller.config.spi.ModuleFactory;
-
-import java.util.Arrays;
-import java.util.List;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.reset;
+import org.osgi.framework.BundleContext;
 
 public class DependencyResolverManagerTest {
 
@@ -101,7 +101,7 @@ public class DependencyResolverManagerTest {
          moduleFactory,
          maybeOldInternalInfo,
          transactionModuleJMXRegistration,
-         isDefaultBean);
+         isDefaultBean, mock(BundleContext.class));
     }
 
     private static Module mockedModule() {
index 3c2230735eee0c41589e33dfb03b9e7c5972a0d8..dd6588f3f63cb7c0f06589f1890cb68c3f94b619 100644 (file)
@@ -60,10 +60,6 @@ public class HardcodedModuleFactoriesResolver implements ModuleFactoriesResolver
         }
     }
 
-    public HardcodedModuleFactoriesResolver(ModuleFactory... list) {
-        this(mockBundleContext(),list);
-    }
-
     private static BundleContext mockBundleContext() {
         BundleContext bundleContext = Mockito.mock(BundleContext.class);
         ServiceRegistration<ModuleFactory> serviceRegistration = mock(ServiceRegistration.class);
index 978d375cd24df6aff7cb508d4087c9cc1580b696..f42b9559c4bb7e5a562aead7b7a60c0bc692602f 100644 (file)
@@ -37,7 +37,7 @@ public class DependentWiringTest extends AbstractParallelAPSPTest {
 
     @Before
     public void setUp() {
-        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(
+        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,
                 new TestingFixedThreadPoolModuleFactory(),
                 new TestingParallelAPSPModuleFactory()));
     }
index 642f526efd703730e7c19931496cfb803d0e91cb..0d4fc91a51760963b5b1b6a7f7dae1792544b698 100644 (file)
@@ -7,12 +7,6 @@
  */
 package org.opendaylight.controller.config.manager.testingservices.parallelapsp.test;
 
-import java.io.Closeable;
-import java.io.IOException;
-import java.util.concurrent.Executor;
-
-import javax.management.ObjectName;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.opendaylight.controller.config.api.DynamicMBeanWithInstance;
@@ -27,6 +21,11 @@ import org.opendaylight.controller.config.manager.testingservices.threadpool.Tes
 import org.opendaylight.controller.config.spi.Module;
 import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
 
+import javax.management.ObjectName;
+import java.io.Closeable;
+import java.io.IOException;
+import java.util.concurrent.Executor;
+
 public class MockedDependenciesTest extends AbstractParallelAPSPTest {
     private final String threadPoolImplementationName = "mockedthreadpool";
 
@@ -36,7 +35,7 @@ public class MockedDependenciesTest extends AbstractParallelAPSPTest {
         ClassBasedModuleFactory mockedThreadPoolConfigFactory = new ClassBasedModuleFactory(
                 threadPoolImplementationName, MockedThreadPoolModule.class);
 
-        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(
+        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,
                 new TestingParallelAPSPModuleFactory(),
                 mockedThreadPoolConfigFactory));
     }
index 28fea454fe44ef4b472eba4b4e86d9364dfe9c72..340e19480175a124bb8408cead317fe05624f08f 100644 (file)
@@ -7,18 +7,17 @@
  */
 package org.opendaylight.controller.config.manager.testingservices.scheduledthreadpool.test;
 
-import static org.junit.Assert.assertEquals;
-
 import org.junit.After;
 import org.junit.Before;
 import org.opendaylight.controller.config.manager.impl.AbstractConfigTest;
 import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
 import org.opendaylight.controller.config.manager.testingservices.parallelapsp.TestingParallelAPSPModuleFactory;
 import org.opendaylight.controller.config.manager.testingservices.scheduledthreadpool.TestingScheduledThreadPoolImpl;
-import org.opendaylight.controller.config.manager.testingservices.scheduledthreadpool
-        .TestingScheduledThreadPoolModuleFactory;
+import org.opendaylight.controller.config.manager.testingservices.scheduledthreadpool.TestingScheduledThreadPoolModuleFactory;
 import org.opendaylight.controller.config.manager.testingservices.threadpool.TestingFixedThreadPoolModuleFactory;
 
+import static org.junit.Assert.assertEquals;
+
 public abstract class AbstractScheduledTest extends AbstractConfigTest {
     protected static final String scheduled1 = "scheduled1";
 
@@ -26,7 +25,7 @@ public abstract class AbstractScheduledTest extends AbstractConfigTest {
     public final void setUp() {
         assertEquals(0,
                 TestingScheduledThreadPoolImpl.getNumberOfCloseMethodCalls());
-        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(
+        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,
                 new TestingScheduledThreadPoolModuleFactory(),
                 new TestingFixedThreadPoolModuleFactory(),
                 new TestingParallelAPSPModuleFactory()));
index d5434d2ed53e6615d4e7d7ab4e742f43943875fe..25125fcd8287eb77928a258dd8c406a6c40d617b 100644 (file)
@@ -53,6 +53,7 @@ public class TestingFixedThreadPool implements TestingThreadPoolIfc, Closeable,
     @Override
     public void close() throws IOException {
         executorService.shutdown();
+        allExecutors.remove(executorService);
 
     }
 
diff --git a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/threadpool/test/ShutdownTest.java b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/threadpool/test/ShutdownTest.java
new file mode 100644 (file)
index 0000000..e047a1e
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * 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.manager.testingservices.threadpool.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.doReturn;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Map.Entry;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.opendaylight.controller.config.manager.impl.AbstractConfigTest;
+import org.opendaylight.controller.config.manager.impl.factoriesresolver.ModuleFactoriesResolver;
+import org.opendaylight.controller.config.manager.testingservices.threadpool.TestingFixedThreadPool;
+import org.opendaylight.controller.config.manager.testingservices.threadpool.TestingFixedThreadPoolModuleFactory;
+import org.opendaylight.controller.config.spi.ModuleFactory;
+import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
+import org.osgi.framework.BundleContext;
+
+public class ShutdownTest extends AbstractConfigTest {
+    private final TestingFixedThreadPoolModuleFactory testingFixedThreadPoolModuleFactory = new TestingFixedThreadPoolModuleFactory();
+
+    @Mock
+    ModuleFactoriesResolver mockedResolver;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        Map<String, Entry<ModuleFactory, BundleContext>> allFactories = ImmutableMap.of(
+                testingFixedThreadPoolModuleFactory.getImplementationName(),
+                Maps.<ModuleFactory, BundleContext>immutableEntry(testingFixedThreadPoolModuleFactory, mockedContext));
+        doReturn(allFactories).when(mockedResolver).getAllFactories();
+        super.initConfigTransactionManagerImpl(mockedResolver);
+    }
+
+
+    @Test
+    public void testCreateAndDestroyBeanInSameTransaction() throws Exception {
+        {
+            ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
+            SimpleConfigurationTest.createFixedThreadPool(transaction);
+            transaction.commit();
+        }
+        assertEquals(1, TestingFixedThreadPool.allExecutors.size());
+        doReturn(Collections.emptyMap()).when(mockedResolver).getAllFactories();
+        {
+            ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
+            transaction.commit();
+        }
+        assertEquals(1, TestingFixedThreadPool.allExecutors.size());
+    }
+}
index 9852a45853b1fad9f0bbd9ab4e3011bb06f8d29b..97d1c63ed2770da0ceb4fb504a4795a775b12c89 100644 (file)
@@ -56,7 +56,7 @@ import static org.junit.Assert.fail;
  * dependencies.
  */
 public class SimpleConfigurationTest extends AbstractConfigTest {
-    private final int numberOfThreads = 5;
+    private static final int numberOfThreads = 5;
     private final int numberOfThreads2 = 10;
     private static final String fixed1 = "fixed1";
     private static final List<ObjectName> emptyONs = Collections
@@ -68,7 +68,7 @@ public class SimpleConfigurationTest extends AbstractConfigTest {
 
     @Before
     public void setUp() {
-        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(
+        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,
                 new TestingFixedThreadPoolModuleFactory()));
     }
 
@@ -96,7 +96,7 @@ public class SimpleConfigurationTest extends AbstractConfigTest {
         return fixed1names;
     }
 
-    private ObjectName createFixedThreadPool(
+    static ObjectName createFixedThreadPool(
             ConfigTransactionJMXClient transaction)
             throws InstanceAlreadyExistsException, InstanceNotFoundException {
         transaction.assertVersion(0, 1);
@@ -246,8 +246,7 @@ public class SimpleConfigurationTest extends AbstractConfigTest {
 
         // 4, check
         assertEquals(2, configRegistryClient.getVersion());
-        assertEquals(1, TestingFixedThreadPool.allExecutors.size());
-        assertTrue(TestingFixedThreadPool.allExecutors.get(0).isShutdown());
+        assertEquals(0, TestingFixedThreadPool.allExecutors.size());
 
         // dynamic config should be removed from platform
         try {
@@ -278,7 +277,7 @@ public class SimpleConfigurationTest extends AbstractConfigTest {
         // commit
         transaction.commit();
         // check that first threadpool is closed
-        checkThreadPools(2, numberOfThreads2);
+        checkThreadPools(1, numberOfThreads2);
     }
 
     private void checkThreadPools(int expectedTotalNumberOfExecutors,
@@ -308,7 +307,7 @@ public class SimpleConfigurationTest extends AbstractConfigTest {
         // commit
         CommitStatus commitStatus = transaction.commit();
         // check that new threadpool is created and old one is closed
-        checkThreadPools(2, numberOfThreads);
+        checkThreadPools(1, numberOfThreads);
         CommitStatus expected = new CommitStatus(emptyONs, emptyONs, fixed1List);
         assertEquals(expected, commitStatus);
     }
@@ -337,6 +336,7 @@ public class SimpleConfigurationTest extends AbstractConfigTest {
             platformMBeanServer.getMBeanInfo(transaction.getObjectName());
             fail();
         }catch(InstanceNotFoundException e){
+            assertEquals("org.opendaylight.controller:TransactionName=ConfigTransaction-0-1,type=ConfigTransaction", e.getMessage());
         }
     }
 
index 1d4139f885152a0f9430ddf541f2c036bb6450ab..156fa580ce0c2403c78451d73702237f46f5ad79 100644 (file)
@@ -18,4 +18,7 @@ public interface PropertiesProvider {
      * @return prefix + key as used in getProperty method.
      */
     String getFullKeyForReporting(String key);
+
+    String getPrefix();
+    String getPropertyWithoutPrefix(String fullKey);
 }
index 2df07b114cf54ff327b10e5bdc7b40e859eb8410..3d4757b926f0fad6900d0c673ebd562c2afc9085 100644 (file)
@@ -26,4 +26,14 @@ public class PropertiesProviderTest implements PropertiesProvider {
     public String getFullKeyForReporting(String key) {
         return null;
     }
+
+    @Override
+    public String getPrefix() {
+        return null;
+    }
+
+    @Override
+    public String getPropertyWithoutPrefix(String fullKey) {
+        return null;
+    }
 }
index 296ce79f6e9cefeb5723107a59cef9b4cc0f3194..d9c9dada6202be0a4eac69d138329cb5f69c745f 100644 (file)
@@ -35,7 +35,7 @@ public class LogbackModuleTest extends AbstractConfigTest {
     public void setUp() throws Exception {
 
         factory = new LogbackModuleFactory();
-        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory));
+        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,factory));
     }
 
     @Test
index e543f752e17b44ee6ab2a1851b54168fccb422d6..37bfb6d9578920c62115fd4deebaf7dc8c2cf750 100644 (file)
@@ -49,7 +49,7 @@ public class LogbackModuleWithInitialConfigurationTest extends AbstractConfigTes
     public void setUp() throws IOException, ClassNotFoundException {
 
         factory = new LogbackModuleFactory();
-        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory));
+        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,factory));
     }
 
     /**
index 814965981226aa2ee71fa2184843ad741cc7d414..3c21e57f6e8aed1f298fd917bf434eda93d5647c 100644 (file)
@@ -42,7 +42,7 @@ public class LogbackWithXmlConfigModuleTest extends AbstractConfigTest {
     public void setUp() throws JoranException, IOException {
 
         factory = new LogbackModuleFactory();
-        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory));
+        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,factory));
 
         lc = (LoggerContext) LoggerFactory.getILoggerFactory();
         JoranConfigurator configurator = new JoranConfigurator();
index f29895c6d00c3428c0329b5aae5be1d494b2530f..e89d82a28fd6b3f8876e89724d254691bf90fad3 100644 (file)
@@ -31,7 +31,7 @@ public class GlobalEventExecutorModuleTest extends AbstractConfigTest {
     @Before
     public void setUp() {
         factory = new GlobalEventExecutorModuleFactory();
-        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory));
+        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,factory));
     }
 
     @Test
index 590bd9185e67ae1480da0527545fddc953e476bb..76134b025cf0c1a975338eb35c0644e8ba2d47db 100644 (file)
@@ -28,7 +28,7 @@ public class NettyThreadgroupModuleTest extends AbstractConfigTest {
     @Before
     public void setUp() {
         factory = new NettyThreadgroupModuleFactory();
-        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory));
+        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,factory));
     }
 
     @Test
index f9622192fec873f3fc01c1396aa4c06ccb8f1624..4abbd3b36f761b71bc521c9a769f091e8afa3b44 100644 (file)
@@ -82,7 +82,6 @@ class Impl implements ShutdownService {
 
 class StopSystemBundleThread extends Thread {
     private static final Logger logger = LoggerFactory.getLogger(StopSystemBundleThread.class);
-    public static final String CONFIG_MANAGER_SYMBOLIC_NAME = "org.opendaylight.controller.config-manager";
     private final Bundle systemBundle;
 
     StopSystemBundleThread(Bundle systemBundle) {
@@ -95,13 +94,6 @@ class StopSystemBundleThread extends Thread {
         try {
             // wait so that JMX response is received
             Thread.sleep(1000);
-            // first try to stop config-manager
-            Bundle configManager = findConfigManager();
-            if (configManager != null){
-                logger.debug("Stopping config-manager");
-                configManager.stop();
-                Thread.sleep(1000);
-            }
             logger.debug("Stopping system bundle");
             systemBundle.stop();
         } catch (BundleException e) {
@@ -110,16 +102,6 @@ class StopSystemBundleThread extends Thread {
             logger.warn("Shutdown process interrupted", e);
         }
     }
-
-    private Bundle findConfigManager() {
-        for(Bundle bundle: systemBundle.getBundleContext().getBundles()){
-            if (CONFIG_MANAGER_SYMBOLIC_NAME.equals(bundle.getSymbolicName())) {
-                return bundle;
-            }
-        }
-        return null;
-    }
-
 }
 
 class CallSystemExitThread extends Thread {
index d4a3160b89bf5da79c9b1407aa5bd3242f23b745..358586f63457e87c9d10ba52a295adec650377ff 100644 (file)
@@ -7,6 +7,17 @@
  */
 package org.opendaylight.controller.config.yang.shutdown.impl;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.verify;
+import static org.opendaylight.controller.config.yang.shutdown.impl.ShutdownModuleFactory.NAME;
+
+import java.util.Collections;
+import javax.management.InstanceNotFoundException;
+import javax.management.JMX;
+import javax.management.ObjectName;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mock;
@@ -20,22 +31,10 @@ import org.opendaylight.controller.config.manager.impl.factoriesresolver.ModuleF
 import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
 import org.osgi.framework.Bundle;
 
-import javax.management.InstanceNotFoundException;
-import javax.management.JMX;
-import javax.management.ObjectName;
-import java.util.Collections;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.verify;
-import static org.opendaylight.controller.config.yang.shutdown.impl.ShutdownModuleFactory.NAME;
-
 public class ShutdownTest extends AbstractConfigTest {
     private final ShutdownModuleFactory factory = new ShutdownModuleFactory();
     @Mock
-    private Bundle mockedSysBundle, mockedConfigManager;
+    private Bundle mockedSysBundle;
 
 
     @Before
@@ -46,11 +45,10 @@ public class ShutdownTest extends AbstractConfigTest {
         doReturn(mockedSysBundle).when(mockedContext).getBundle(0);
         mockedContext.getBundle(0);
         doNothing().when(mockedSysBundle).stop();
-        doNothing().when(mockedConfigManager).stop();
         doReturn(mockedContext).when(mockedSysBundle).getBundleContext();
-        doReturn(new Bundle[]{mockedSysBundle, mockedConfigManager}).when(mockedContext).getBundles();
+        doReturn(new Bundle[]{mockedSysBundle}).when(mockedContext).getBundles();
         doReturn("system bundle").when(mockedSysBundle).getSymbolicName();
-        doReturn(StopSystemBundleThread.CONFIG_MANAGER_SYMBOLIC_NAME).when(mockedConfigManager).getSymbolicName();
+
 
 
         ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
@@ -129,7 +127,6 @@ public class ShutdownTest extends AbstractConfigTest {
 
     private void assertStopped() throws Exception {
         Thread.sleep(3000); // happens on another thread
-        verify(mockedConfigManager).stop();
         verify(mockedSysBundle).stop();
     }
 }
index 177adc1588d0ce2697a010ce37eb747f5879d7ff..0b339fc6007834f9c8fad9cc9619457ee60fa9f1 100644 (file)
@@ -40,7 +40,7 @@ public class AsyncEventBusConfigBeanTest extends AbstractConfigTest {
                 TestingScheduledThreadPoolModule.class, poolImplName);
 
         factory = new AsyncEventBusModuleFactory();
-        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory,
+        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,factory,
                 scheduledThreadPoolConfigFactory));
     }
 
index bc5e98bcb358ec419685823e0403fefe4f6f2e2d..aeb6d6b959ab3ce70a662b7d2a6efbf773ce58f5 100644 (file)
@@ -7,14 +7,6 @@
  */
 package org.opendaylight.controller.config.threadpool.eventbus;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.fail;
-import static org.junit.matchers.JUnitMatchers.containsString;
-
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.ObjectName;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.opendaylight.controller.config.api.ConflictingVersionException;
@@ -25,6 +17,14 @@ import org.opendaylight.controller.config.manager.impl.factoriesresolver.Hardcod
 import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
 import org.opendaylight.controller.config.yang.threadpool.impl.EventBusModuleFactory;
 
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.ObjectName;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
+import static org.junit.matchers.JUnitMatchers.containsString;
+
 public class SyncEventBusConfigBeanTest extends AbstractConfigTest {
 
     private EventBusModuleFactory factory;
@@ -34,7 +34,7 @@ public class SyncEventBusConfigBeanTest extends AbstractConfigTest {
     public void setUp() {
 
         factory = new EventBusModuleFactory();
-        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory));
+        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,factory));
     }
 
     @Test
index 781215da43ef18063a2408a1478234b03df3fad2..c95661d9c95b7470ca45156b56c6bc2df3fe7fe6 100644 (file)
@@ -36,7 +36,7 @@ public class FixedThreadPoolConfigBeanTest extends AbstractConfigTest {
     @Before
     public void setUp() {
         factory = new FixedThreadPoolModuleFactory();
-        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory,
+        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,factory,
                 new NamingThreadFactoryModuleFactory()));
     }
 
index f0e8a108e74c76c43b14dfee998c60faee9fdd98..a1d1c40655ec867f8d0d7404a1c3e65e80cab66c 100644 (file)
@@ -38,7 +38,7 @@ public class FlexibleThreadPoolConfigBeanTest extends AbstractConfigTest {
     public void setUp() {
 
         flexibleFactory = new FlexibleThreadPoolModuleFactory();
-        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(flexibleFactory,
+        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,flexibleFactory,
                 new NamingThreadFactoryModuleFactory()));
     }
 
index 6dea96e21f3cf42d64f5ab1ed17b8981a61f5e2d..499beced5f4511906f2d7cf0ecaffd4335eae63d 100644 (file)
@@ -16,7 +16,6 @@ import static org.junit.matchers.JUnitMatchers.containsString;
 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;
@@ -38,7 +37,7 @@ public class NamingThreadPoolFactoryConfigBeanTest extends AbstractConfigTest {
     public void setUp() {
 
         factory = new NamingThreadFactoryModuleFactory();
-        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory));
+        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext, factory));
     }
 
     @Test
index 538d43726b1119f7a913da4a328ddbc2c5b08011..ef06e43d2f291b87f994d04612c0f9f5488ea86b 100644 (file)
@@ -39,7 +39,7 @@ public class ScheduledThreadPoolConfigBeanTest extends AbstractConfigTest {
     public void setUp() {
 
         factory = new ScheduledThreadPoolModuleFactory();
-        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory,
+        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext, factory,
                 new NamingThreadFactoryModuleFactory()));
     }
 
index 598b6b3d5b5ca6cf7f19b79b56de11f6cfa82c06..7505fcf485c62431fc29ee28b8d635cb5a7e6519 100644 (file)
@@ -7,11 +7,6 @@
  */
 package org.opendaylight.controller.config.yangjmxgenerator.it;
 
-import static org.junit.Assert.fail;
-
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.ObjectName;
-
 import org.junit.Before;
 import org.junit.Ignore;
 import org.junit.Test;
@@ -26,6 +21,11 @@ import org.opendaylight.controller.config.yang.test.impl.DtoB;
 import org.opendaylight.controller.config.yang.test.impl.TestImplModuleFactory;
 import org.opendaylight.controller.config.yang.test.impl.TestImplModuleMXBean;
 
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.ObjectName;
+
+import static org.junit.Assert.fail;
+
 @Ignore
 // ietf beans are not JMX compliant beans:
 // Do not know how to make a
@@ -42,7 +42,7 @@ public class ITTest extends AbstractConfigTest {
     public void setUp() {
 
         factory = new TestImplModuleFactory();
-        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(
+        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,
                 factory));
     }
 
index 2d49ed7fab1bb21b595d68d35683c8d9e7d7f85a..b8831f6979ec3205e496c13ee1df15217d3d9feb 100644 (file)
 
   </dependencies>
 
-  <build>
-    <plugins>
-      <plugin>
-        <artifactId>maven-compiler-plugin</artifactId>
-        <version>3.1</version>
-        <configuration>
-          <compilerId>groovy-eclipse-compiler</compilerId>
-          <verbose>false</verbose>
-        </configuration>
-        <dependencies>
-
-          <dependency>
-            <groupId>org.codehaus.groovy</groupId>
-            <artifactId>groovy-eclipse-batch</artifactId>
-            <version>2.1.8-01</version>
-          </dependency>
-          <dependency>
-            <groupId>org.codehaus.groovy</groupId>
-            <artifactId>groovy-eclipse-compiler</artifactId>
-            <version>2.8.0-01</version>
-          </dependency>
-        </dependencies>
-      </plugin>
-
-    </plugins>
-  </build>
 </project>
diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/gofactory/AbsFactoryGeneratedObjectFactory.groovy b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/gofactory/AbsFactoryGeneratedObjectFactory.groovy
deleted file mode 100644 (file)
index baff88c..0000000
+++ /dev/null
@@ -1,168 +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.config.yangjmxgenerator.plugin.gofactory
-import com.google.common.base.Optional
-import org.opendaylight.controller.config.api.DependencyResolver
-import org.opendaylight.controller.config.api.DynamicMBeanWithInstance
-import org.opendaylight.controller.config.api.ModuleIdentifier
-import org.opendaylight.controller.config.api.annotations.AbstractServiceInterface
-import org.opendaylight.controller.config.api.annotations.Description
-import org.opendaylight.controller.config.spi.Module
-import org.opendaylight.controller.config.spi.ModuleFactory
-import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry
-import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.AbstractFactoryTemplate
-import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.TemplateFactory
-import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Annotation
-import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Field
-import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.*
-import org.opendaylight.yangtools.yang.common.QName
-import org.osgi.framework.BundleContext
-
-public class AbsFactoryGeneratedObjectFactory {
-
-    public GeneratedObject toGeneratedObject(ModuleMXBeanEntry mbe, Optional<String> copyright) {
-        FullyQualifiedName absFactoryFQN = new FullyQualifiedName(mbe.packageName, mbe.abstractFactoryName)
-        FullyQualifiedName moduleFQN = new FullyQualifiedName(mbe.packageName, mbe.stubModuleName)
-        Optional<String> classJavaDoc = Optional.fromNullable(mbe.getNullableDescription())
-
-        AbstractFactoryTemplate abstractFactoryTemplate = TemplateFactory.abstractFactoryTemplateFromMbe(mbe)
-        Optional<String> header = abstractFactoryTemplate.headerString;
-        List<FullyQualifiedName> providedServices = mbe.providedServices.keySet().collect {
-            FullyQualifiedName.fromString(it)
-        }
-
-
-        return toGeneratedObject(absFactoryFQN, copyright,
-                header, classJavaDoc, mbe.yangModuleQName,
-                mbe.globallyUniqueName,
-                providedServices,
-                moduleFQN,
-                abstractFactoryTemplate.fields)
-    }
-
-    public GeneratedObject toGeneratedObject(FullyQualifiedName absFactoryFQN, Optional<String> copyright,
-                                             Optional<String> header, Optional<String> classJavaDoc, QName yangModuleQName,
-                                             String globallyUniqueName,
-                                             List<FullyQualifiedName> providedServices,
-                                             FullyQualifiedName moduleFQN,
-                                             List<Field> moduleFields) {
-        JavaFileInputBuilder b = new JavaFileInputBuilder()
-        Annotation moduleQNameAnnotation = Annotation.createModuleQNameANnotation(yangModuleQName)
-        b.addClassAnnotation(moduleQNameAnnotation)
-
-        b.setFqn(absFactoryFQN)
-        b.setTypeName(TypeName.absClassType)
-
-        b.setCopyright(copyright);
-        b.setHeader(header);
-        b.setClassJavaDoc(classJavaDoc);
-        b.addImplementsFQN(new FullyQualifiedName(ModuleFactory))
-        if (classJavaDoc.isPresent()) {
-            b.addClassAnnotation("@${Description.canonicalName}(value=\"${classJavaDoc.get()}\")")
-        }
-
-        b.addToBody("public static final java.lang.String NAME = \"${globallyUniqueName}\";")
-        b.addToBody("private static final java.util.Set<Class<? extends ${AbstractServiceInterface.canonicalName}>> serviceIfcs;")
-
-        b.addToBody("@Override\n public final String getImplementationName() { \n return NAME; \n}")
-
-        b.addToBody(getServiceIfcsInitialization(providedServices))
-
-        // createModule
-        b.addToBody("""
-            @Override
-            public ${Module.canonicalName} createModule(String instanceName, ${DependencyResolver.canonicalName} dependencyResolver, ${BundleContext.canonicalName} bundleContext) {
-                return instantiateModule(instanceName, dependencyResolver, bundleContext);
-            }
-            """)
-
-        b.addToBody(getCreateModule(moduleFQN, moduleFields))
-
-        b.addToBody("""
-            public ${moduleFQN} instantiateModule(String instanceName, ${DependencyResolver.canonicalName} dependencyResolver, ${moduleFQN} oldModule, ${AutoCloseable.canonicalName} oldInstance, ${BundleContext.canonicalName} bundleContext) {
-                return new ${moduleFQN}(new ${ModuleIdentifier.canonicalName}(NAME, instanceName), dependencyResolver, oldModule, oldInstance);
-            }
-            """)
-
-        b.addToBody("""
-            public ${moduleFQN} instantiateModule(String instanceName, ${DependencyResolver.canonicalName} dependencyResolver, ${BundleContext.canonicalName} bundleContext) {
-                return new ${moduleFQN}(new ${ModuleIdentifier.canonicalName}(NAME, instanceName), dependencyResolver);
-            }
-            """)
-
-        b.addToBody("""
-            public ${moduleFQN} handleChangedClass(${DynamicMBeanWithInstance.canonicalName} old) throws Exception {
-                throw new UnsupportedOperationException("Class reloading is not supported");
-            }
-            """)
-
-        b.addToBody("""
-            @Override
-            public java.util.Set<${moduleFQN}> getDefaultModules(org.opendaylight.controller.config.api.DependencyResolverFactory dependencyResolverFactory, ${BundleContext.canonicalName} bundleContext) {
-                return new java.util.HashSet<${moduleFQN}>();
-            }
-            """)
-
-        return new GeneratedObjectBuilder(b.build()).toGeneratedObject()
-    }
-
-    private static String getCreateModule(FullyQualifiedName moduleFQN, List<Field> moduleFields) {
-        String result = """
-            @Override
-            public ${Module.canonicalName} createModule(String instanceName, ${DependencyResolver.canonicalName} dependencyResolver, ${DynamicMBeanWithInstance.canonicalName} old, ${BundleContext.canonicalName} bundleContext) throws Exception {
-                ${moduleFQN} oldModule = null;
-                try {
-                    oldModule = (${moduleFQN}) old.getModule();
-                } catch(Exception e) {
-                    return handleChangedClass(old);
-                }
-                ${moduleFQN} module = instantiateModule(instanceName, dependencyResolver, oldModule, old.getInstance(), bundleContext);
-            """
-        result += moduleFields.collect{"module.set${it.name}(oldModule.get${it.name}());"}.join("\n")
-        result += """
-                return module;
-            }
-            """
-        return result
-    }
-
-    private static String getServiceIfcsInitialization(List<FullyQualifiedName> providedServices) {
-        String generic = "Class<? extends ${AbstractServiceInterface.canonicalName}>"
-
-        String result = """static {
-            java.util.Set<${generic}> serviceIfcs2 = new java.util.HashSet<${generic}>();
-            """
-        result += providedServices.collect{"serviceIfcs2.add(${it}.class);"}.join("\n")
-        result += """serviceIfcs = java.util.Collections.unmodifiableSet(serviceIfcs2);
-            }
-            """
-
-        // add isModuleImplementingServiceInterface and getImplementedServiceIntefaces methods
-
-        result += """
-            @Override
-            public final boolean isModuleImplementingServiceInterface(Class<? extends ${AbstractServiceInterface.canonicalName}> serviceInterface) {
-                for (Class<?> ifc: serviceIfcs) {
-                    if (serviceInterface.isAssignableFrom(ifc)){
-                        return true;
-                    }
-                }
-                return false;
-            }
-
-            @Override
-            public java.util.Set<Class<? extends ${AbstractServiceInterface.canonicalName}>> getImplementedServiceIntefaces() {
-                return serviceIfcs;
-            }
-            """
-
-        return result
-    }
-
-}
diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/gofactory/AbsFactoryGeneratedObjectFactory.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/gofactory/AbsFactoryGeneratedObjectFactory.java
new file mode 100644 (file)
index 0000000..48a6c15
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.config.yangjmxgenerator.plugin.gofactory;
+
+import static java.lang.String.format;
+
+import com.google.common.base.Optional;
+import java.util.ArrayList;
+import java.util.List;
+import org.opendaylight.controller.config.api.DependencyResolver;
+import org.opendaylight.controller.config.api.DynamicMBeanWithInstance;
+import org.opendaylight.controller.config.api.ModuleIdentifier;
+import org.opendaylight.controller.config.api.annotations.AbstractServiceInterface;
+import org.opendaylight.controller.config.api.annotations.Description;
+import org.opendaylight.controller.config.spi.Module;
+import org.opendaylight.controller.config.spi.ModuleFactory;
+import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
+import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.AbstractFactoryTemplate;
+import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.TemplateFactory;
+import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Annotation;
+import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Field;
+import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.FullyQualifiedName;
+import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.GeneratedObject;
+import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.GeneratedObjectBuilder;
+import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.JavaFileInputBuilder;
+import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.TypeName;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.osgi.framework.BundleContext;
+
+public class AbsFactoryGeneratedObjectFactory {
+
+    public GeneratedObject toGeneratedObject(ModuleMXBeanEntry mbe, Optional<String> copyright) {
+        FullyQualifiedName absFactoryFQN = new FullyQualifiedName(mbe.getPackageName(), mbe.getAbstractFactoryName());
+        FullyQualifiedName moduleFQN = new FullyQualifiedName(mbe.getPackageName(), mbe.getStubModuleName());
+        Optional<String> classJavaDoc = Optional.fromNullable(mbe.getNullableDescription());
+
+        AbstractFactoryTemplate abstractFactoryTemplate = TemplateFactory.abstractFactoryTemplateFromMbe(mbe);
+        Optional<String> header = abstractFactoryTemplate.getHeaderString();
+
+        List<FullyQualifiedName> providedServices = new ArrayList<>();
+        for(String providedService: mbe.getProvidedServices().keySet()) {
+            providedServices.add(FullyQualifiedName.fromString(providedService));
+        }
+
+        return toGeneratedObject(absFactoryFQN, copyright,
+                header, classJavaDoc, mbe.getYangModuleQName(),
+                mbe.getGloballyUniqueName(),
+                providedServices,
+                moduleFQN,
+                abstractFactoryTemplate.getFields());
+    }
+
+    public GeneratedObject toGeneratedObject(FullyQualifiedName absFactoryFQN, Optional<String> copyright,
+                                             Optional<String> header, Optional<String> classJavaDoc, QName yangModuleQName,
+                                             String globallyUniqueName,
+                                             List<FullyQualifiedName> providedServices,
+                                             FullyQualifiedName moduleFQN,
+                                             List<Field> moduleFields) {
+        JavaFileInputBuilder b = new JavaFileInputBuilder();
+        Annotation moduleQNameAnnotation = Annotation.createModuleQNameANnotation(yangModuleQName);
+        b.addClassAnnotation(moduleQNameAnnotation);
+
+        b.setFqn(absFactoryFQN);
+        b.setTypeName(TypeName.absClassType);
+
+        b.setCopyright(copyright);
+        b.setHeader(header);
+        b.setClassJavaDoc(classJavaDoc);
+        b.addImplementsFQN(new FullyQualifiedName(ModuleFactory.class));
+        if (classJavaDoc.isPresent()) {
+            b.addClassAnnotation(format("@%s(value=\"%s\")", Description.class.getCanonicalName(), classJavaDoc.get()));
+        }
+
+        b.addToBody(format("public static final java.lang.String NAME = \"%s\";", globallyUniqueName));
+        b.addToBody(format("private static final java.util.Set<Class<? extends %s>> serviceIfcs;",
+                AbstractServiceInterface.class.getCanonicalName()));
+
+        b.addToBody("@Override\n public final String getImplementationName() { \n return NAME; \n}");
+
+        b.addToBody(getServiceIfcsInitialization(providedServices));
+
+        // createModule
+        b.addToBody(format("\n"+
+            "@Override\n"+
+            "public %s createModule(String instanceName, %s dependencyResolver, %s bundleContext) {\n"+
+                "return instantiateModule(instanceName, dependencyResolver, bundleContext);\n"+
+            "}\n",
+                Module.class.getCanonicalName(), DependencyResolver.class.getCanonicalName(), BundleContext.class.getCanonicalName()));
+
+        b.addToBody(getCreateModule(moduleFQN, moduleFields));
+
+        b.addToBody(format("\n"+
+            "public %s instantiateModule(String instanceName, %s dependencyResolver, %s oldModule, %s oldInstance, %s bundleContext) {\n"+
+                "return new %s(new %s(NAME, instanceName), dependencyResolver, oldModule, oldInstance);\n"+
+            "}\n",
+                moduleFQN, DependencyResolver.class.getCanonicalName(), moduleFQN, AutoCloseable.class.getCanonicalName(),
+                BundleContext.class.getCanonicalName(), moduleFQN, ModuleIdentifier.class.getCanonicalName()));
+
+        b.addToBody(format("\n"+
+            "public %s instantiateModule(String instanceName, %s dependencyResolver, %s bundleContext) {\n"+
+                "return new %s(new %s(NAME, instanceName), dependencyResolver);\n"+
+            "}\n", moduleFQN, DependencyResolver.class.getCanonicalName(), BundleContext.class.getCanonicalName(),
+                moduleFQN, ModuleIdentifier.class.getCanonicalName()
+        ));
+
+        b.addToBody(format("\n"+
+            "public %s handleChangedClass(%s old) throws Exception {\n"+
+                "throw new UnsupportedOperationException(\"Class reloading is not supported\");\n"+
+            "}\n", moduleFQN, DynamicMBeanWithInstance.class.getCanonicalName()));
+
+        b.addToBody(format("\n"+
+            "@Override\n"+
+            "public java.util.Set<%s> getDefaultModules(org.opendaylight.controller.config.api.DependencyResolverFactory dependencyResolverFactory, %s bundleContext) {\n"+
+                "return new java.util.HashSet<%s>();\n"+
+            "}\n", moduleFQN, BundleContext.class.getCanonicalName(), moduleFQN));
+
+        return new GeneratedObjectBuilder(b.build()).toGeneratedObject();
+    }
+
+    private static String getCreateModule(FullyQualifiedName moduleFQN, List<Field> moduleFields) {
+        String result = "\n"+
+            "@Override\n"+
+            format("public %s createModule(String instanceName, %s dependencyResolver, %s old, %s bundleContext) throws Exception {\n",
+                                Module.class.getCanonicalName(),DependencyResolver.class.getCanonicalName(),
+                                DynamicMBeanWithInstance.class.getCanonicalName(),BundleContext.class.getCanonicalName())+
+                format("%s oldModule = null;\n",moduleFQN)+
+                "try {\n"+
+                    format("oldModule = (%s) old.getModule();\n",moduleFQN)+
+                "} catch(Exception e) {\n"+
+                    "return handleChangedClass(old);\n"+
+                "}\n"+
+            format("%s module = instantiateModule(instanceName, dependencyResolver, oldModule, old.getInstance(), bundleContext);\n", moduleFQN);
+
+        for(Field field: moduleFields) {
+            result += format("module.set%s(oldModule.get%1$s());\n", field.getName());
+        }
+
+        result += "\n"+
+                "return module;\n"+
+            "}\n";
+        return result;
+    }
+
+    private static String getServiceIfcsInitialization(List<FullyQualifiedName> providedServices) {
+        String generic = format("Class<? extends %s>", AbstractServiceInterface.class.getCanonicalName());
+
+        String result = format("static {\n"+
+            "java.util.Set<%1$s> serviceIfcs2 = new java.util.HashSet<%1$s>();\n", generic);
+
+        for(FullyQualifiedName fqn: providedServices) {
+            result += format("serviceIfcs2.add(%s.class);\n", fqn);
+        }
+        result += "serviceIfcs = java.util.Collections.unmodifiableSet(serviceIfcs2);\n"+
+            "}\n";
+
+        // add isModuleImplementingServiceInterface and getImplementedServiceIntefaces methods
+
+        result += format("\n"+
+            "@Override\n"+
+            "public final boolean isModuleImplementingServiceInterface(Class<? extends %1$s> serviceInterface) {\n"+
+                "for (Class<?> ifc: serviceIfcs) {\n"+
+                    "if (serviceInterface.isAssignableFrom(ifc)){\n"+
+                        "return true;\n"+
+                    "}\n"+
+                "}\n"+
+                "return false;\n"+
+            "}\n"+
+            "\n"+
+            "@Override\n"+
+            "public java.util.Set<Class<? extends %1$s>> getImplementedServiceIntefaces() {\n"+
+                "return serviceIfcs;\n"+
+            "}\n", AbstractServiceInterface.class.getCanonicalName());
+
+        return result;
+    }
+
+}
diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/gofactory/AbsModuleGeneratedObjectFactory.groovy b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/gofactory/AbsModuleGeneratedObjectFactory.groovy
deleted file mode 100644 (file)
index 930acff..0000000
+++ /dev/null
@@ -1,400 +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.config.yangjmxgenerator.plugin.gofactory
-import com.google.common.base.Optional
-import org.opendaylight.controller.config.api.DependencyResolver
-import org.opendaylight.controller.config.api.ModuleIdentifier
-import org.opendaylight.controller.config.api.annotations.Description
-import org.opendaylight.controller.config.api.runtime.RootRuntimeBeanRegistrator
-import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry
-import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.AbstractModuleTemplate
-import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.TemplateFactory
-import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Annotation
-import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.IdentityRefModuleField
-import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Method
-import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.ModuleField
-import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.*
-import org.opendaylight.yangtools.yang.common.QName
-import org.slf4j.Logger
-import org.slf4j.LoggerFactory
-
-public class AbsModuleGeneratedObjectFactory {
-
-    public GeneratedObject toGeneratedObject(ModuleMXBeanEntry mbe, Optional<String> copyright) {
-        FullyQualifiedName abstractFQN = new FullyQualifiedName(mbe.getPackageName(), mbe.getAbstractModuleName())
-        Optional<String> classJavaDoc = Optional.fromNullable(mbe.getNullableDescription())
-        AbstractModuleTemplate abstractModuleTemplate = TemplateFactory.abstractModuleTemplateFromMbe(mbe)
-        Optional<String> header = abstractModuleTemplate.headerString;
-        List<FullyQualifiedName> implementedInterfaces = abstractModuleTemplate.getTypeDeclaration().getImplemented().collect {
-            FullyQualifiedName.fromString(it)
-        }
-        Optional<FullyQualifiedName> maybeRegistratorType
-        if (abstractModuleTemplate.isRuntime()) {
-            maybeRegistratorType = Optional.of(FullyQualifiedName.fromString(abstractModuleTemplate.getRegistratorType()))
-        } else {
-            maybeRegistratorType = Optional.absent()
-        }
-
-        return toGeneratedObject(abstractFQN, copyright, header, classJavaDoc, implementedInterfaces,
-                abstractModuleTemplate.getModuleFields(), maybeRegistratorType, abstractModuleTemplate.getMethods(),
-                mbe.yangModuleQName
-        )
-    }
-
-    public GeneratedObject toGeneratedObject(FullyQualifiedName abstractFQN,
-                                             Optional<String> copyright,
-                                             Optional<String> header,
-                                             Optional<String> classJavaDoc,
-                                             List<FullyQualifiedName> implementedInterfaces,
-                                             List<ModuleField> moduleFields,
-                                             Optional<FullyQualifiedName> maybeRegistratorType,
-                                             List<Method> methods,
-                                             QName yangModuleQName) {
-        JavaFileInputBuilder b = new JavaFileInputBuilder()
-
-        Annotation moduleQNameAnnotation = Annotation.createModuleQNameANnotation(yangModuleQName)
-        b.addClassAnnotation(moduleQNameAnnotation)
-
-        b.setFqn(abstractFQN)
-        b.setTypeName(TypeName.absClassType)
-
-        b.setCopyright(copyright);
-        b.setHeader(header);
-        b.setClassJavaDoc(classJavaDoc);
-        implementedInterfaces.each { b.addImplementsFQN(it) }
-        if (classJavaDoc.isPresent()) {
-            b.addClassAnnotation("@${Description.canonicalName}(value=\"${classJavaDoc.get()}\")")
-        }
-
-        // add logger:
-        b.addToBody(getLogger(abstractFQN));
-
-        b.addToBody("//attributes start");
-
-        b.addToBody(moduleFields.collect { it.toString() }.join("\n"))
-
-        b.addToBody("//attributes end");
-
-
-        b.addToBody(getCommonFields(abstractFQN));
-
-
-        b.addToBody(getNewConstructor(abstractFQN))
-        b.addToBody(getCopyFromOldConstructor(abstractFQN))
-
-        b.addToBody(getRuntimeRegistratorCode(maybeRegistratorType))
-        b.addToBody(getValidationMethods(moduleFields))
-
-        b.addToBody(getCachesOfResolvedDependencies(moduleFields))
-        b.addToBody(getCachesOfResolvedIdentityRefs(moduleFields))
-        b.addToBody(getGetInstance(moduleFields))
-        b.addToBody(getReuseLogic(moduleFields, abstractFQN))
-        b.addToBody(getEqualsAndHashCode(abstractFQN))
-
-        b.addToBody(getMethods(methods))
-
-        return new GeneratedObjectBuilder(b.build()).toGeneratedObject()
-    }
-
-    private static String getMethods(List<Method> methods) {
-        String result = """
-            // getters and setters
-        """
-        result += methods.collect{it.toString()}.join("\n")
-        return result
-    }
-
-    private static String getEqualsAndHashCode(FullyQualifiedName abstractFQN) {
-        return """
-            @Override
-            public boolean equals(Object o) {
-                if (this == o) return true;
-                if (o == null || getClass() != o.getClass()) return false;
-                ${abstractFQN.typeName} that = (${abstractFQN.typeName}) o;
-                return identifier.equals(that.identifier);
-            }
-
-            @Override
-            public int hashCode() {
-                return identifier.hashCode();
-            }
-        """
-    }
-
-    private static String getReuseLogic(List<ModuleField> moduleFields, FullyQualifiedName abstractFQN) {
-        String result = """
-            public boolean canReuseInstance(${abstractFQN.typeName} oldModule){
-                // allow reusing of old instance if no parameters was changed
-                return isSame(oldModule);
-            }
-
-            public ${AutoCloseable.canonicalName} reuseInstance(${AutoCloseable.canonicalName} oldInstance){
-                // implement if instance reuse should be supported. Override canReuseInstance to change the criteria.
-                return oldInstance;
-            }
-            """
-        // isSame method that detects changed fields
-        result += """
-            public boolean isSame(${abstractFQN.typeName} other) {
-                if (other == null) {
-                    throw new IllegalArgumentException("Parameter 'other' is null");
-                }
-            """
-        // loop through fields, do deep equals on each field
-        result += moduleFields.collect { field ->
-            if (field.isListOfDependencies()) {
-                return """
-                    if (${field.name}Dependency.equals(other.${field.name}Dependency) == false) {
-                        return false;
-                    }
-                    for (int idx = 0; idx < ${field.name}Dependency.size(); idx++) {
-                        if (${field.name}Dependency.get(idx) != other.${field.name}Dependency.get(idx)) {
-                            return false;
-                        }
-                    }
-                """
-            } else if (field.isDependent()) {
-                return """
-                    if (${field.name}Dependency != other.${field.name}Dependency) { // reference to dependency must be same
-                        return false;
-                    }
-                """
-            } else {
-                return """
-                    if (java.util.Objects.deepEquals(${field.name}, other.${field.name}) == false) {
-                        return false;
-                    }
-                """
-            }
-        }.join("\n")
-
-
-        result += """
-                return true;
-            }
-            """
-
-        return result
-    }
-
-    private static String getGetInstance(List<ModuleField> moduleFields) {
-        String result = """
-            @Override
-            public final ${AutoCloseable.canonicalName} getInstance() {
-                if(instance==null) {
-            """
-        // create instance start
-
-        // loop through dependent fields, use dependency resolver to instantiate dependencies. Do it in loop in case field represents list of dependencies.
-        Map<ModuleField, String> resolveDependenciesMap = moduleFields.findAll {
-            it.isDependent()
-        }.collectEntries { ModuleField field ->
-            [field, field.isList() ?
-                    """
-                ${field.name}Dependency = new java.util.ArrayList<${field.dependency.sie.exportedOsgiClassName}>();
-                for(javax.management.ObjectName dep : ${field.name}) {
-                    ${field.name}Dependency.add(dependencyResolver.resolveInstance(${
-                        field.dependency.sie.exportedOsgiClassName
-                    }.class, dep, ${field.name}JmxAttribute));
-                }
-                """
-                    :
-                    """
-                ${field.name}Dependency = dependencyResolver.resolveInstance(${
-                        field.dependency.sie.exportedOsgiClassName
-                    }.class, ${field.name}, ${field.name}JmxAttribute);
-                """
-            ]
-        }
-        // wrap each field resolvation statement with if !=null when dependency is not mandatory
-        def wrapWithNullCheckClosure = {Map<ModuleField, String> map, predicate -> map.collect { ModuleField key, String value ->
-            predicate(key) ? """
-                if(${key.name}!=null) {
-                    ${value}
-                }
-                """ : value
-            }.join("\n")
-        }
-
-        result += wrapWithNullCheckClosure(resolveDependenciesMap, {ModuleField key ->
-            key.getDependency().isMandatory() == false} )
-
-        // add code to inject dependency resolver to fields that support it
-        Map<ModuleField, String> injectDepsMap = moduleFields.findAll { it.needsDepResolver }.collectEntries { field ->
-            if (field.isList()) {
-                return [field,"""
-                for(${field.genericInnerType} candidate : ${field.name}) {
-                    candidate.injectDependencyResolver(dependencyResolver);
-                }
-                """]
-            } else {
-                return [field, "${field.name}.injectDependencyResolver(dependencyResolver);"]
-            }
-        }
-
-        result += wrapWithNullCheckClosure(injectDepsMap, {true})
-
-        // identity refs need to be injected with dependencyResolver and base class
-        Map<ModuleField, String> resolveIdentityMap = moduleFields.findAll { it.isIdentityRef() }.collectEntries { IdentityRefModuleField field ->
-            [field,
-            "set${field.attributeName}(${field.name}.resolveIdentity(dependencyResolver, ${field.identityBaseClass}.class));"]
-        }
-
-        result += wrapWithNullCheckClosure(resolveIdentityMap, {true})
-
-        // create instance end: reuse and recreate logic
-        result += """
-                    if(oldInstance!=null && canReuseInstance(oldModule)) {
-                        instance = reuseInstance(oldInstance);
-                    } else {
-                        if(oldInstance!=null) {
-                            try {
-                                oldInstance.close();
-                            } catch(Exception e) {
-                                logger.error("An error occurred while closing old instance " + oldInstance, e);
-                            }
-                        }
-                        instance = createInstance();
-                        if (instance == null) {
-                            throw new IllegalStateException("Error in createInstance - null is not allowed as return value");
-                        }
-                    }
-                }
-                return instance;
-            }
-            public abstract ${AutoCloseable.canonicalName} createInstance();
-            """
-        return result
-    }
-
-    private static String getCommonFields(FullyQualifiedName abstractFQN) {
-        return """
-            private final ${abstractFQN.typeName} oldModule;
-            private final ${AutoCloseable.canonicalName} oldInstance;
-            private ${AutoCloseable.canonicalName} instance;
-            private final ${DependencyResolver.canonicalName} dependencyResolver;
-            private final ${ModuleIdentifier.canonicalName} identifier;
-            @Override
-            public ${ModuleIdentifier.canonicalName} getIdentifier() {
-                return identifier;
-            }
-            """
-    }
-
-    private static String getCachesOfResolvedIdentityRefs(List<ModuleField> moduleFields) {
-        return moduleFields.findAll { it.isIdentityRef() }.collect { IdentityRefModuleField field ->
-            "private ${field.identityClassType} ${field.identityClassName};"
-        }.join("\n")
-    }
-
-    private static String getCachesOfResolvedDependencies(List<ModuleField> moduleFields) {
-        return moduleFields.findAll { it.dependent }.collect { field ->
-            if (field.isList()) {
-                return """
-                    private java.util.List<${field.dependency.sie.exportedOsgiClassName}> ${
-                    field.name
-                }Dependency = new java.util.ArrayList<${field.dependency.sie.exportedOsgiClassName}>();
-                    protected final java.util.List<${field.dependency.sie.exportedOsgiClassName}> get${
-                    field.attributeName
-                }Dependency(){
-                        return ${field.name}Dependency;
-                    }
-                    """
-            } else {
-                return """
-                    private ${field.dependency.sie.exportedOsgiClassName} ${field.name}Dependency;
-                    protected final ${field.dependency.sie.exportedOsgiClassName} get${field.attributeName}Dependency(){
-                        return ${field.name}Dependency;
-                    }
-                    """
-            }
-        }.join("\n")
-    }
-
-    private static String getRuntimeRegistratorCode(Optional<FullyQualifiedName> maybeRegistratorType) {
-        if (maybeRegistratorType.isPresent()) {
-            String registratorType = maybeRegistratorType.get()
-
-            return """
-                private ${registratorType} rootRuntimeBeanRegistratorWrapper;
-
-                public ${registratorType} getRootRuntimeBeanRegistratorWrapper(){
-                    return rootRuntimeBeanRegistratorWrapper;
-                }
-
-                @Override
-                public void setRuntimeBeanRegistrator(${RootRuntimeBeanRegistrator.canonicalName} rootRuntimeRegistrator){
-                    this.rootRuntimeBeanRegistratorWrapper = new ${registratorType}(rootRuntimeRegistrator);
-                }
-                """
-        } else {
-            return ""
-        }
-    }
-
-    private static String getValidationMethods(List<ModuleField> moduleFields) {
-        String result = """
-            @Override
-            public void validate() {
-            """
-        // validate each mandatory dependency
-        List<String> lines = moduleFields.findAll{(it.dependent && it.dependency.mandatory)}.collect { field ->
-            if (field.isList()) {
-                return "" +
-                        "for(javax.management.ObjectName dep : ${field.name}) {\n" +
-                        "    dependencyResolver.validateDependency(${field.dependency.sie.fullyQualifiedName}.class, dep, ${field.name}JmxAttribute);\n" +
-                        "}\n"
-            } else {
-                return "dependencyResolver.validateDependency(${field.dependency.sie.fullyQualifiedName}.class, ${field.name}, ${field.name}JmxAttribute);"
-            }
-        }
-        result += lines.findAll { it.isEmpty() == false }.join("\n")
-        result += """
-                customValidation();
-            }
-
-            protected void customValidation(){
-            }
-        """
-        return result
-    }
-
-    private static String getLogger(FullyQualifiedName fqn) {
-        return "private static final ${Logger.canonicalName} logger = ${LoggerFactory.canonicalName}.getLogger(${fqn.toString()}.class);"
-    }
-
-    // assumes that each parameter name corresponds to an field in this class, constructs lines setting this.field = field;
-    private static String getConstructorStart(FullyQualifiedName fqn,
-                                              LinkedHashMap<String, String> parameters, String after) {
-        return "public ${fqn.typeName}(" +
-                parameters.collect { it.key + " " + it.value }.join(",") +
-                ") {\n" +
-                parameters.values().collect { "this.${it}=${it};\n" }.join() +
-                after +
-                "}\n"
-    }
-
-    private static String getNewConstructor(FullyQualifiedName abstractFQN) {
-        LinkedHashMap<String, String> parameters = [
-                (ModuleIdentifier.canonicalName): "identifier",
-                (DependencyResolver.canonicalName): "dependencyResolver"
-        ]
-        String setToNulls = ["oldInstance", "oldModule"].collect { "this.${it}=null;\n" }.join()
-        return getConstructorStart(abstractFQN, parameters, setToNulls)
-    }
-
-    private static String getCopyFromOldConstructor(FullyQualifiedName abstractFQN) {
-        LinkedHashMap<String, String> parameters = [
-                (ModuleIdentifier.canonicalName): "identifier",
-                (DependencyResolver.canonicalName): "dependencyResolver",
-                (abstractFQN.typeName): "oldModule",
-                (AutoCloseable.canonicalName): "oldInstance"
-        ]
-        return getConstructorStart(abstractFQN, parameters, "")
-    }
-}
diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/gofactory/AbsModuleGeneratedObjectFactory.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/gofactory/AbsModuleGeneratedObjectFactory.java
new file mode 100644 (file)
index 0000000..aa06cb9
--- /dev/null
@@ -0,0 +1,417 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.config.yangjmxgenerator.plugin.gofactory;
+
+import static java.lang.String.format;
+
+import com.google.common.base.Joiner;
+import com.google.common.base.Optional;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import org.opendaylight.controller.config.api.DependencyResolver;
+import org.opendaylight.controller.config.api.ModuleIdentifier;
+import org.opendaylight.controller.config.api.annotations.Description;
+import org.opendaylight.controller.config.api.runtime.RootRuntimeBeanRegistrator;
+import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
+import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.AbstractModuleTemplate;
+import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.TemplateFactory;
+import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Annotation;
+import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.IdentityRefModuleField;
+import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Method;
+import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.ModuleField;
+import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.FullyQualifiedName;
+import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.GeneratedObject;
+import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.GeneratedObjectBuilder;
+import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.JavaFileInputBuilder;
+import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.TypeName;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class AbsModuleGeneratedObjectFactory {
+
+    public GeneratedObject toGeneratedObject(ModuleMXBeanEntry mbe, Optional<String> copyright) {
+        FullyQualifiedName abstractFQN = new FullyQualifiedName(mbe.getPackageName(), mbe.getAbstractModuleName());
+        Optional<String> classJavaDoc = Optional.fromNullable(mbe.getNullableDescription());
+        AbstractModuleTemplate abstractModuleTemplate = TemplateFactory.abstractModuleTemplateFromMbe(mbe);
+        Optional<String> header = abstractModuleTemplate.getHeaderString();
+
+        List<FullyQualifiedName> implementedInterfaces = new ArrayList<>();
+        for(String implemented: abstractModuleTemplate.getTypeDeclaration().getImplemented()) {
+            implementedInterfaces.add(FullyQualifiedName.fromString(implemented));
+        }
+        Optional<FullyQualifiedName> maybeRegistratorType;
+        if (abstractModuleTemplate.isRuntime()) {
+            maybeRegistratorType = Optional.of(FullyQualifiedName.fromString(abstractModuleTemplate.getRegistratorType()));
+        } else {
+            maybeRegistratorType = Optional.absent();
+        }
+
+        return toGeneratedObject(abstractFQN, copyright, header, classJavaDoc, implementedInterfaces,
+                abstractModuleTemplate.getModuleFields(), maybeRegistratorType, abstractModuleTemplate.getMethods(),
+                mbe.getYangModuleQName());
+    }
+
+    public GeneratedObject toGeneratedObject(FullyQualifiedName abstractFQN,
+                                             Optional<String> copyright,
+                                             Optional<String> header,
+                                             Optional<String> classJavaDoc,
+                                             List<FullyQualifiedName> implementedInterfaces,
+                                             List<ModuleField> moduleFields,
+                                             Optional<FullyQualifiedName> maybeRegistratorType,
+                                             List<? extends Method> methods,
+                                             QName yangModuleQName) {
+        JavaFileInputBuilder b = new JavaFileInputBuilder();
+
+        Annotation moduleQNameAnnotation = Annotation.createModuleQNameANnotation(yangModuleQName);
+        b.addClassAnnotation(moduleQNameAnnotation);
+
+        b.setFqn(abstractFQN);
+        b.setTypeName(TypeName.absClassType);
+
+        b.setCopyright(copyright);
+        b.setHeader(header);
+        b.setClassJavaDoc(classJavaDoc);
+        for(FullyQualifiedName implemented: implementedInterfaces) {
+            b.addImplementsFQN(implemented);
+        }
+        if (classJavaDoc.isPresent()) {
+            b.addClassAnnotation(format("@%s(value=\"%s\")", Description.class.getCanonicalName(), classJavaDoc.get()));
+        }
+
+        // add logger:
+        b.addToBody(getLogger(abstractFQN));
+
+        b.addToBody("//attributes start");
+        for(ModuleField moduleField: moduleFields) {
+            b.addToBody(moduleField.toString() +"\n");
+        }
+
+        b.addToBody("//attributes end");
+
+
+        b.addToBody(getCommonFields(abstractFQN));
+
+
+        b.addToBody(getNewConstructor(abstractFQN));
+        b.addToBody(getCopyFromOldConstructor(abstractFQN));
+
+        b.addToBody(getRuntimeRegistratorCode(maybeRegistratorType));
+        b.addToBody(getValidationMethods(moduleFields));
+
+        b.addToBody(getCachesOfResolvedDependencies(moduleFields));
+        b.addToBody(getCachesOfResolvedIdentityRefs(moduleFields));
+        b.addToBody(getGetInstance(moduleFields));
+        b.addToBody(getReuseLogic(moduleFields, abstractFQN));
+        b.addToBody(getEqualsAndHashCode(abstractFQN));
+
+        b.addToBody(getMethods(methods));
+
+        return new GeneratedObjectBuilder(b.build()).toGeneratedObject();
+    }
+
+    private static String getMethods(List<? extends Method>  methods) {
+        String result = "\n// getters and setters\n";
+        for(Method method: methods) {
+            result += method.toString()+"\n";
+        }
+        return result;
+    }
+
+    private static String getEqualsAndHashCode(FullyQualifiedName abstractFQN) {
+        return "\n"+
+            "@Override\n"+
+            "public boolean equals(Object o) {\n"+
+                "if (this == o) return true;\n"+
+                "if (o == null || getClass() != o.getClass()) return false;\n"+
+                format("%s that = (%1$s) o;\n", abstractFQN.getTypeName())+
+                "return identifier.equals(that.identifier);\n"+
+            "}\n"+
+            "\n"+
+            "@Override\n"+
+            "public int hashCode() {\n"+
+                "return identifier.hashCode();\n"+
+            "}\n";
+    }
+
+    private static String getReuseLogic(List<ModuleField> moduleFields, FullyQualifiedName abstractFQN) {
+        String result = "\n"+
+            format("public boolean canReuseInstance(%s oldModule){\n", abstractFQN.getTypeName())+
+                "// allow reusing of old instance if no parameters was changed\n"+
+                "return isSame(oldModule);\n"+
+            "}\n"+
+            "\n"+
+            format("public %s reuseInstance(%1$s oldInstance){\n", AutoCloseable.class.getCanonicalName())+
+                "// implement if instance reuse should be supported. Override canReuseInstance to change the criteria.\n"+
+                "return oldInstance;\n"+
+            "}\n";
+        // isSame method that detects changed fields
+        result += "\n"+
+            format("public boolean isSame(%s other) {\n", abstractFQN.getTypeName())+
+                "if (other == null) {\n"+
+                    "throw new IllegalArgumentException(\"Parameter 'other' is null\");\n"+
+                "}\n";
+        // loop through fields, do deep equals on each field
+
+        for (ModuleField moduleField : moduleFields) {
+            if (moduleField.isListOfDependencies()) {
+                result += format(
+                    "if (%1$sDependency.equals(other.%1$sDependency) == false) {\n"+
+                        "return false;\n"+
+                    "}\n"+
+                    "for (int idx = 0; idx < %1$sDependency.size(); idx++) {\n"+
+                        "if (%1$sDependency.get(idx) != other.%1$sDependency.get(idx)) {\n"+
+                            "return false;\n"+
+                        "}\n"+
+                    "}\n" ,moduleField.getName());
+            } else if (moduleField.isDependent()) {
+                result += format(
+                    "if (%sDependency != other.%1$sDependency) { // reference to dependency must be same\n"+
+                        "return false;\n"+
+                    "}\n",moduleField.getName());
+            } else {
+                result += format(
+                    "if (java.util.Objects.deepEquals(%s, other.%1$s) == false) {\n"+
+                        "return false;\n"+
+                    "}\n", moduleField.getName());
+            }
+        }
+        result += "\n"+
+                "return true;\n"+
+            "}\n";
+
+        return result;
+    }
+
+    private static String getGetInstance(List<ModuleField> moduleFields) {
+        String result = "\n"+
+            "@Override\n"+
+            format("public final %s getInstance() {\n", AutoCloseable.class.getCanonicalName())+
+                "if(instance==null) {\n";
+        // create instance start
+
+        // loop through dependent fields, use dependency resolver to instantiate dependencies. Do it in loop in case field represents list of dependencies.
+        Map<ModuleField, String> resolveDependenciesMap = new HashMap<>();
+        for(ModuleField moduleField: moduleFields) {
+            if (moduleField.isDependent()) {
+                String str;
+                String osgi = moduleField.getDependency().getSie().getExportedOsgiClassName();
+                if (moduleField.isList()) {
+                    str = format(
+                        "%sDependency = new java.util.ArrayList<%s>();\n"+
+                        "for(javax.management.ObjectName dep : %1$s) {\n"+
+                            "%1$sDependency.add(dependencyResolver.resolveInstance(%2$s.class, dep, %1$sJmxAttribute));\n"+
+                        "}\n", moduleField.getName(), osgi);
+                } else {
+                    str = format(
+                        "%1$sDependency = dependencyResolver.resolveInstance(%2$s.class, %1$s, %1$sJmxAttribute);",
+                        moduleField.getName(), osgi);
+                }
+                resolveDependenciesMap.put(moduleField, str);
+            }
+        }
+
+        // wrap each field resolvation statement with if !=null when dependency is not mandatory
+        for (Map.Entry<ModuleField, String> entry : resolveDependenciesMap.entrySet()) {
+            if (entry.getKey().getDependency().isMandatory() == false) {
+                result += format("if (%s!=null) {\n%s;\n}", entry.getKey().getName(), entry.getValue());
+            } else {
+                result += entry.getValue();
+            }
+        }
+
+        // add code to inject dependency resolver to fields that support it
+        for(ModuleField moduleField: moduleFields) {
+            if (moduleField.isNeedsDepResolver()) {
+                result += format("if (%s!=null){\n", moduleField.getName());
+                if (moduleField.isList()) {
+                    result += format(
+                        "for(%s candidate : %s) {\n"+
+                            "candidate.injectDependencyResolver(dependencyResolver);\n"+
+                        "}\n", moduleField.getGenericInnerType(), moduleField.getName());
+                } else {
+                    result += format("%s.injectDependencyResolver(dependencyResolver);\n", moduleField.getName());
+                }
+                result += "}\n";
+            }
+        }
+
+        // identity refs need to be injected with dependencyResolver and base class
+        for (ModuleField moduleField : moduleFields) {
+            if (moduleField.isIdentityRef()) {
+                result += format("if (%s!=null) {", moduleField.getName());
+                result += format("set%s(%s.resolveIdentity(dependencyResolver, %s.class));",
+                        moduleField.getAttributeName(), moduleField.getName(),
+                        ((IdentityRefModuleField)moduleField).getIdentityBaseClass());
+                result += "}\n";
+            }
+        }
+
+        // create instance end: reuse and recreate logic
+        result +=   "if(oldInstance!=null && canReuseInstance(oldModule)) {\n"+
+                        "instance = reuseInstance(oldInstance);\n"+
+                    "} else {\n"+
+                        "if(oldInstance!=null) {\n"+
+                           "try {\n"+
+                                "oldInstance.close();\n"+
+                            "} catch(Exception e) {\n"+
+                                "logger.error(\"An error occurred while closing old instance \" + oldInstance, e);\n"+
+                            "}\n"+
+                        "}\n"+
+                        "instance = createInstance();\n"+
+                        "if (instance == null) {\n"+
+                            "throw new IllegalStateException(\"Error in createInstance - null is not allowed as return value\");\n"+
+                        "}\n"+
+                    "}\n"+
+                "}\n"+
+                "return instance;\n"+
+            "}\n"+
+            format("public abstract %s createInstance();\n", AutoCloseable.class.getCanonicalName());
+
+        return result;
+    }
+
+    private static String getCommonFields(FullyQualifiedName abstractFQN) {
+        return "\n"+
+            format("private final %s oldModule;\n", abstractFQN.getTypeName())+
+            format("private final %s oldInstance;\n", AutoCloseable.class.getCanonicalName())+
+            format("private %s instance;\n", AutoCloseable.class.getCanonicalName())+
+            format("private final %s dependencyResolver;\n", DependencyResolver.class.getCanonicalName())+
+            format("private final %s identifier;\n", ModuleIdentifier.class.getCanonicalName())+
+            "@Override\n"+
+            format("public %s getIdentifier() {\n", ModuleIdentifier.class.getCanonicalName())+
+                "return identifier;\n"+
+            "}\n";
+    }
+
+    private static String getCachesOfResolvedIdentityRefs(List<ModuleField> moduleFields) {
+        StringBuilder result = new StringBuilder();
+        for (ModuleField moduleField : moduleFields) {
+            if (moduleField.isIdentityRef()) {
+                IdentityRefModuleField field = (IdentityRefModuleField) moduleField;
+                result.append(format("private %s %s;\n", field.getIdentityClassType(), field.getIdentityClassName()));
+            }
+        }
+        return result.toString();
+    }
+
+    private static String getCachesOfResolvedDependencies(List<ModuleField> moduleFields) {
+        StringBuilder result = new StringBuilder();
+        for (ModuleField moduleField: moduleFields) {
+            if (moduleField.isDependent()) {
+                String osgi = moduleField.getDependency().getSie().getExportedOsgiClassName();
+                if (moduleField.isList()) {
+                    result
+                            .append(format("private java.util.List<%s> %sDependency = new java.util.ArrayList<%s>();", osgi, moduleField.getName(), osgi))
+                            .append(format("protected final java.util.List<%s> get%sDependency(){\n", osgi, moduleField.getAttributeName()))
+                            .append(format("return %sDependency;\n", moduleField.getName()))
+                            .append("}\n");
+                } else {
+                    result.append(format(
+                    "private %s %sDependency;\n"+
+                    "protected final %s get%sDependency(){\n"+
+                        "return %sDependency;\n"+
+                    "}",
+                    osgi, moduleField.getName(), osgi, moduleField.getAttributeName(), moduleField.getName()));
+                }
+            }
+        }
+        return result.toString();
+    }
+
+    private static String getRuntimeRegistratorCode(Optional<FullyQualifiedName> maybeRegistratorType) {
+        if (maybeRegistratorType.isPresent()) {
+            String registratorType = maybeRegistratorType.get().toString();
+
+            return "\n"+
+                format("private %s rootRuntimeBeanRegistratorWrapper;\n", registratorType)+
+                "\n"+
+                format("public %s getRootRuntimeBeanRegistratorWrapper(){\n", registratorType)+
+                    "return rootRuntimeBeanRegistratorWrapper;\n"+
+                "}\n"+
+                "\n"+
+                "@Override\n"+
+                format("public void setRuntimeBeanRegistrator(%s rootRuntimeRegistrator){\n", RootRuntimeBeanRegistrator.class.getCanonicalName())+
+                    format("this.rootRuntimeBeanRegistratorWrapper = new %s(rootRuntimeRegistrator);\n", registratorType)+
+                "}\n";
+        } else {
+            return "";
+        }
+    }
+
+    private static String getValidationMethods(List<ModuleField> moduleFields) {
+        String result = "\n"+
+            "@Override\n"+
+            "public void validate() {\n";
+        // validate each mandatory dependency
+        for(ModuleField moduleField: moduleFields) {
+            if (moduleField.isDependent() && moduleField.getDependency().isMandatory()) {
+                if (moduleField.isList()) {
+                    result += "" +
+                            format("for(javax.management.ObjectName dep : %s) {\n", moduleField.getName()) +
+                            format("    dependencyResolver.validateDependency(%s.class, dep, %sJmxAttribute);\n",
+                                    moduleField.getDependency().getSie().getFullyQualifiedName(), moduleField.getName()) +
+                            "}\n";
+                } else {
+                    result += format("dependencyResolver.validateDependency(%s.class, %s, %sJmxAttribute);",
+                            moduleField.getDependency().getSie().getFullyQualifiedName(), moduleField.getName(), moduleField.getName());
+                }
+            }
+        }
+        result += "\n"+
+                "customValidation();\n"+
+            "}\n"+
+            "\n"+
+            "protected void customValidation() {\n"+
+            "}\n";
+        return result;
+    }
+
+    private static String getLogger(FullyQualifiedName fqn) {
+        return format("private static final %s logger = %s.getLogger(%s.class);",
+                Logger.class.getCanonicalName(), LoggerFactory.class.getCanonicalName(), fqn);
+    }
+
+    // assumes that each parameter name corresponds to an field in this class, constructs lines setting this.field = field;
+    private static String getConstructorStart(FullyQualifiedName fqn,
+                                              LinkedHashMap<String, String> parameters, String after) {
+        String paramString = Joiner.on(",").withKeyValueSeparator(" ").join(parameters);
+        String setters = "";
+        for (String paramName : parameters.values()) {
+            setters += format("this.%s = %1$s;\n", paramName);
+        }
+        return format("public %s(", fqn.getTypeName()) +
+                paramString +
+                ") {\n" +
+                setters +
+                after +
+                "}\n";
+    }
+
+    private static String getNewConstructor(FullyQualifiedName abstractFQN) {
+        LinkedHashMap<String, String> parameters = new LinkedHashMap<>();
+        parameters.put(ModuleIdentifier.class.getCanonicalName(), "identifier");
+        parameters.put(DependencyResolver.class.getCanonicalName(), "dependencyResolver");
+
+        String setToNulls = "this.oldInstance=null;\n;" +
+                "this.oldModule=null;\n";
+        return getConstructorStart(abstractFQN, parameters, setToNulls);
+    }
+
+    private static String getCopyFromOldConstructor(FullyQualifiedName abstractFQN) {
+        LinkedHashMap<String, String> parameters = new LinkedHashMap<>();
+        parameters.put(ModuleIdentifier.class.getCanonicalName(), "identifier");
+        parameters.put(DependencyResolver.class.getCanonicalName(), "dependencyResolver");
+        parameters.put(abstractFQN.getTypeName(), "oldModule");
+        parameters.put(AutoCloseable.class.getCanonicalName(), "oldInstance");
+        return getConstructorStart(abstractFQN, parameters, "");
+    }
+}
diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/gofactory/GenericGeneratedObjectFactory.groovy b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/gofactory/GenericGeneratedObjectFactory.groovy
deleted file mode 100644 (file)
index 6504aac..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.config.yangjmxgenerator.plugin.gofactory
-
-import com.google.common.base.Optional
-import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.FtlTemplate
-import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.FullyQualifiedName
-import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.GeneratedObject
-import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.GeneratedObjectBuilder
-import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.JavaFileInputBuilder
-
-public class GenericGeneratedObjectFactory {
-
-    public GeneratedObject toGeneratedObject(FtlTemplate template, Optional<String> copyright) {
-        JavaFileInputBuilder b = new JavaFileInputBuilder();
-        b.setHeader(template.headerString)
-        b.setFqn(new FullyQualifiedName(template.packageName, template.typeDeclaration.name))
-        b.setClassJavaDoc(template.maybeJavadoc)
-        template.annotations.each { b.addClassAnnotation(it) }
-        // type declaration
-        template.typeDeclaration.extended.each { b.addExtendsFQN(FullyQualifiedName.fromString(it)) }
-        template.typeDeclaration.implemented.each { b.addImplementsFQN(FullyQualifiedName.fromString(it)) }
-        b.setCopyright(copyright);
-        b.setTypeName(template.typeDeclaration.toTypeName())
-        // fields
-        template.fields.each { b.addToBody(it.toString()) }
-        // constructors
-        template.constructors.each { b.addToBody(it.toString()) }
-        // methods
-        template.methods.each { b.addToBody(it.toString()) }
-
-        return new GeneratedObjectBuilder(b.build()).toGeneratedObject();
-    }
-}
diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/gofactory/GenericGeneratedObjectFactory.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/gofactory/GenericGeneratedObjectFactory.java
new file mode 100644 (file)
index 0000000..11bb677
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.config.yangjmxgenerator.plugin.gofactory;
+
+import com.google.common.base.Optional;
+import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.FtlTemplate;
+import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Annotation;
+import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Constructor;
+import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Field;
+import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Method;
+import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.FullyQualifiedName;
+import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.GeneratedObject;
+import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.GeneratedObjectBuilder;
+import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.JavaFileInputBuilder;
+
+public class GenericGeneratedObjectFactory {
+
+    public GeneratedObject toGeneratedObject(FtlTemplate template, Optional<String> copyright) {
+        JavaFileInputBuilder b = new JavaFileInputBuilder();
+        b.setHeader(template.getHeaderString());
+        b.setFqn(new FullyQualifiedName(template.getPackageName(), template.getTypeDeclaration().getName()));
+        b.setClassJavaDoc(template.getMaybeJavadoc());
+        for (Annotation annotation : template.getAnnotations()) {
+            b.addClassAnnotation(annotation);
+        }
+        // type declaration
+        for (String extended : template.getTypeDeclaration().getExtended()) {
+            b.addExtendsFQN(FullyQualifiedName.fromString(extended));
+        }
+        for (String implemented : template.getTypeDeclaration().getImplemented()) {
+            b.addImplementsFQN(FullyQualifiedName.fromString(implemented));
+        }
+        b.setCopyright(copyright);
+        b.setTypeName(template.getTypeDeclaration().toTypeName());
+        // fields
+        for (Field field : template.getFields()) {
+            b.addToBody(field.toString());
+        }
+        // constructors
+        for (Constructor constructor : template.getConstructors()) {
+            b.addToBody(constructor.toString());
+        }
+        // methods
+        for (Method method : template.getMethods()) {
+            b.addToBody(method.toString());
+        }
+        return new GeneratedObjectBuilder(b.build()).toGeneratedObject();
+    }
+}
index f2a56f2b1bfbe2a1e1066a90f3ef16ba6afef660..7a20f22440a75dc97f45ed9575c1d9364f40c3fb 100644 (file)
@@ -44,22 +44,53 @@ public class ProcessSources extends AbstractMojo{
 
         File[] sourceFiles = sourceDirectory.listFiles();
         for (File sourceFile: sourceFiles) {
-            if(sourceFile.getName().endsWith("Module.java") || sourceFile.getName().endsWith("ModuleFactory.java")) {
-                File stubFile = new File(sourceFile.getPath().replace(".java", "Stub.txt"));
-                if (stubFile.exists()) {
-                    try {
-                        rewrite(sourceFile, FileUtils.readFileToString(stubFile));
-                    } catch (IOException e) {
-                        getLog().error("Error while reading/writing to files.", e);
+            if (sourceFile.getName().endsWith(".java")) {
+                String sourceContent;
+                try {
+                    sourceContent = FileUtils.readFileToString(sourceFile);
+                } catch (IOException e) {
+                    getLog().error("Cannot read " + sourceFile.getAbsolutePath(), e);
+                    continue;
+                }
+                if (sourceFile.getName().endsWith("Module.java") || sourceFile.getName().endsWith("ModuleFactory.java")) {
+                    File stubFile = new File(sourceFile.getPath().replace(".java", "Stub.txt"));
+                    if (stubFile.exists()) {
+                        String stubContent = null;
+                        try {
+                            stubContent = FileUtils.readFileToString(stubFile);
+                        } catch (IOException e) {
+                            getLog().error("Cannot read " + stubFile.getAbsolutePath(), e);
+                        }
+                        if (stubContent != null) {
+                            sourceContent = rewriteStub(sourceContent, stubContent);
+                        }
                     }
                 }
+                // remove copyright headers as they can contain timestamp
+                sourceContent = removeCopyrights(sourceContent);
+
+                // replace the file content
+                try {
+                    FileUtils.write(sourceFile, sourceContent);
+                } catch (IOException e) {
+                    getLog().error("Cannot write " + sourceFile.getAbsolutePath(), e);
+                }
             }
+
         }
     }
 
-    private static void rewrite(File sourceFile, String replaceTODOWith) throws IOException {
-        String source = FileUtils.readFileToString(sourceFile);
-        String target = Pattern.compile("^.*TODO.*\n.*throw new java.lang.UnsupportedOperationException.*$", Pattern.MULTILINE).matcher(source).replaceFirst(replaceTODOWith);
-        FileUtils.write(sourceFile, target);
+    private static Pattern MULTILINE_COMMENT_PATTERN = Pattern.compile("/\\*.*\\*/", Pattern.MULTILINE | Pattern.DOTALL);
+    private static String removeCopyrights(String source) {
+        String target = MULTILINE_COMMENT_PATTERN.matcher(source).replaceAll("\n");
+        //FileUtils.write(sourceFile, target);
+        return target;
+    }
+
+    private static Pattern UNSUPPORTED_OP_PATTERN = Pattern.compile("^.*TODO.*\n.*throw new java.lang.UnsupportedOperationException.*$", Pattern.MULTILINE);
+
+    private static String rewriteStub(String source, String replaceTODOWith) {
+        String target = UNSUPPORTED_OP_PATTERN.matcher(source).replaceFirst(replaceTODOWith);
+        return target;
     }
 }
index 07d7438a00b9758ccd28ee10b70f2059b37f77a8..78ac362e594e393b2a9128cce895d3e4d2c9f4e7 100644 (file)
@@ -1,10 +1,5 @@
-/*
-* Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
-*
-* This program and the accompanying materials are made available under the
-* terms of the Eclipse Public License v1.0 which accompanies this distribution,
-* and is available at http://www.eclipse.org/legal/epl-v10.html
-*/
+
+
 package org.opendaylight.controller.config.yang.test.impl;
 public class DepTestImplModule extends org.opendaylight.controller.config.yang.test.impl.AbstractDepTestImplModule {
     public DepTestImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
index 330f804e0eae6caa252ec5de740a87cffa2f5078..026dd9aca28b873c2268d0f269dab5702dca1bba 100644 (file)
@@ -1,19 +1,5 @@
-/*
-* 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
-*/
-/*
-* Generated file
-*
-* Generated from: yang module name: config-test-impl yang module local name: impl-dep
-* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
-* Generated at: Fri Apr 25 09:12:08 CEST 2014
-*
-* Do not modify this file unless it is present under src/main directory
-*/
+
+
 package org.opendaylight.controller.config.yang.test.impl;
 public class DepTestImplModuleFactory extends org.opendaylight.controller.config.yang.test.impl.AbstractDepTestImplModuleFactory {
 
index a5b7f55df382b4b403404f168a32bfd04c8a1976..ddf72f39b4da73d529ddac371b9fc64cd9158a0f 100644 (file)
@@ -1,10 +1,5 @@
-/*
-* Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
-*
-* This program and the accompanying materials are made available under the
-* terms of the Eclipse Public License v1.0 which accompanies this distribution,
-* and is available at http://www.eclipse.org/legal/epl-v10.html
-*/
+
+
 package org.opendaylight.controller.config.yang.test.impl;
 public class IdentityTestModule extends org.opendaylight.controller.config.yang.test.impl.AbstractIdentityTestModule {
     public IdentityTestModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
index b57d1dc1d4347b0ff4cf436a8c2149c3ca2e974d..3a4348d376f8841d1dbc3c9f17ef391214588f82 100644 (file)
@@ -1,19 +1,5 @@
-/*
-* 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
-*/
-/*
-* Generated file
-*
-* Generated from: yang module name: config-test-impl yang module local name: impl-identity-test
-* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
-* Generated at: Fri Apr 25 09:12:08 CEST 2014
-*
-* Do not modify this file unless it is present under src/main directory
-*/
+
+
 package org.opendaylight.controller.config.yang.test.impl;
 public class IdentityTestModuleFactory extends org.opendaylight.controller.config.yang.test.impl.AbstractIdentityTestModuleFactory {
 
index ecbf4aba33c436b9354f4c4abe0a674de258745c..943fe3b0d7709cc979a84c54ed6c7df8c24d3fc8 100644 (file)
@@ -1,10 +1,5 @@
-/*
-* Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
-*
-* This program and the accompanying materials are made available under the
-* terms of the Eclipse Public License v1.0 which accompanies this distribution,
-* and is available at http://www.eclipse.org/legal/epl-v10.html
-*/
+
+
 package org.opendaylight.controller.config.yang.test.impl;
 public class NetconfTestImplModule extends org.opendaylight.controller.config.yang.test.impl.AbstractNetconfTestImplModule {
     public NetconfTestImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
index 74a05496df7e7f31c3c78cda03b3e813cfaefdfa..587089b10f488d9f9c03090469cb00f6d9b0a865 100644 (file)
@@ -1,19 +1,5 @@
-/*
-* 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
-*/
-/*
-* Generated file
-*
-* Generated from: yang module name: config-test-impl yang module local name: impl-netconf
-* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
-* Generated at: Fri Apr 25 09:12:08 CEST 2014
-*
-* Do not modify this file unless it is present under src/main directory
-*/
+
+
 package org.opendaylight.controller.config.yang.test.impl;
 public class NetconfTestImplModuleFactory extends org.opendaylight.controller.config.yang.test.impl.AbstractNetconfTestImplModuleFactory {
 
index 4de980433753e4165f66dec8fe2eb7081073ddd5..1d5cda036f8a05867b94d04e947c0c0ddec4a88f 100644 (file)
@@ -1,10 +1,5 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
+
+
 package org.opendaylight.controller.config.yang.test.impl;
 
 import com.google.common.collect.Lists;
index 9132407356e8b4c52ab23610079d1d189e029c8b..7b049e7b578e9ae8d94bd85a7e4a18a842a520ca 100644 (file)
@@ -1,10 +1,5 @@
-/*
-* Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
-*
-* This program and the accompanying materials are made available under the
-* terms of the Eclipse Public License v1.0 which accompanies this distribution,
-* and is available at http://www.eclipse.org/legal/epl-v10.html
-*/
+
+
 package org.opendaylight.controller.config.yang.test.impl;
 public class TestImplModule extends org.opendaylight.controller.config.yang.test.impl.AbstractTestImplModule {
     public TestImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
index 9680bffd6b42d0391d637f52109f172206918aad..de9ac2fef3ad363e8952384b526be688ab5b6dbc 100644 (file)
@@ -1,19 +1,5 @@
-/*
-* 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
-*/
-/*
-* Generated file
-*
-* Generated from: yang module name: config-test-impl yang module local name: impl
-* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
-* Generated at: Fri Apr 25 09:12:08 CEST 2014
-*
-* Do not modify this file unless it is present under src/main directory
-*/
+
+
 package org.opendaylight.controller.config.yang.test.impl;
 public class TestImplModuleFactory extends org.opendaylight.controller.config.yang.test.impl.AbstractTestImplModuleFactory {
 
index 281c1aade55db8972553f578595d89e3128d5d46..13a31f59766c7e4ecb1936aa8ca64c3d7c8b85ee 100644 (file)
@@ -48,7 +48,7 @@ public class NetconfTestImplModuleTest  extends AbstractConfigTest {
     public void setUp() {
 
         factory = new NetconfTestImplModuleFactory();
-        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory,
+        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,factory,
                 new DepTestImplModuleFactory(), new IdentityTestModuleFactory()));
     }
 
index 9d0d6c1888a480aa96042fc2c7824aaf41b5ecbf..234e0feb45047ed2ca14e45e2b2e1dd18432834e 100644 (file)
@@ -22,6 +22,8 @@ netconf.tcp.client.port=8383
 netconf.ssh.address=0.0.0.0
 netconf.ssh.port=1830
 netconf.ssh.pk.path = ./configuration/RSA.pk
+netconf.ssh.default.user = netconf
+netconf.ssh.default.password = netconf
 
 
 netconf.config.persister.active=1,2
index 619ab06d8d3c3da7ca181949b4fff7ddd7596e6e..d872bfd47b229c4047d0bcfb05e98034474e93d3 100644 (file)
                     <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:schema-service-singleton</type>
                     <name>yang-schema-service</name>
                 </module>
-                <!-- To enable use of new in-memory datastore and new implementations
-                     of data brokers, comment out all parts of this
-                     xml which are marked with DATA-BROKER and uncomment all parts
-                     of this xml which are marked with NEW-DATA-BROKER
-                -->
-                <!-- DATA-BROKER start-->
-                <module>
-                    <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:hash-map-data-store</type>
-                    <name>hash-map-data-store</name>
-                </module>
-                <!-- DATA BROKER end -->
-                <!-- NEW-DATA-BROKER start -->
-                <!--
                 <module>
-                    <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:dom-inmemory-data-broker</type>
-                    <name>async-data-broker</name>
-                    <schema-service>
-                        <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:schema-service</type>
-                        <name>yang-schema-service</name>
-                    </schema-service>
+                    <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:runtime-generated-mapping</type>
+                    <name>runtime-mapping-singleton</name>
                 </module>
-                -->
-                <!-- NEW-DATA-BROKER end -->
                 <module>
-                    <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:dom-broker-impl</type>
-                    <name>dom-broker</name>
-                    <!-- DATA-BROKER start -->
-                    <data-store xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">
-                        <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-data-store</type>
-                        <!-- to switch to the clustered data store, comment out the hash-map-data-store <name> and uncomment the cluster-data-store one -->
-                        <name>hash-map-data-store</name>
-                        <!-- <name>cluster-data-store</name> -->
-                    </data-store>
-                    <!-- DATA-BROKER end -->
-                    <!-- NEW-DATA-BROKER start -->
-                    <!--
-                    <async-data-broker>
-                        <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-async-data-broker</type>
-                        <name>async-data-broker</name>
-                    </async-data-broker>
-                    -->
-                    <!-- NEW-DATA-BROKER end -->
+                    <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-notification-broker</type>
+                    <name>binding-notification-broker</name>
                 </module>
                 <module>
                     <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-broker-impl</type>
                         <name>binding-data-broker</name>
                     </data-broker>
                 </module>
+
+                <!--
+                     Tree-based in-memory data store. This is the data store which is currently
+                     recommended for single-node deployments.
+                -->
                 <module>
-                    <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:runtime-generated-mapping</type>
-                    <name>runtime-mapping-singleton</name>
-                </module>
-                <module>
-                    <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-notification-broker</type>
-                    <name>binding-notification-broker</name>
+                    <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:dom-inmemory-data-broker</type>
+                    <name>inmemory-data-broker</name>
+                    <schema-service>
+                        <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:schema-service</type>
+                        <name>yang-schema-service</name>
+                    </schema-service>
                 </module>
-                <!-- DATA-BROKER start -->
                 <module>
-                    <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-data-broker</type>
-                    <name>binding-data-broker</name>
-                    <dom-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
-                        <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-broker-osgi-registry</type>
-                        <name>dom-broker</name>
-                    </dom-broker>
-                    <mapping-service xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
-                        <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">binding:binding-dom-mapping-service</type>
-                        <name>runtime-mapping-singleton</name>
-                    </mapping-service>
+                    <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:dom-broker-impl</type>
+                    <name>inmemory-dom-broker</name>
+                    <async-data-broker>
+                        <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-async-data-broker</type>
+                        <name>inmemory-data-broker</name>
+                    </async-data-broker>
                 </module>
-                <!-- DATA-BROKER end -->
-                <!-- NEW-DATA-BROKER start -->
-                <!--
                 <module>
                     <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-data-compatible-broker</type>
-                    <name>binding-data-broker</name>
+                    <name>inmemory-binding-data-broker</name>
                     <dom-async-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
                         <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-broker-osgi-registry</type>
                         <name>dom-broker</name>
                         <name>runtime-mapping-singleton</name>
                     </binding-mapping-service>
                 </module>
-                -->
-                <!-- NEW-DATA-BROKER end -->
             </modules>
             <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
-                <service>
-                    <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:schema-service</type>
-                    <instance>
-                        <name>yang-schema-service</name>
-                        <provider>/modules/module[type='schema-service-singleton'][name='yang-schema-service']</provider>
-                    </instance>
-                </service>
-                <service>
-                    <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-notification-service</type>
-                    <instance>
-                        <name>binding-notification-broker</name>
-                        <provider>/modules/module[type='binding-notification-broker'][name='binding-notification-broker']</provider>
-                    </instance>
-                </service>
-                <!-- DATA-BROKER start -->
-                <service>
-                    <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-data-store</type>
-                    <instance>
-                        <name>hash-map-data-store</name>
-                        <provider>/modules/module[type='hash-map-data-store'][name='hash-map-data-store']</provider>
-                    </instance>
-                </service>
-                <!-- DATA-BROKER end -->
-                <!-- NEW-DATA-BROKER start -->
-                <!--
-                <service>
-                    <type  xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-async-data-broker</type>
-                    <instance>
-                        <name>async-data-broker</name>
-                        <provider>/modules/module[type='dom-inmemory-data-broker'][name='async-data-broker']</provider>
-                    </instance>
-                </service>
-                -->
-                <!-- NEW-DATA-BROKER end -->
-                <service>
-                    <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-broker-osgi-registry</type>
-                    <instance>
-                        <name>binding-osgi-broker</name>
-                        <provider>/modules/module[type='binding-broker-impl'][name='binding-broker-impl']</provider>
-                    </instance>
-                </service>
-                <service>
-                    <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-rpc-registry</type>
-                    <instance>
-                        <name>binding-rpc-broker</name>
-                        <provider>/modules/module[type='binding-broker-impl'][name='binding-broker-impl']</provider>
-                    </instance>
-                </service>
-                <service>
-                    <type xmlns:binding-impl="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">binding-impl:binding-dom-mapping-service</type>
-                    <instance>
-                        <name>runtime-mapping-singleton</name>
-                        <provider>/modules/module[type='runtime-generated-mapping'][name='runtime-mapping-singleton']</provider>
-                    </instance>
-                </service>
-                <service>
-                <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-broker-osgi-registry</type>
-                    <instance>
-                        <name>dom-broker</name>
-                        <provider>/modules/module[type='dom-broker-impl'][name='dom-broker']</provider>
-                    </instance>
-                </service>
+                    <service>
+                        <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:schema-service</type>
+                        <instance>
+                            <name>yang-schema-service</name>
+                            <provider>/modules/module[type='schema-service-singleton'][name='yang-schema-service']</provider>
+                        </instance>
+                    </service>
+                    <service>
+                        <type xmlns:binding-impl="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">binding-impl:binding-dom-mapping-service</type>
+                        <instance>
+                            <name>runtime-mapping-singleton</name>
+                            <provider>/modules/module[type='runtime-generated-mapping'][name='runtime-mapping-singleton']</provider>
+                        </instance>
+                    </service>
+                    <service>
+                        <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-notification-service</type>
+                        <instance>
+                            <name>binding-notification-broker</name>
+                            <provider>/modules/module[type='binding-notification-broker'][name='binding-notification-broker']</provider>
+                        </instance>
+                    </service>
+                    <service>
+                        <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-broker-osgi-registry</type>
+                        <instance>
+                            <name>binding-osgi-broker</name>
+                            <provider>/modules/module[type='binding-broker-impl'][name='binding-broker-impl']</provider>
+                        </instance>
+                    </service>
+                    <service>
+                        <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-rpc-registry</type>
+                        <instance>
+                            <name>binding-rpc-broker</name>
+                            <provider>/modules/module[type='binding-broker-impl'][name='binding-broker-impl']</provider>
+                        </instance>
+                    </service>
 
-                <service>
-                    <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-data-broker</type>
-                    <instance>
-                        <name>binding-data-broker</name>
-                        <!--  DATA-BROKER start -->
-                        <provider>/modules/module[type='binding-data-broker'][name='binding-data-broker']</provider>
-                        <!--  DATA-BROKER end -->
-                        <!-- NEW-DATA-BROKER start -->
-                        <!--
-                        <provider>/modules/module[type='binding-data-compatible-broker'][name='binding-data-broker']</provider>
-                        -->
-                        <!--  NEW-DATA-BROKER end -->
-                    </instance>
-                </service>
+                    <service>
+                        <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-broker-osgi-registry</type>
+                        <instance>
+                            <name>dom-broker</name>
+                            <provider>/modules/module[type='dom-broker-impl'][name='inmemory-dom-broker']</provider>
+                        </instance>
+                    </service>
 
+                    <service>
+                        <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-data-broker</type>
+                        <instance>
+                            <name>binding-data-broker</name>
+                            <provider>/modules/module[type='binding-data-compatible-broker'][name='inmemory-binding-data-broker']</provider>
+                        </instance>
+                    </service>
+
+                    <service>
+                        <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-async-data-broker</type>
+                        <instance>
+                            <name>inmemory-data-broker</name>
+                            <provider>/modules/module[type='dom-inmemory-data-broker'][name='inmemory-data-broker']</provider>
+                        </instance>
+                    </service>
             </services>
         </data>
     </configuration>
index 919a53c3643c406fbe8cfabfc595adfff950f204..9bd63d3c3bb5268d8d6e5142dd38da888a90b906 100644 (file)
           </instructions>
         </configuration>
       </plugin>
-      <plugin>
-        <groupId>org.eclipse.xtend</groupId>
-        <artifactId>xtend-maven-plugin</artifactId>
-      </plugin>
     </plugins>
   </build>
 
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/AbstractChangeListener.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/AbstractChangeListener.java
new file mode 100644 (file)
index 0000000..426f4ba
--- /dev/null
@@ -0,0 +1,94 @@
+/**
+ * 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.frm;
+
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.Map.Entry;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
+import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * 
+ * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
+ *
+ */
+public abstract class AbstractChangeListener implements DataChangeListener {
+
+    private final AtomicLong txNum = new AtomicLong();
+    private String transactionId;
+
+    @Override
+    public void onDataChanged(DataChangeEvent<InstanceIdentifier<?>, DataObject> changeEvent) {
+        this.transactionId = this.newTransactionIdentifier().toString();
+
+        final Set<Entry<InstanceIdentifier<? extends DataObject>, DataObject>> createdEntries = 
+                changeEvent.getCreatedConfigurationData().entrySet();
+        final Set<Entry<InstanceIdentifier<? extends DataObject>, DataObject>> updatedEntries = 
+                new HashSet<Entry<InstanceIdentifier<? extends DataObject>, DataObject>>();
+
+        Set<Entry<InstanceIdentifier<? extends DataObject>, DataObject>> updateConfigEntrySet = 
+                changeEvent.getUpdatedConfigurationData().entrySet();
+        updatedEntries.addAll(updateConfigEntrySet);
+        updatedEntries.removeAll(createdEntries);
+
+        final Set<InstanceIdentifier<? extends DataObject>> removeEntriesInstanceIdentifiers = 
+                changeEvent.getRemovedConfigurationData();
+
+        for (final Entry<InstanceIdentifier<? extends DataObject>, DataObject> createdEntry : createdEntries) {
+            InstanceIdentifier<? extends DataObject> c_key = createdEntry.getKey();
+            DataObject c_value = createdEntry.getValue();
+            this.add(c_key, c_value);
+        }
+
+        for (final Entry<InstanceIdentifier<?>, DataObject> updatedEntrie : updatedEntries) {
+            Map<InstanceIdentifier<? extends DataObject>, DataObject> origConfigData = 
+                    changeEvent.getOriginalConfigurationData();
+
+            InstanceIdentifier<? extends Object> u_key = updatedEntrie.getKey();
+            final DataObject originalFlow = origConfigData.get(u_key);
+            final DataObject updatedFlow = updatedEntrie.getValue();
+            this.update(u_key, originalFlow, updatedFlow);
+        }
+
+        for (final InstanceIdentifier<?> instanceId : removeEntriesInstanceIdentifiers) {
+            Map<InstanceIdentifier<? extends DataObject>, DataObject> origConfigData = 
+                    changeEvent.getOriginalConfigurationData();
+
+            final DataObject removeValue = origConfigData.get(instanceId);
+            this.remove(instanceId, removeValue);
+        }
+    }
+
+    public String getTransactionId() {
+        return this.transactionId;
+    }
+
+    private Object newTransactionIdentifier() {
+        return "DOM-" + txNum.getAndIncrement();
+    }
+
+    protected abstract void validate() throws IllegalStateException;
+
+    protected abstract void remove(
+            final InstanceIdentifier<? extends DataObject> identifier,
+            final DataObject remove);
+
+    protected abstract void update(
+            final InstanceIdentifier<? extends DataObject> identifier,
+            final DataObject original, final DataObject update);
+
+    protected abstract void add(
+            final InstanceIdentifier<? extends DataObject> identifier,
+            final DataObject add);
+}
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/AbstractTransaction.xtend b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/AbstractTransaction.xtend
deleted file mode 100644 (file)
index cb1e90d..0000000
+++ /dev/null
@@ -1,106 +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.frm
-
-import java.util.Collections
-import java.util.HashSet
-import java.util.Map.Entry
-import java.util.Set
-import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction
-import org.opendaylight.controller.md.sal.common.api.data.DataModification
-import org.opendaylight.controller.sal.common.util.Rpcs
-import org.opendaylight.yangtools.yang.binding.DataObject
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-import org.opendaylight.yangtools.yang.common.RpcError
-
-abstract class AbstractTransaction implements DataCommitTransaction<InstanceIdentifier<?extends DataObject>, DataObject> {
-        
-    @Property
-    val DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification;
-    
-    new(DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification) {
-        _modification = modification;
-    }
-    
-    def void validate() throws IllegalStateException
-    
-    override finish() throws IllegalStateException {
-        validate()
-        callRpcs();
-        return Rpcs.getRpcResult(true, null, Collections.<RpcError>emptySet());     
-    }
-    
-    override getModification() {
-        return _modification;
-    }
-    
-    override rollback() throws IllegalStateException {
-        rollbackRpcs();
-        return Rpcs.getRpcResult(true, null, Collections.<RpcError>emptySet());
-    }
-    
-    def private callRpcs() {
-        val Set<Entry<InstanceIdentifier<? extends DataObject>, DataObject>> createdEntries = _modification.getCreatedConfigurationData().entrySet();
-
-        /*
-         * This little dance is because updatedEntries contains both created and modified entries
-         * The reason I created a new HashSet is because the collections we are returned are immutable.
-         */
-        val Set<Entry<InstanceIdentifier<? extends DataObject>, DataObject>> updatedEntries = new HashSet<Entry<InstanceIdentifier<? extends DataObject>, DataObject>>();
-        updatedEntries.addAll(_modification.getUpdatedConfigurationData().entrySet());
-        updatedEntries.removeAll(createdEntries);
-
-        val Set<InstanceIdentifier<? extends DataObject>> removeEntriesInstanceIdentifiers = _modification.getRemovedConfigurationData();
-        for (Entry<InstanceIdentifier<? extends DataObject >, DataObject> entry : createdEntries) {
-            add(entry.key,entry.value);
-        }
-        for (Entry<InstanceIdentifier<?>, DataObject> entry : updatedEntries) {
-                val originalFlow = _modification.originalConfigurationData.get(entry.key);
-                val updatedFlow = entry.value
-                update(entry.key, originalFlow ,updatedFlow);
-        }
-
-        for (InstanceIdentifier<?> instanceId : removeEntriesInstanceIdentifiers ) {
-            val removeValue = _modification.getOriginalConfigurationData.get(instanceId);
-                remove(instanceId,removeValue);
-        }
-    }
-    
-    def void remove(InstanceIdentifier<?> identifier, DataObject remove)
-    
-    def void update(InstanceIdentifier<?> identifier, DataObject original, DataObject update)
-    
-    def void add(InstanceIdentifier<?> identifier, DataObject add)
-    
-    def private rollbackRpcs() {
-        val Set<Entry<InstanceIdentifier<? extends DataObject>, DataObject>> createdEntries = _modification.getCreatedConfigurationData().entrySet();
-
-        /*
-         * This little dance is because updatedEntries contains both created and modified entries
-         * The reason I created a new HashSet is because the collections we are returned are immutable.
-         */
-        val Set<Entry<InstanceIdentifier<? extends DataObject>, DataObject>> updatedEntries = new HashSet<Entry<InstanceIdentifier<? extends DataObject>, DataObject>>();
-        updatedEntries.addAll(_modification.getUpdatedConfigurationData().entrySet());
-        updatedEntries.removeAll(createdEntries);
-
-        val Set<InstanceIdentifier<? >> removeEntriesInstanceIdentifiers = _modification.getRemovedConfigurationData();
-        for (Entry<InstanceIdentifier<?>, DataObject> entry : createdEntries) {
-            remove(entry.key,entry.value); // because we are rolling back, remove what we would have added.            
-        }
-        for (Entry<InstanceIdentifier<?>, DataObject> entry : updatedEntries) {
-            val originalFlow = _modification.originalConfigurationData.get(entry.key);
-            val updatedFlow = entry.value
-            update(entry.key, updatedFlow ,originalFlow);// because we are rolling back, replace the updated with the original
-        }
-
-        for (InstanceIdentifier<?> instanceId : removeEntriesInstanceIdentifiers ) {
-            val removeValue = _modification.getOriginalConfigurationData.get(instanceId);
-            add(instanceId,removeValue);// because we are rolling back, add what we would have removed.
-        }
-    }    
-}
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/FRMActivator.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/FRMActivator.java
new file mode 100644 (file)
index 0000000..929c489
--- /dev/null
@@ -0,0 +1,61 @@
+/**
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.frm;
+
+import org.opendaylight.controller.frm.flow.FlowProvider;
+import org.opendaylight.controller.frm.group.GroupProvider;
+import org.opendaylight.controller.frm.meter.MeterProvider;
+import org.opendaylight.controller.sal.binding.api.AbstractBindingAwareProvider;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.SalGroupService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.SalMeterService;
+import org.osgi.framework.BundleContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class FRMActivator extends AbstractBindingAwareProvider {
+
+    private final static Logger LOG = LoggerFactory.getLogger(FRMActivator.class);
+
+    private static FlowProvider flowProvider = new FlowProvider(); 
+    private static GroupProvider groupProvider = new GroupProvider();
+    private static MeterProvider meterProvider = new MeterProvider();
+    
+    @Override
+    public void onSessionInitiated(final ProviderContext session) {
+        DataProviderService flowSalService = session.<DataProviderService>getSALService(DataProviderService.class);
+        FRMActivator.flowProvider.setDataService(flowSalService);
+        SalFlowService rpcFlowSalService = session.<SalFlowService>getRpcService(SalFlowService.class);
+        FRMActivator.flowProvider.setSalFlowService(rpcFlowSalService);
+        FRMActivator.flowProvider.start();
+        DataProviderService groupSalService = session.<DataProviderService>getSALService(DataProviderService.class);
+        FRMActivator.groupProvider.setDataService(groupSalService);
+        SalGroupService rpcGroupSalService = session.<SalGroupService>getRpcService(SalGroupService.class);
+        FRMActivator.groupProvider.setSalGroupService(rpcGroupSalService);
+        FRMActivator.groupProvider.start();
+        DataProviderService meterSalService = session.<DataProviderService>getSALService(DataProviderService.class);
+        FRMActivator.meterProvider.setDataService(meterSalService);
+        SalMeterService rpcMeterSalService = session.<SalMeterService>getRpcService(SalMeterService.class);
+        FRMActivator.meterProvider.setSalMeterService(rpcMeterSalService);
+        FRMActivator.meterProvider.start();
+    }
+    
+    @Override
+    protected void stopImpl(final BundleContext context) {
+        try {
+            FRMActivator.flowProvider.close();
+            FRMActivator.groupProvider.close();
+            FRMActivator.meterProvider.close();
+        } catch (Throwable e) {
+            LOG.error("Unexpected error by stopping FRMActivator", e);
+            throw new RuntimeException(e);
+        }
+    }
+  }
\ No newline at end of file
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/FRMActivator.xtend b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/FRMActivator.xtend
deleted file mode 100644 (file)
index 8ec9d79..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- * 
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.frm
-
-import org.opendaylight.controller.frm.flow.FlowProvider
-import org.opendaylight.controller.frm.group.GroupProvider
-import org.opendaylight.controller.frm.meter.MeterProvider
-import org.opendaylight.controller.sal.binding.api.AbstractBindingAwareProvider
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.SalGroupService
-import org.osgi.framework.BundleContext
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.SalMeterService
-
-class FRMActivator extends AbstractBindingAwareProvider {
-
-    static var FlowProvider provider = new FlowProvider();
-    static var GroupProvider groupProvider = new GroupProvider();
-    static var MeterProvider meterProvider = new MeterProvider();
-
-    override onSessionInitiated(ProviderContext session) {
-        provider.dataService = session.getSALService(DataProviderService)
-        provider.salFlowService = session.getRpcService(SalFlowService);
-        provider.start();
-        
-        groupProvider.dataService = session.getSALService(DataProviderService)
-        groupProvider.salGroupService = session.getRpcService(SalGroupService)
-        groupProvider.start();
-        
-        meterProvider.dataService = session.getSALService(DataProviderService)
-        meterProvider.salMeterService = session.getRpcService(SalMeterService)
-        meterProvider.start();
-    }
-
-    override protected stopImpl(BundleContext context) {
-        provider.close();
-        groupProvider.close();
-        meterProvider.close();
-    }
-
-}
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowChangeListener.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowChangeListener.java
new file mode 100644 (file)
index 0000000..df086c7
--- /dev/null
@@ -0,0 +1,120 @@
+/**
+ * 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.frm.flow;
+
+import org.opendaylight.controller.frm.AbstractChangeListener;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowTableRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.OriginalFlow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.OriginalFlowBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.UpdatedFlow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.UpdatedFlowBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * 
+ * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
+ *
+ */
+public class FlowChangeListener extends AbstractChangeListener {
+
+    private final static Logger LOG = LoggerFactory.getLogger(FlowChangeListener.class);
+
+    private final SalFlowService salFlowService;
+
+    public SalFlowService getSalFlowService() {
+        return this.salFlowService;
+    }
+    
+    public FlowChangeListener(final SalFlowService manager) {
+        this.salFlowService = manager;
+    }
+
+    @Override
+    protected void validate() throws IllegalStateException {
+        FlowTransactionValidator.validate(this);
+    }
+
+    @Override
+    protected void remove(InstanceIdentifier<? extends DataObject> identifier, DataObject removeDataObj) {
+        if ((removeDataObj instanceof Flow)) {
+            
+            final Flow flow = ((Flow) removeDataObj);
+            final InstanceIdentifier<Table> tableInstanceId = identifier.<Table> firstIdentifierOf(Table.class);
+            final InstanceIdentifier<Node> nodeInstanceId = identifier.<Node> firstIdentifierOf(Node.class);
+            final RemoveFlowInputBuilder builder = new RemoveFlowInputBuilder(flow);
+            
+            builder.setFlowRef(new FlowRef(identifier));
+            builder.setNode(new NodeRef(nodeInstanceId));
+            builder.setFlowTable(new FlowTableRef(tableInstanceId));
+            
+            Uri uri = new Uri(this.getTransactionId());
+            builder.setTransactionUri(uri);
+            this.salFlowService.removeFlow((RemoveFlowInput) builder.build());
+            LOG.debug("Transaction {} - Removed Flow has removed flow: {}", new Object[]{uri, removeDataObj});
+        }
+    }
+
+    @Override
+    protected void update(InstanceIdentifier<? extends DataObject> identifier, DataObject original, DataObject update) {
+        if (original instanceof Flow && update instanceof Flow) {
+            
+            final Flow originalFlow = ((Flow) original);
+            final Flow updatedFlow = ((Flow) update);
+            final InstanceIdentifier<Node> nodeInstanceId = identifier.<Node>firstIdentifierOf(Node.class);
+            final UpdateFlowInputBuilder builder = new UpdateFlowInputBuilder();
+            
+            builder.setNode(new NodeRef(nodeInstanceId));
+            builder.setFlowRef(new FlowRef(identifier));
+            
+            Uri uri = new Uri(this.getTransactionId());
+            builder.setTransactionUri(uri);
+            
+            builder.setUpdatedFlow((UpdatedFlow) (new UpdatedFlowBuilder(updatedFlow)).build());
+            builder.setOriginalFlow((OriginalFlow) (new OriginalFlowBuilder(originalFlow)).build());
+            
+            this.salFlowService.updateFlow((UpdateFlowInput) builder.build());
+            LOG.debug("Transaction {} - Update Flow has updated flow {} with {}", new Object[]{uri, original, update});
+      }
+    }
+
+    @Override
+    protected void add(InstanceIdentifier<? extends DataObject> identifier, DataObject addDataObj) {
+        if ((addDataObj instanceof Flow)) {
+            
+            final Flow flow = ((Flow) addDataObj);
+            final InstanceIdentifier<Table> tableInstanceId = identifier.<Table> firstIdentifierOf(Table.class);
+            final InstanceIdentifier<Node> nodeInstanceId = identifier.<Node> firstIdentifierOf(Node.class);
+            final AddFlowInputBuilder builder = new AddFlowInputBuilder(flow);
+            
+            builder.setNode(new NodeRef(nodeInstanceId));
+            builder.setFlowRef(new FlowRef(identifier));
+            builder.setFlowTable(new FlowTableRef(tableInstanceId));
+            
+            Uri uri = new Uri(this.getTransactionId());
+            builder.setTransactionUri(uri);
+            this.salFlowService.addFlow((AddFlowInput) builder.build());
+            LOG.debug("Transaction {} - Add Flow has added flow: {}", new Object[]{uri, addDataObj});
+        }
+    }
+}
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowCommitHandler.xtend b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowCommitHandler.xtend
deleted file mode 100644 (file)
index 188bfcd..0000000
+++ /dev/null
@@ -1,29 +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.frm.flow
-
-import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler
-import org.opendaylight.controller.md.sal.common.api.data.DataModification
-import org.opendaylight.yangtools.yang.binding.DataObject
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService
-
-class FlowCommitHandler implements DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject> {
-       
-    @Property
-    val SalFlowService salFlowService;
-    
-    new(SalFlowService manager) {
-        _salFlowService = manager;
-    }
-    
-    override requestCommit(DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification) {
-        return new FlowTransaction(modification,salFlowService);
-    }
-    
-}
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowProvider.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowProvider.java
new file mode 100644 (file)
index 0000000..afdd628
--- /dev/null
@@ -0,0 +1,70 @@
+/**
+ * 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.frm.flow;
+
+import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;
+import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService;
+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.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class FlowProvider implements AutoCloseable {
+
+    private final static Logger LOG = LoggerFactory.getLogger(FlowProvider.class);
+
+    private SalFlowService salFlowService;
+    private DataProviderService dataService;
+
+    /* DataChangeListener */
+    private FlowChangeListener flowDataChangeListener;
+    ListenerRegistration<DataChangeListener> flowDataChangeListenerRegistration;
+
+    public void start() {
+        /* Build Path */
+        InstanceIdentifierBuilder<Nodes> nodesBuilder = InstanceIdentifier.<Nodes> builder(Nodes.class);
+        InstanceIdentifierBuilder<Node> nodeChild = nodesBuilder.<Node> child(Node.class);
+        InstanceIdentifierBuilder<FlowCapableNode> augmentFlowCapNode = nodeChild.<FlowCapableNode> augmentation(FlowCapableNode.class);
+        InstanceIdentifierBuilder<Table> tableChild = augmentFlowCapNode.<Table> child(Table.class);
+        InstanceIdentifierBuilder<Flow> flowChild = tableChild.<Flow> child(Flow.class);
+        final InstanceIdentifier<? extends DataObject> flowDataObjectPath = flowChild.toInstance();
+        
+        /* DataChangeListener registration */
+        this.flowDataChangeListener = new FlowChangeListener(this.salFlowService);
+        this.flowDataChangeListenerRegistration = this.dataService.registerDataChangeListener(flowDataObjectPath, flowDataChangeListener);
+        LOG.info("Flow Config Provider started.");
+    }
+
+    protected DataModificationTransaction startChange() {
+        return this.dataService.beginTransaction();
+    }
+
+    @Override
+    public void close() throws Exception {
+        if(flowDataChangeListenerRegistration != null){
+            flowDataChangeListenerRegistration.close();
+        }
+    }
+
+    public void setDataService(final DataProviderService dataService) {
+        this.dataService = dataService;
+    }
+
+    public void setSalFlowService(final SalFlowService salFlowService) {
+        this.salFlowService = salFlowService;
+    }
+}
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowProvider.xtend b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowProvider.xtend
deleted file mode 100644 (file)
index d2ed541..0000000
+++ /dev/null
@@ -1,57 +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.frm.flow
-
-import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService
-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.yangtools.concepts.Registration
-import org.opendaylight.yangtools.yang.binding.DataObject
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-import org.slf4j.LoggerFactory
-
-class FlowProvider implements AutoCloseable {
-    
-    @Property
-    DataProviderService dataService;
-    
-    @Property
-    SalFlowService salFlowService;
-    
-    FlowCommitHandler commitHandler
-
-    Registration<DataCommitHandler<InstanceIdentifier<? extends DataObject>,DataObject>> commitHandlerRegistration;
-    
-    static val LOG = LoggerFactory.getLogger(FlowProvider);
-    
-    def void start() {
-        commitHandler = new FlowCommitHandler(salFlowService)
-        val InstanceIdentifier<? extends DataObject> path = InstanceIdentifier.builder(Nodes)
-            .child(Node)
-            .augmentation(FlowCapableNode)
-            .child(Table)
-            .child(Flow)
-            .toInstance();
-        commitHandlerRegistration = dataService.registerCommitHandler(path,commitHandler);
-        LOG.info("Flow Config Provider started.");
-    }
-
-    protected def startChange() {
-        return dataService.beginTransaction;
-    }
-    
-    override close() throws Exception {
-        throw new UnsupportedOperationException("TODO: auto-generated method stub")
-    }
-    
-}
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowTransaction.xtend b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowTransaction.xtend
deleted file mode 100644 (file)
index 26846ad..0000000
+++ /dev/null
@@ -1,88 +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.frm.flow
-
-import org.opendaylight.controller.frm.AbstractTransaction
-import org.opendaylight.controller.md.sal.common.api.data.DataModification
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInputBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowTableRef
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInputBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInputBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.OriginalFlowBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.UpdatedFlowBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node
-import org.opendaylight.yangtools.yang.binding.DataObject
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowRef
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri
-
-class FlowTransaction extends AbstractTransaction {
-    
-    @Property
-    val SalFlowService salFlowService;   
-    
-    
-    new(DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification,SalFlowService salFlowService) {
-        super(modification)        
-        _salFlowService = salFlowService;
-    }
-    
-    override remove(InstanceIdentifier<?> instanceId, DataObject obj) {
-        if(obj instanceof Flow) {
-            val flow = (obj as Flow)
-            val tableInstanceId = instanceId.firstIdentifierOf(Table);
-            val nodeInstanceId = instanceId.firstIdentifierOf(Node);
-            val builder = new RemoveFlowInputBuilder(flow);
-            builder.setFlowRef(new FlowRef(instanceId));            
-            builder.setNode(new NodeRef(nodeInstanceId));
-            builder.setFlowTable(new FlowTableRef(tableInstanceId));
-            builder.setTransactionUri(new Uri(modification.getIdentifier() as String));
-            _salFlowService.removeFlow(builder.build());            
-        }
-    }
-    
-    override update(InstanceIdentifier<?> instanceId, DataObject originalObj, DataObject updatedObj) {
-        if(originalObj instanceof Flow && updatedObj instanceof Flow) {
-            val originalFlow = (originalObj as Flow)
-            val updatedFlow = (updatedObj as Flow)
-            val nodeInstanceId = instanceId.firstIdentifierOf(Node);
-            val builder = new UpdateFlowInputBuilder();
-            builder.setNode(new NodeRef(nodeInstanceId));
-            builder.setFlowRef(new FlowRef(instanceId));
-            val ufb = new UpdatedFlowBuilder(updatedFlow);
-            builder.setUpdatedFlow((ufb.build()));
-            builder.setTransactionUri(new Uri(modification.getIdentifier() as String));
-            val ofb = new OriginalFlowBuilder(originalFlow);
-            builder.setOriginalFlow(ofb.build());      
-            _salFlowService.updateFlow(builder.build());
-           
-        }
-    }
-    
-    override add(InstanceIdentifier<?> instanceId, DataObject obj) {
-        if(obj instanceof Flow) {
-            val flow = (obj as Flow)
-            val tableInstanceId = instanceId.firstIdentifierOf(Table);
-            val nodeInstanceId = instanceId.firstIdentifierOf(Node);
-            val builder = new AddFlowInputBuilder(flow);
-            builder.setNode(new NodeRef(nodeInstanceId));
-            builder.setTransactionUri(new Uri(modification.getIdentifier() as String));
-            builder.setFlowRef(new FlowRef(instanceId));
-            builder.setFlowTable(new FlowTableRef(tableInstanceId));
-            _salFlowService.addFlow(builder.build());            
-        }
-    }
-    
-    override validate() throws IllegalStateException {
-        FlowTransactionValidator.validate(this)
-    }  
-}
index 7c6f1ff1cb8afcf6fcd797194c99db160b8935e9..4ef93a55e9d515ebcc8e15312ae72108658d379b 100644 (file)
@@ -1,6 +1,6 @@
-/*
+/**
  * 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
@@ -9,8 +9,7 @@ package org.opendaylight.controller.frm.flow;
 
 public class FlowTransactionValidator {
 
-    public static void validate(FlowTransaction transaction) throws IllegalStateException {
+    public static void validate(FlowChangeListener transaction) throws IllegalStateException {
         // NOOP
     }
-
 }
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupChangeListener.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupChangeListener.java
new file mode 100644 (file)
index 0000000..1260f0e
--- /dev/null
@@ -0,0 +1,113 @@
+/**
+ * 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.frm.group;
+
+import org.opendaylight.controller.frm.AbstractChangeListener;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.SalGroupService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.group.update.OriginalGroup;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.group.update.OriginalGroupBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.group.update.UpdatedGroup;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.group.update.UpdatedGroupBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * 
+ * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
+ *
+ */
+public class GroupChangeListener extends AbstractChangeListener {
+
+    private final static Logger LOG = LoggerFactory.getLogger(GroupChangeListener.class);
+
+    private final SalGroupService salGroupService;
+
+    public SalGroupService getSalGroupService() {
+        return this.salGroupService;
+    }
+    
+    public GroupChangeListener(final SalGroupService manager) {
+        this.salGroupService = manager;
+    }
+
+    @Override
+    protected void validate() throws IllegalStateException {
+        GroupTransactionValidator.validate(this);
+    }
+
+    @Override
+    protected void remove(InstanceIdentifier<? extends DataObject> identifier, DataObject removeDataObj) {
+        if ((removeDataObj instanceof Group)) {
+            
+            final Group group = ((Group) removeDataObj);
+            final InstanceIdentifier<Node> nodeInstanceId = identifier.<Node> firstIdentifierOf(Node.class);
+            final RemoveGroupInputBuilder builder = new RemoveGroupInputBuilder(group);
+            
+            builder.setNode(new NodeRef(nodeInstanceId));
+            builder.setGroupRef(new GroupRef(identifier));
+            
+            Uri uri = new Uri(this.getTransactionId());
+            builder.setTransactionUri(uri);
+            this.salGroupService.removeGroup((RemoveGroupInput) builder.build());
+            LOG.debug("Transaction {} - Remove Group has removed group: {}", new Object[]{uri, removeDataObj});
+        }
+    }
+
+    @Override
+    protected void update(InstanceIdentifier<? extends DataObject> identifier, DataObject original, DataObject update) {
+        if (original instanceof Group && update instanceof Group) {
+            
+            final Group originalGroup = ((Group) original);
+            final Group updatedGroup = ((Group) update);
+            final InstanceIdentifier<Node> nodeInstanceId = identifier.<Node> firstIdentifierOf(Node.class);
+            final UpdateGroupInputBuilder builder = new UpdateGroupInputBuilder();
+            
+            builder.setNode(new NodeRef(nodeInstanceId));
+            builder.setGroupRef(new GroupRef(identifier));
+            
+            Uri uri = new Uri(this.getTransactionId());
+            builder.setTransactionUri(uri);
+            
+            builder.setUpdatedGroup((UpdatedGroup) (new UpdatedGroupBuilder(updatedGroup)).build());
+            builder.setOriginalGroup((OriginalGroup) (new OriginalGroupBuilder(originalGroup)).build());
+            
+            this.salGroupService.updateGroup((UpdateGroupInput) builder.build());
+            LOG.debug("Transaction {} - Update Group has updated group {} with group {}", new Object[]{uri, original, update});
+        }
+    }
+
+    @Override
+    protected void add(InstanceIdentifier<? extends DataObject> identifier, DataObject addDataObj) {
+        if ((addDataObj instanceof Group)) {
+            final Group group = ((Group) addDataObj);
+            final InstanceIdentifier<Node> nodeInstanceId = identifier.<Node> firstIdentifierOf(Node.class);
+            final AddGroupInputBuilder builder = new AddGroupInputBuilder(group);
+            
+            builder.setNode(new NodeRef(nodeInstanceId));
+            builder.setGroupRef(new GroupRef(identifier));
+            
+            Uri uri = new Uri(this.getTransactionId());
+            builder.setTransactionUri(uri);
+            this.salGroupService.addGroup((AddGroupInput) builder.build());
+            LOG.debug("Transaction {} - Add Group has added group: {}", new Object[]{uri, addDataObj});
+        }
+    }
+}
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupCommitHandler.xtend b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupCommitHandler.xtend
deleted file mode 100644 (file)
index b6d3851..0000000
+++ /dev/null
@@ -1,29 +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.frm.group
-
-import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler
-import org.opendaylight.controller.md.sal.common.api.data.DataModification
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.SalGroupService
-import org.opendaylight.yangtools.yang.binding.DataObject
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-
-class GroupCommitHandler implements DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject> {
-       
-    @Property
-    val SalGroupService groupService;
-    
-    new(SalGroupService groupService) {
-        _groupService = groupService;
-    }
-    
-    override requestCommit(DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification) {
-        return new GroupTransaction(modification,groupService);
-    }
-    
-}
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupProvider.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupProvider.java
new file mode 100644 (file)
index 0000000..14b1b6f
--- /dev/null
@@ -0,0 +1,67 @@
+/**
+ * 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.frm.group;
+
+import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;
+import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.SalGroupService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
+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.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class GroupProvider implements AutoCloseable {
+
+    private final static Logger LOG = LoggerFactory.getLogger(GroupProvider.class);
+
+    private SalGroupService salGroupService;
+    private DataProviderService dataService;
+
+    /* DataChangeListener */
+    private GroupChangeListener groupDataChangeListener;
+    ListenerRegistration<DataChangeListener> groupDataChangeListenerRegistration;
+
+    public void start() {
+        /* Build Path */
+        InstanceIdentifierBuilder<Nodes> nodesBuilder = InstanceIdentifier.<Nodes> builder(Nodes.class);
+        InstanceIdentifierBuilder<Node> nodeChild = nodesBuilder.<Node> child(Node.class);
+        InstanceIdentifierBuilder<FlowCapableNode> augmentFlowCapNode = nodeChild.<FlowCapableNode> augmentation(FlowCapableNode.class);
+        InstanceIdentifierBuilder<Group> groupChild = augmentFlowCapNode.<Group> child(Group.class);
+        final InstanceIdentifier<? extends DataObject> groupDataObjectPath = groupChild.toInstance();
+
+        /* DataChangeListener registration */
+        this.groupDataChangeListener = new GroupChangeListener(this.salGroupService);
+        this.groupDataChangeListenerRegistration = this.dataService.registerDataChangeListener(groupDataObjectPath, groupDataChangeListener);
+        LOG.info("Group Config Provider started.");
+    }
+    
+    protected DataModificationTransaction startChange() {
+        return this.dataService.beginTransaction();
+    }
+    
+    public void close() throws Exception {
+        if(groupDataChangeListenerRegistration != null){
+            groupDataChangeListenerRegistration.close();
+        }
+    }
+
+    public void setDataService(final DataProviderService dataService) {
+        this.dataService = dataService;
+    }
+
+    public void setSalGroupService(final SalGroupService salGroupService) {
+        this.salGroupService = salGroupService;
+    }
+}
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupProvider.xtend b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupProvider.xtend
deleted file mode 100644 (file)
index 4ded8b6..0000000
+++ /dev/null
@@ -1,55 +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.frm.group
-
-import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.SalGroupService
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group
-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.yangtools.concepts.Registration
-import org.opendaylight.yangtools.yang.binding.DataObject
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-import org.slf4j.LoggerFactory
-
-class GroupProvider implements AutoCloseable {
-    
-    @Property
-    DataProviderService dataService;
-    
-    @Property
-    SalGroupService salGroupService;
-    
-    GroupCommitHandler commitHandler
-
-    Registration<DataCommitHandler<InstanceIdentifier<? extends DataObject>,DataObject>> commitHandlerRegistration;
-    
-    static val LOG = LoggerFactory.getLogger(GroupProvider);
-    
-    def void start() {
-        commitHandler = new GroupCommitHandler(salGroupService)
-        val InstanceIdentifier<? extends DataObject> path = InstanceIdentifier.builder(Nodes)
-            .child(Node)
-            .augmentation(FlowCapableNode)
-            .child(Group)
-            .toInstance();
-        commitHandlerRegistration = dataService.registerCommitHandler(path,commitHandler);
-        LOG.info("Group Config Provider started.");
-    }
-
-    protected def startChange() {
-        return dataService.beginTransaction;
-    }
-    
-    override close() throws Exception {
-        throw new UnsupportedOperationException("TODO: auto-generated method stub")
-    }
-    
-}
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupTransaction.xtend b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupTransaction.xtend
deleted file mode 100644 (file)
index e8d9982..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.frm.group
-
-import org.opendaylight.controller.frm.AbstractTransaction
-import org.opendaylight.controller.md.sal.common.api.data.DataModification
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupInputBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupInputBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.SalGroupService
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupInputBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.group.update.OriginalGroupBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.group.update.UpdatedGroupBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupRef
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node
-import org.opendaylight.yangtools.yang.binding.DataObject
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri
-
-class GroupTransaction extends AbstractTransaction {
-    
-    @Property
-    val SalGroupService groupService;
-        
-    new(DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification,SalGroupService groupService) {
-        super(modification)        
-        _groupService = groupService;
-    }
-    
-    override remove(InstanceIdentifier<?> instanceId, DataObject obj) {
-        if(obj instanceof Group) {
-            val group = (obj as Group)
-            val nodeInstanceId = instanceId.firstIdentifierOf(Node);
-            val builder = new RemoveGroupInputBuilder(group);
-            builder.setNode(new NodeRef(nodeInstanceId));
-            builder.setTransactionUri(new Uri(modification.getIdentifier() as String));
-            builder.setGroupRef(new GroupRef(instanceId));
-            _groupService.removeGroup(builder.build());            
-        }
-    }
-    
-    override update(InstanceIdentifier<?> instanceId, DataObject originalObj, DataObject updatedObj) {
-        if(originalObj instanceof Group && updatedObj instanceof Group) {
-            val originalGroup = (originalObj as Group)
-            val updatedGroup = (updatedObj as Group)
-            val nodeInstanceId = instanceId.firstIdentifierOf(Node);
-            val builder = new UpdateGroupInputBuilder();
-            builder.setNode(new NodeRef(nodeInstanceId));
-            builder.setGroupRef(new GroupRef(instanceId));
-            val ufb = new UpdatedGroupBuilder(updatedGroup);
-            builder.setUpdatedGroup((ufb.build()));
-            builder.setTransactionUri(new Uri(modification.getIdentifier() as String));
-            val ofb = new OriginalGroupBuilder(originalGroup);
-            builder.setOriginalGroup(ofb.build());      
-            _groupService.updateGroup(builder.build());
-           
-        }
-    }
-    
-    override add(InstanceIdentifier<?> instanceId, DataObject obj) {
-        if(obj instanceof Group) {
-            val group = (obj as Group)
-            val nodeInstanceId = instanceId.firstIdentifierOf(Node);
-            val builder = new AddGroupInputBuilder(group);
-            builder.setNode(new NodeRef(nodeInstanceId));
-            builder.setGroupRef(new GroupRef(instanceId));
-            builder.setTransactionUri(new Uri(modification.getIdentifier() as String));
-            _groupService.addGroup(builder.build());            
-        }
-    }
-    
-    override validate() throws IllegalStateException {
-        GroupTransactionValidator.validate(this)
-    }  
-}
index 92baf7bdf0a022a7d1783e78d28bfffc4fc7a243..88eea0db343eb6c2725d7d6dc11580ceaddb50a1 100644 (file)
@@ -1,4 +1,4 @@
-/*
+/**
  * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
  *
  * This program and the accompanying materials are made available under the
@@ -9,8 +9,7 @@ package org.opendaylight.controller.frm.group;
 
 public class GroupTransactionValidator {
 
-    public static void validate(GroupTransaction transaction) throws IllegalStateException {
+    public static void validate(GroupChangeListener transaction) throws IllegalStateException {
         // NOOP
     }
-
 }
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterChangeListener.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterChangeListener.java
new file mode 100644 (file)
index 0000000..839e556
--- /dev/null
@@ -0,0 +1,114 @@
+/**
+ * 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.frm.meter;
+
+import org.opendaylight.controller.frm.AbstractChangeListener;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.AddMeterInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.AddMeterInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.RemoveMeterInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.RemoveMeterInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.SalMeterService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.UpdateMeterInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.UpdateMeterInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.meter.update.OriginalMeter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.meter.update.OriginalMeterBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.meter.update.UpdatedMeter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.meter.update.UpdatedMeterBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.Meter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterRef;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * 
+ * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
+ *
+ */
+public class MeterChangeListener extends AbstractChangeListener {
+
+    private final static Logger LOG = LoggerFactory.getLogger(MeterChangeListener.class);
+
+    private final SalMeterService salMeterService;
+
+    public SalMeterService getSalMeterService() {
+        return this.salMeterService;
+    }
+    
+    public MeterChangeListener(final SalMeterService manager) {
+        this.salMeterService = manager;
+    }
+
+    @Override
+    protected void validate() throws IllegalStateException {
+        MeterTransactionValidator.validate(this);
+    }
+
+    @Override
+    protected void remove(InstanceIdentifier<? extends DataObject> identifier, DataObject removeDataObj) {
+        if ((removeDataObj instanceof Meter)) {
+            
+            final Meter meter = ((Meter) removeDataObj);
+            final InstanceIdentifier<Node> nodeInstanceId = identifier.<Node> firstIdentifierOf(Node.class);
+            final RemoveMeterInputBuilder builder = new RemoveMeterInputBuilder(meter);
+            
+            builder.setNode(new NodeRef(nodeInstanceId));
+            builder.setMeterRef(new MeterRef(identifier));
+            
+            Uri uri = new Uri(this.getTransactionId());
+            builder.setTransactionUri(uri);
+            this.salMeterService.removeMeter((RemoveMeterInput) builder.build());
+            LOG.debug("Transaction {} - Remove Meter has removed meter: {}", new Object[]{uri, removeDataObj});
+        }
+    }
+
+    @Override
+    protected void update(InstanceIdentifier<? extends DataObject> identifier, DataObject original, DataObject update) {
+        if (original instanceof Meter && update instanceof Meter) {
+            
+            final Meter originalMeter = ((Meter) original);
+            final Meter updatedMeter = ((Meter) update);
+            final InstanceIdentifier<Node> nodeInstanceId = identifier.<Node> firstIdentifierOf(Node.class);
+            final UpdateMeterInputBuilder builder = new UpdateMeterInputBuilder();
+            
+            builder.setNode(new NodeRef(nodeInstanceId));
+            builder.setMeterRef(new MeterRef(identifier));
+            
+            Uri uri = new Uri(this.getTransactionId());
+            builder.setTransactionUri(uri);
+            
+            builder.setUpdatedMeter((UpdatedMeter) (new UpdatedMeterBuilder(updatedMeter)).build());
+            builder.setOriginalMeter((OriginalMeter) (new OriginalMeterBuilder(originalMeter)).build());
+            
+            this.salMeterService.updateMeter((UpdateMeterInput) builder.build());
+            LOG.debug("Transaction {} - Update Meter has updated meter {} with {}", new Object[]{uri, original, update});
+        }
+    }
+
+    @Override
+    protected void add(InstanceIdentifier<? extends DataObject> identifier, DataObject addDataObj) {
+        if ((addDataObj instanceof Meter)) {
+            
+            final Meter meter = ((Meter) addDataObj);
+            final InstanceIdentifier<Node> nodeInstanceId = identifier.<Node> firstIdentifierOf(Node.class);
+            final AddMeterInputBuilder builder = new AddMeterInputBuilder(meter);
+            
+            builder.setNode(new NodeRef(nodeInstanceId));
+            builder.setMeterRef(new MeterRef(identifier));
+            
+            Uri uri = new Uri(this.getTransactionId());
+            builder.setTransactionUri(uri);
+            this.salMeterService.addMeter((AddMeterInput) builder.build());
+            LOG.debug("Transaction {} - Add Meter has added meter: {}", new Object[]{uri, addDataObj});
+        }
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterCommitHandler.xtend b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterCommitHandler.xtend
deleted file mode 100644 (file)
index d5292f0..0000000
+++ /dev/null
@@ -1,29 +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.frm.meter
-
-import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler
-import org.opendaylight.controller.md.sal.common.api.data.DataModification
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.SalMeterService
-import org.opendaylight.yangtools.yang.binding.DataObject
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-
-class FlowCommitHandler implements DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject> {
-       
-    @Property
-    val SalMeterService salMeterService;
-    
-    new(SalMeterService manager) {
-        _salMeterService = manager;
-    }
-    
-    override requestCommit(DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification) {
-        return new MeterTransaction(modification,salMeterService);
-    }
-    
-}
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterProvider.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterProvider.java
new file mode 100644 (file)
index 0000000..620801f
--- /dev/null
@@ -0,0 +1,67 @@
+/**
+ * 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.frm.meter;
+
+import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;
+import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter;
+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.meter.service.rev130918.SalMeterService;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class MeterProvider implements AutoCloseable {
+
+    private final static Logger LOG = LoggerFactory.getLogger(MeterProvider.class);
+
+    private DataProviderService dataService;
+    private SalMeterService salMeterService;
+
+    /* DataChangeListener */
+    private MeterChangeListener meterDataChangeListener;
+    ListenerRegistration<DataChangeListener> meterDataChangeListenerRegistration;
+
+    public void start() {
+        /* Build Path */
+        InstanceIdentifierBuilder<Nodes> nodesBuilder = InstanceIdentifier.<Nodes> builder(Nodes.class);
+        InstanceIdentifierBuilder<Node> nodeChild = nodesBuilder.<Node> child(Node.class);
+        InstanceIdentifierBuilder<FlowCapableNode> augmentFlowCapNode = nodeChild.<FlowCapableNode> augmentation(FlowCapableNode.class);
+        InstanceIdentifierBuilder<Meter> meterChild = augmentFlowCapNode.<Meter> child(Meter.class);
+        final InstanceIdentifier<? extends DataObject> meterDataObjectPath = meterChild.toInstance();
+
+        /* DataChangeListener registration */
+        this.meterDataChangeListener = new MeterChangeListener(this.salMeterService);
+        this.meterDataChangeListenerRegistration = this.dataService.registerDataChangeListener(meterDataObjectPath, meterDataChangeListener);
+        LOG.info("Meter Config Provider started.");
+    }
+    
+    protected DataModificationTransaction startChange() {
+        return this.dataService.beginTransaction();
+    }
+
+    public void close() throws Exception {
+        if(meterDataChangeListenerRegistration != null){
+            meterDataChangeListenerRegistration.close();
+        }
+    }
+
+    public void setDataService(final DataProviderService dataService) {
+        this.dataService = dataService;
+    }
+
+    public void setSalMeterService(final SalMeterService salMeterService) {
+        this.salMeterService = salMeterService;
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterProvider.xtend b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterProvider.xtend
deleted file mode 100644 (file)
index 323da57..0000000
+++ /dev/null
@@ -1,55 +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.frm.meter
-
-import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter
-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.meter.service.rev130918.SalMeterService
-import org.opendaylight.yangtools.concepts.Registration
-import org.opendaylight.yangtools.yang.binding.DataObject
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-import org.slf4j.LoggerFactory
-
-class MeterProvider implements AutoCloseable {
-    
-    @Property
-    DataProviderService dataService;
-    
-    @Property
-    SalMeterService salMeterService;
-    
-    FlowCommitHandler commitHandler
-
-    Registration<DataCommitHandler<InstanceIdentifier<? extends DataObject>,DataObject>> commitHandlerRegistration;
-    
-    static val LOG = LoggerFactory.getLogger(MeterProvider);
-    
-    def void start() {
-        commitHandler = new FlowCommitHandler(salMeterService)
-        val InstanceIdentifier<? extends DataObject> path = InstanceIdentifier.builder(Nodes)
-            .child(Node)
-            .augmentation(FlowCapableNode)
-            .child(Meter)
-            .toInstance();
-        commitHandlerRegistration = dataService.registerCommitHandler(path,commitHandler);
-        LOG.info("Meter Config Provider started.");
-    }
-
-    protected def startChange() {
-        return dataService.beginTransaction;
-    }
-    
-    override close() throws Exception {
-        throw new UnsupportedOperationException("TODO: auto-generated method stub")
-    }
-    
-}
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterTransaction.xtend b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterTransaction.xtend
deleted file mode 100644 (file)
index 491fa08..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.frm.meter
-
-import org.opendaylight.controller.frm.AbstractTransaction
-import org.opendaylight.controller.md.sal.common.api.data.DataModification
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.AddMeterInputBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.RemoveMeterInputBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.SalMeterService
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.UpdateMeterInputBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.meter.update.OriginalMeterBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.meter.update.UpdatedMeterBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.Meter
-import org.opendaylight.yangtools.yang.binding.DataObject
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterRef
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri
-
-class MeterTransaction extends AbstractTransaction {
-    
-    @Property
-    val SalMeterService salMeterService;
-        
-    new(DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification,SalMeterService salMeterService) {
-        super(modification)    
-        _salMeterService = salMeterService;
-    }
-    
-    override remove(InstanceIdentifier<?> instanceId, DataObject obj) {
-        if(obj instanceof Meter) {
-            val meter = (obj as Meter)
-            val nodeInstanceId = instanceId.firstIdentifierOf(Node);
-            val builder = new RemoveMeterInputBuilder(meter);
-            builder.setNode(new NodeRef(nodeInstanceId));
-            builder.setMeterRef(new MeterRef(instanceId));
-            builder.setTransactionUri(new Uri(modification.getIdentifier() as String));
-            _salMeterService.removeMeter(builder.build());            
-        }
-    }
-    
-    override update(InstanceIdentifier<?> instanceId, DataObject originalObj, DataObject updatedObj) {
-        if(originalObj instanceof Meter && updatedObj instanceof Meter) {
-            val originalMeter = (originalObj as Meter)
-            val updatedMeter = (updatedObj as Meter)
-            val nodeInstanceId = instanceId.firstIdentifierOf(Node);
-            val builder = new UpdateMeterInputBuilder();
-            builder.setNode(new NodeRef(nodeInstanceId));
-            builder.setMeterRef(new MeterRef(instanceId));
-            val ufb = new UpdatedMeterBuilder(updatedMeter);
-            builder.setUpdatedMeter((ufb.build()));
-            builder.setTransactionUri(new Uri(modification.getIdentifier() as String));
-            val ofb = new OriginalMeterBuilder(originalMeter);
-            builder.setOriginalMeter(ofb.build());      
-            _salMeterService.updateMeter(builder.build());
-           
-        }
-    }
-    
-    override add(InstanceIdentifier<?> instanceId, DataObject obj) {
-        if(obj instanceof Meter) {
-            val meter = (obj as Meter)
-            val nodeInstanceId = instanceId.firstIdentifierOf(Node);
-            val builder = new AddMeterInputBuilder(meter);
-            builder.setNode(new NodeRef(nodeInstanceId));
-            builder.setMeterRef(new MeterRef(instanceId));
-            builder.setTransactionUri(new Uri(modification.getIdentifier() as String));
-            _salMeterService.addMeter(builder.build());            
-        }
-    }
-    
-    override validate() throws IllegalStateException {
-        MeterTransactionValidator.validate(this)
-    }  
-}
index b16739cc5b8f551dc25e10bfa24aed91ccfde46e..c8fba23b93601e4c3bde099e4e4a45221f1a2fdc 100644 (file)
@@ -1,4 +1,4 @@
-/*
+/**
  * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
  *
  * This program and the accompanying materials are made available under the
@@ -9,8 +9,7 @@ package org.opendaylight.controller.frm.meter;
 
 public class MeterTransactionValidator {
 
-    public static void validate(MeterTransaction transaction) throws IllegalStateException {
+    public static void validate(MeterChangeListener transaction) throws IllegalStateException {
         // NOOP
     }
-
 }
index 21fa207d781a8cd74a16b49b1f7dc72d77e89daf..d1354f897fdcd45133c3ae17c5045a1ddf046095 100644 (file)
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.yangtools</groupId>
+      <artifactId>yang-binding</artifactId>
+    </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal-binding-broker-impl</artifactId>
       <type>test-jar</type>
       <scope>test</scope>
     </dependency>
-    <dependency>
-    <groupId>org.opendaylight.yangtools</groupId>
-    <artifactId>yang-binding</artifactId>
-    </dependency>
     <dependency>
       <groupId>org.opendaylight.controller.model</groupId>
       <artifactId>model-flow-management</artifactId>
   </dependencies>
   <build>
     <plugins>
-    <plugin>
-        <groupId>org.opendaylight.yangtools</groupId>
-        <artifactId>yang-maven-plugin</artifactId>
-        <executions>
-          <execution>
-            <goals>
-              <goal>generate-sources</goal>
-            </goals>
-            <configuration>
-              <codeGenerators>
-                <generator>
-                  <codeGeneratorClass>org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl</codeGeneratorClass>
-                  <outputBaseDir>${salGeneratorPath}</outputBaseDir>
-                </generator>
-              </codeGenerators>
-              <inspectDependencies>true</inspectDependencies>
-            </configuration>
-          </execution>
-        </executions>
-    </plugin>
       <plugin>
         <groupId>org.jacoco</groupId>
         <artifactId>jacoco-maven-plugin</artifactId>
           </execution>
         </executions>
       </plugin>
+      <plugin>
+        <groupId>org.opendaylight.yangtools</groupId>
+        <artifactId>yang-maven-plugin</artifactId>
+        <executions>
+          <execution>
+            <goals>
+              <goal>generate-sources</goal>
+            </goals>
+            <configuration>
+              <codeGenerators>
+                <generator>
+                  <codeGeneratorClass>org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl</codeGeneratorClass>
+                  <outputBaseDir>${salGeneratorPath}</outputBaseDir>
+                </generator>
+              </codeGenerators>
+              <inspectDependencies>true</inspectDependencies>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
     </plugins>
   </build>
   <scm>
@@ -16,6 +16,7 @@ import java.util.Collection;
 import java.util.List;
 
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ConsumerContext;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
@@ -36,7 +37,8 @@ import org.opendaylight.yangtools.concepts.Registration;
 import org.opendaylight.yangtools.yang.binding.NotificationListener;
 import org.opendaylight.yangtools.yang.binding.RpcService;
 
-public class NoficationTest extends AbstractTest {
+@Ignore
+public class NotificationTest extends AbstractTest {
 
     private final FlowListener listener1 = new FlowListener();
     private final FlowListener listener2 = new FlowListener();
index 08d22b96d67bcee2331ca6512904154cc11b6868..37ef257224d30ad749a6030557fab85f7fb734c6 100644 (file)
                                 </provider>
                             </instance>
                         </service>
+
                         <service>
                             <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">
                                 binding:binding-broker-osgi-registry
                                 </provider>
                             </instance>
                         </service>
+                        <service>
+                            <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-rpc-registry</type>
+                            <instance>
+                                <name>binding-rpc-broker</name>
+                                <provider>/modules/module[type='binding-broker-impl'][name='binding-broker-impl']</provider>
+                            </instance>
+                        </service>
                         <service>
                             <type xmlns:binding-impl="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
                                 binding-impl:binding-dom-mapping-service
index a91799d45823a2e2a6c8f90e69cd0931df18584d..19235d2ddfe56bac11b05cfe2bc9d36fee271bde 100644 (file)
@@ -11,6 +11,7 @@ import com.google.common.base.Predicate;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
 
 public final class ImmutableDataChangeEvent<P extends Path<P>, D> implements DataChangeEvent<P,D> {
 
@@ -127,6 +128,8 @@ public final class ImmutableDataChangeEvent<P extends Path<P>, D> implements Dat
             originalOperational.putAll(Maps.filterKeys(data.getOriginalOperationalData(), keyFilter));
             createdOperational.putAll(Maps.filterKeys(data.getCreatedOperationalData(), keyFilter));
             createdConfiguration.putAll(Maps.filterKeys(data.getCreatedConfigurationData(), keyFilter));
+            removedOperational.addAll(Sets.filter(data.getRemovedOperationalData(), keyFilter));
+            removedConfiguration.addAll(Sets.filter(data.getRemovedConfigurationData(), keyFilter));
             return this;
         }
 
index 8d52950a2954539da471fcbe1f164b01f4eeb1c1..aa5c6f40a9a4f827c88aa97d9a72551d6e8fd94f 100644 (file)
@@ -289,7 +289,7 @@ public class NetconfDevice implements Provider, //
 
     @Override
     public ListenableFuture<RpcResult<CompositeNode>> invokeRpc(QName rpc, CompositeNode input) {
-        return listener.sendRequest(toRpcMessage(rpc, input, getSchemaContext()));
+        return listener.sendRequest(toRpcMessage(rpc, input, getSchemaContext()), rpc);
     }
 
     @Override
index 94f5e166a115e216cf839e52a044bc870c34c661..1dfc3b44d3191bf00427d9e5908ff0f68f7517e0 100644 (file)
@@ -25,6 +25,7 @@ import org.opendaylight.controller.netconf.client.NetconfClientSession;
 import org.opendaylight.controller.netconf.client.NetconfClientSessionListener;
 import org.opendaylight.controller.netconf.util.xml.XmlElement;
 import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
+import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.opendaylight.controller.sal.common.util.Rpcs;
 import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance;
 import org.opendaylight.yangtools.yang.common.QName;
@@ -45,10 +46,12 @@ class NetconfDeviceListener implements NetconfClientSessionListener {
     private static final class Request {
         final UncancellableFuture<RpcResult<CompositeNode>> future;
         final NetconfMessage request;
+        final QName rpc;
 
-        private Request(UncancellableFuture<RpcResult<CompositeNode>> future, NetconfMessage request) {
+        private Request(UncancellableFuture<RpcResult<CompositeNode>> future, NetconfMessage request, final QName rpc) {
             this.future = future;
             this.request = request;
+            this.rpc = rpc;
         }
     }
 
@@ -163,14 +166,13 @@ class NetconfDeviceListener implements NetconfClientSessionListener {
                 return;
             }
 
-            r.future.set(Rpcs.getRpcResult(true, NetconfMapping.toNotificationNode(message, device.getSchemaContext()),
-                    Collections.<RpcError>emptyList()));
+            r.future.set(NetconfMapping.toRpcResult(message, r.rpc, device.getSchemaContext()));
         } else {
             LOG.warn("Ignoring unsolicited message", message);
         }
     }
 
-    synchronized ListenableFuture<RpcResult<CompositeNode>> sendRequest(final NetconfMessage message) {
+    synchronized ListenableFuture<RpcResult<CompositeNode>> sendRequest(final NetconfMessage message, final QName rpc) {
         if (session == null) {
             LOG.debug("Session to {} is disconnected, failing RPC request {}", device.getName(), message);
             return Futures.<RpcResult<CompositeNode>>immediateFuture(new RpcResult<CompositeNode>() {
@@ -192,7 +194,7 @@ class NetconfDeviceListener implements NetconfClientSessionListener {
             });
         }
 
-        final Request req = new Request(new UncancellableFuture<RpcResult<CompositeNode>>(true), message);
+        final Request req = new Request(new UncancellableFuture<RpcResult<CompositeNode>>(true), message, rpc);
         requests.add(req);
 
         session.sendMessage(req.request).addListener(new FutureListener<Void>() {
@@ -200,7 +202,7 @@ class NetconfDeviceListener implements NetconfClientSessionListener {
             public void operationComplete(final Future<Void> future) throws Exception {
                 if (!future.isSuccess()) {
                     // We expect that a session down will occur at this point
-                    LOG.debug("Failed to send request {}", req.request, future.cause());
+                    LOG.debug("Failed to send request {}", XmlUtil.toString(req.request.getDocument()), future.cause());
                     req.future.setException(future.cause());
                 } else {
                     LOG.trace("Finished sending request {}", req.request);
index a6e6b3dfdf456d92711da924522d22de0aeea788..f0b711d368595dede27c14030b4d0d4ef64112a6 100644 (file)
@@ -192,12 +192,6 @@ public class NetconfMapping {
                 rawRpc = it.toInstance();
                 // sys(xmlData)
             } else {
-                RpcDefinition rpcSchema = Iterables.find(context.get().getOperations(), new Predicate<RpcDefinition>() {
-                    @Override
-                    public boolean apply(final RpcDefinition input) {
-                        return rpc == input.getQName();
-                    }
-                });
                 rawRpc = (CompositeNode) toCompositeNode(message.getDocument());
             }
         else {
index c734e80d9aa06f76d3c4a96c277b8c71a7a48d74..abd935dd63e177ddfe23b1de713891351080c3ab 100644 (file)
@@ -20,6 +20,8 @@ import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProvider;
 
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 class NetconfRemoteSchemaSourceProvider implements SchemaSourceProvider<String> {
 
@@ -30,8 +32,11 @@ class NetconfRemoteSchemaSourceProvider implements SchemaSourceProvider<String>
 
     private final NetconfDevice device;
 
+    private final Logger logger;
+
     public NetconfRemoteSchemaSourceProvider(NetconfDevice device) {
         this.device = Preconditions.checkNotNull(device);
+        logger = LoggerFactory.getLogger(NetconfDevice.class + "#" + device.getName());
     }
 
     @Override
@@ -44,7 +49,7 @@ class NetconfRemoteSchemaSourceProvider implements SchemaSourceProvider<String>
             request.addLeaf("version", revision.get());
         }
 
-        device.logger.trace("Loading YANG schema source for {}:{}", moduleName, revision);
+        logger.trace("Loading YANG schema source for {}:{}", moduleName, revision);
         try {
             RpcResult<CompositeNode> schemaReply = device.invokeRpc(GET_SCHEMA_QNAME, request.toInstance()).get();
             if (schemaReply.isSuccessful()) {
@@ -54,9 +59,9 @@ class NetconfRemoteSchemaSourceProvider implements SchemaSourceProvider<String>
                     return Optional.of(schemaBody);
                 }
             }
-            device.logger.warn("YANG shcema was not successfully retrieved.");
+            logger.warn("YANG shcema was not successfully retrieved.");
         } catch (InterruptedException | ExecutionException e) {
-            device.logger.warn("YANG shcema was not successfully retrieved.", e);
+            logger.warn("YANG shcema was not successfully retrieved.", e);
         }
         return Optional.absent();
     }
index e19f9f5805d9074cd946aee53d48e15510d9e0ef..4d9958ee6b4720b66fe5fc2a286e754630274e20 100644 (file)
@@ -122,7 +122,7 @@ class JsonReader {
         // it could be identityref Built-In Type
         URI namespace = getNamespaceFor(value);
         if (namespace != null) {
-            return new IdentityValuesDTO(namespace.toString(), getLocalNameFor(value), null);
+            return new IdentityValuesDTO(namespace.toString(), getLocalNameFor(value), null,value);
         }
         // it is not "prefix:value" but just "value"
         return value;
index 225eb7de6a7c16c1fea465659de373e0c65ef8ab..ba3e315e72728d9e0b9f7aa2c4ee78ff892ea428 100644 (file)
@@ -42,7 +42,7 @@ public final class RestUtil {
         if (xPathParts.length < 2) { // must be at least "/pr:node"
             return null;
         }
-        IdentityValuesDTO identityValuesDTO = new IdentityValuesDTO();
+        IdentityValuesDTO identityValuesDTO = new IdentityValuesDTO(value);
         for (int i = 1; i < xPathParts.length; i++) {
             String xPathPartTrimmed = xPathParts[i].trim();
             
index d807070dbdc21ad00429410ad360d5ce87607e6f..a75f6b4a85f8277bffa57ad6034abe6bc323f2a0 100644 (file)
@@ -205,7 +205,7 @@ public class XmlReader {
         if (namespaceAndValue.length == 2) {
             String namespace = startElement.getNamespaceContext().getNamespaceURI(namespaceAndValue[0]);
             if (namespace != null && !namespace.isEmpty()) {
-                return new IdentityValuesDTO(namespace, namespaceAndValue[1], namespaceAndValue[0]);
+                return new IdentityValuesDTO(namespace, namespaceAndValue[1], namespaceAndValue[0],value);
             }
         }
         // it is not "prefix:value" but just "value"
index 4fb75141d5d8e909143c93017727d740921b8a44..14a558967d2081a18e045192712ab0988cde6efa 100644 (file)
@@ -14,13 +14,19 @@ import java.util.List;
 public final class IdentityValuesDTO {
 
     private final List<IdentityValue> elementData = new ArrayList<>();
+    private final String originValue;
 
-    public IdentityValuesDTO(String namespace, String value, String prefix) {
+    public IdentityValuesDTO(String namespace, String value, String prefix,String originValue) {
         elementData.add(new IdentityValue(namespace, value, prefix));
+        this.originValue = originValue;
+    }
+    
+    public IdentityValuesDTO(String originValue) {
+        this.originValue = originValue;
     }
     
     public IdentityValuesDTO() {
-        
+        originValue = null;
     }
 
     public void add(String namespace, String value, String prefix) {
@@ -40,6 +46,10 @@ public final class IdentityValuesDTO {
     public String toString() {
         return elementData.toString();
     }
+    
+    public String getOriginValue() {
+        return originValue;
+    }
 
     public static final class IdentityValue {
 
index d6b530039eb681cf831956b9e61a83aad106ac64..42658d79f1468b97eaead0e852b57a125ee528b9 100644 (file)
@@ -89,6 +89,9 @@ public class RestCodec {
                             input == null ? "null" : input.getClass(), String.valueOf(input));
                     return null;
                 } else if (type instanceof LeafrefTypeDefinition) {
+                    if (input instanceof IdentityValuesDTO) {
+                        return LEAFREF_DEFAULT_CODEC.deserialize(((IdentityValuesDTO)input).getOriginValue());
+                    }
                     return LEAFREF_DEFAULT_CODEC.deserialize(input);
                 } else if (type instanceof InstanceIdentifierTypeDefinition) {
                     if (input instanceof IdentityValuesDTO) {
@@ -102,6 +105,9 @@ public class RestCodec {
                     TypeDefinitionAwareCodec<Object, ? extends TypeDefinition<?>> typeAwarecodec = TypeDefinitionAwareCodec
                             .from(type);
                     if (typeAwarecodec != null) {
+                        if (input instanceof IdentityValuesDTO) {
+                            return typeAwarecodec.deserialize(((IdentityValuesDTO)input).getOriginValue());
+                        }
                         return typeAwarecodec.deserialize(String.valueOf(input));
                     } else {
                         logger.debug("Codec for type \"" + type.getQName().getLocalName()
@@ -162,7 +168,7 @@ public class RestCodec {
 
         @Override
         public IdentityValuesDTO serialize(QName data) {
-            return new IdentityValuesDTO(data.getNamespace().toString(), data.getLocalName(), data.getPrefix());
+            return new IdentityValuesDTO(data.getNamespace().toString(), data.getLocalName(), data.getPrefix(),null);
         }
 
         @Override
index fa478ac72e398ae928c619004023b8aae6cc68fe..a0bd99c5d2cc3dfc4b822125f43bdf104c8663ba 100644 (file)
@@ -669,7 +669,7 @@ class RestconfImpl implements RestconfService {
 
             if (schema.typeDefinition instanceof IdentityrefTypeDefinition) {
                 if (value instanceof String) {
-                    inputValue = new IdentityValuesDTO(nodeBuilder.namespace.toString, value as String, null)
+                    inputValue = new IdentityValuesDTO(nodeBuilder.namespace.toString, value as String, null,value as String);
                 } // else value is already instance of IdentityValuesDTO
             }
             
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/XmlAndJsonToCnSnLeafRefTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/XmlAndJsonToCnSnLeafRefTest.java
new file mode 100644 (file)
index 0000000..e5a737e
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * 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.restconf.impl.test;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+
+import javax.ws.rs.WebApplicationException;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider;
+import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.data.api.SimpleNode;
+
+public class XmlAndJsonToCnSnLeafRefTest extends YangAndXmlAndDataSchemaLoader {
+
+    @BeforeClass
+    public static void initialize() {
+        dataLoad("/leafref/yang", 2, "leafref-module", "cont");
+    }
+
+    @Test
+    public void loadXmlToCnSn() throws WebApplicationException, IOException, URISyntaxException {
+        CompositeNode cnSn = TestUtils.readInputToCnSn("/leafref/xml/xmldata.xml", XmlToCompositeNodeProvider.INSTANCE);
+        TestUtils.normalizeCompositeNode(cnSn, modules, schemaNodePath);
+        verifyContPredicate(cnSn, "/ns:cont/ns:lf1", "/cont/lf1", "/ns:cont/ns:lf1", "../lf1");
+    }
+
+    @Test
+    public void loadJsonToCnSn() throws WebApplicationException, IOException, URISyntaxException {
+        CompositeNode cnSn = TestUtils.readInputToCnSn("/leafref/json/jsondata.json",
+                JsonToCompositeNodeProvider.INSTANCE);
+        TestUtils.normalizeCompositeNode(cnSn, modules, schemaNodePath);
+        verifyContPredicate(cnSn, "/leafref-module:cont/leafref-module:lf1", "/leafref-module:cont/leafref-module:lf1",
+                "/referenced-module:cont/referenced-module:lf1", "/leafref-module:cont/leafref-module:lf1");
+    }
+
+    private void verifyContPredicate(CompositeNode cnSn, String... values) throws URISyntaxException {
+        Object lf2Value = null;
+        Object lf3Value = null;
+        Object lf4Value = null;
+        Object lf5Value = null;
+
+        for (Node<?> node : cnSn.getValue()) {
+            if (node.getNodeType().getLocalName().equals("lf2")) {
+                lf2Value = ((SimpleNode<?>) node).getValue();
+            } else if (node.getNodeType().getLocalName().equals("lf3")) {
+                lf3Value = ((SimpleNode<?>) node).getValue();
+            } else if (node.getNodeType().getLocalName().equals("lf4")) {
+                lf4Value = ((SimpleNode<?>) node).getValue();
+            } else if (node.getNodeType().getLocalName().equals("lf5")) {
+                lf5Value = ((SimpleNode<?>) node).getValue();
+            }
+        }
+        assertEquals(values[0], lf2Value);
+        assertEquals(values[1], lf3Value);
+        assertEquals(values[2], lf4Value);
+        assertEquals(values[3], lf5Value);
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/leafref/json/jsondata.json b/opendaylight/md-sal/sal-rest-connector/src/test/resources/leafref/json/jsondata.json
new file mode 100644 (file)
index 0000000..cbe455b
--- /dev/null
@@ -0,0 +1,8 @@
+{
+    "leafref-module:cont" : {
+        "lf4" : "/referenced-module:cont/referenced-module:lf1",
+        "lf2" : "/leafref-module:cont/leafref-module:lf1",
+        "lf3" : "/leafref-module:cont/leafref-module:lf1",
+        "lf5" : "/leafref-module:cont/leafref-module:lf1"
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/leafref/xml/xmldata.xml b/opendaylight/md-sal/sal-rest-connector/src/test/resources/leafref/xml/xmldata.xml
new file mode 100644 (file)
index 0000000..01bf092
--- /dev/null
@@ -0,0 +1,6 @@
+<cont xmlns="leafref:module">
+    <lf4 xmlns:ns="referenced:module">/ns:cont/ns:lf1</lf4>
+    <lf2 xmlns:ns="leafref:module">/ns:cont/ns:lf1</lf2>
+    <lf3 xmlns:ns="leafref:module">/cont/lf1</lf3>
+    <lf5 xmlns:ns="leafref:module">../lf1</lf5>
+</cont>
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/leafref/yang/leafref-module.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/leafref/yang/leafref-module.yang
new file mode 100644 (file)
index 0000000..00df290
--- /dev/null
@@ -0,0 +1,44 @@
+module leafref-module {
+  namespace "leafref:module";  
+
+
+  prefix "lfrfmodule";
+
+  import referenced-module { prefix refmod; revision-date 2014-04-17;} 
+
+  
+  revision 2014-04-17 {    
+  }
+  
+
+    container cont {
+        leaf lf1 {
+            type instance-identifier;
+        }
+
+        leaf lf2 {
+            type leafref {
+                path "../lf1";
+            }
+        }
+
+        leaf lf3 {
+            type leafref {
+                path "/refmod:cont/refmod:lf1";
+            }
+        }
+
+        leaf lf4 {
+            type leafref {
+                path "/cont/lf1";
+            }
+        }
+
+        leaf lf5 {
+            type leafref {
+                path "../lf1";
+            }
+        }
+        
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/leafref/yang/referenced-module.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/leafref/yang/referenced-module.yang
new file mode 100644 (file)
index 0000000..b6de719
--- /dev/null
@@ -0,0 +1,13 @@
+module referenced-module {
+  namespace "referenced:module";  
+
+  prefix "refmodule";
+  revision 2014-04-17 {    
+  }
+
+    container cont {
+        leaf lf1 {
+            type instance-identifier;
+        }
+    }
+}
\ No newline at end of file
index 4a58579b13fd542936f876ddad48c7ebaabcb8a5..167fb21ffdc763f6cda840fc42b6b1e6aed03c7f 100644 (file)
@@ -20,8 +20,8 @@ abstract class AbstractListeningStatsTracker<I, K> extends AbstractStatsTracker<
     private static final Logger logger = LoggerFactory.getLogger(AbstractListeningStatsTracker.class);
     private ListenerRegistration<?> reg;
 
-    protected AbstractListeningStatsTracker(FlowCapableContext context, long lifetimeNanos) {
-        super(context, lifetimeNanos);
+    protected AbstractListeningStatsTracker(FlowCapableContext context) {
+        super(context);
     }
 
     protected abstract InstanceIdentifier<?> listenPath();
index c29b6a7730ced4f24374d2e4e67a650f3ed69293..e922656d919f5726de7fe19d743458a26f08a531 100644 (file)
@@ -32,6 +32,9 @@ import com.google.common.util.concurrent.JdkFutureAdapters;
 
 abstract class AbstractStatsTracker<I, K> {
     private static final Logger logger = LoggerFactory.getLogger(AbstractStatsTracker.class);
+    
+    private static final int WAIT_FOR_REQUEST_CYCLE = 2;
+    
     private final FutureCallback<RpcResult<? extends TransactionAware>> callback =
             new FutureCallback<RpcResult<? extends TransactionAware>>() {
         @Override
@@ -62,11 +65,11 @@ abstract class AbstractStatsTracker<I, K> {
 
     private final Map<K, Long> trackedItems = new HashMap<>();
     private final FlowCapableContext context;
-    private final long lifetimeNanos;
+    private long requestCounter;
 
-    protected AbstractStatsTracker(final FlowCapableContext context, final long lifetimeNanos) {
+    protected AbstractStatsTracker(final FlowCapableContext context) {
         this.context = Preconditions.checkNotNull(context);
-        this.lifetimeNanos = lifetimeNanos;
+        this.requestCounter = 0;
     }
 
     protected final InstanceIdentifierBuilder<Node> getNodeIdentifierBuilder() {
@@ -89,24 +92,32 @@ abstract class AbstractStatsTracker<I, K> {
         return context.startDataModification();
     }
 
+    public final synchronized void increaseRequestCounter(){
+        this.requestCounter++;
+    }
     protected abstract void cleanupSingleStat(DataModificationTransaction trans, K item);
     protected abstract K updateSingleStat(DataModificationTransaction trans, I item);
+    public abstract void request();
 
     public final synchronized void updateStats(List<I> list) {
-        final Long expiryTime = System.nanoTime() + lifetimeNanos;
+
         final DataModificationTransaction trans = startTransaction();
 
         for (final I item : list) {
-            trackedItems.put(updateSingleStat(trans, item), expiryTime);
+            trackedItems.put(updateSingleStat(trans, item), requestCounter);
         }
 
         trans.commit();
     }
 
-    public final synchronized void cleanup(final DataModificationTransaction trans, long now) {
+    /**
+     * Statistics will be cleaned up if not update in last two request cycles.
+     * @param trans
+     */
+    public final synchronized void cleanup(final DataModificationTransaction trans) {
         for (Iterator<Entry<K, Long>> it = trackedItems.entrySet().iterator();it.hasNext();){
             Entry<K, Long> e = it.next();
-            if (now > e.getValue()) {
+            if (requestCounter >= e.getValue()+WAIT_FOR_REQUEST_CYCLE) {
                 cleanupSingleStat(trans, e.getKey());
                 it.remove();
             }
index 90ddc28acd0066e72e8e134a49c0a786b6f49b4b..06d6e821122617aa1642e3cfd6a5d46808f8518a 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.controller.md.statistics.manager;
 
+import java.util.Collection;
 import java.util.Map.Entry;
 
 import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
@@ -37,12 +38,17 @@ import org.slf4j.LoggerFactory;
 final class FlowStatsTracker extends AbstractListeningStatsTracker<FlowAndStatisticsMapList, FlowStatsEntry> {
     private static final Logger logger = LoggerFactory.getLogger(FlowStatsTracker.class);
     private final OpendaylightFlowStatisticsService flowStatsService;
+    private FlowTableStatsTracker flowTableStats;
     private int unaccountedFlowsCounter = 1;
 
-    FlowStatsTracker(OpendaylightFlowStatisticsService flowStatsService, final FlowCapableContext context, long lifetimeNanos) {
-        super(context, lifetimeNanos);
+    FlowStatsTracker(OpendaylightFlowStatisticsService flowStatsService, final FlowCapableContext context) {
+        super(context);
         this.flowStatsService = flowStatsService;
     }
+    FlowStatsTracker(OpendaylightFlowStatisticsService flowStatsService, final FlowCapableContext context, FlowTableStatsTracker flowTableStats) {
+        this(flowStatsService, context);
+        this.flowTableStats = flowTableStats;
+    }
 
     @Override
     protected void cleanupSingleStat(DataModificationTransaction trans, FlowStatsEntry item) {
@@ -203,6 +209,20 @@ final class FlowStatsTracker extends AbstractListeningStatsTracker<FlowAndStatis
         return "Flow";
     }
 
+    @Override
+    public void request() {
+        // FIXME: it does not make sense to trigger this before sendAllFlowTablesStatisticsRequest()
+        //        comes back -- we do not have any tables anyway.
+        final Collection<TableKey> tables = flowTableStats.getTables();
+        logger.debug("Node {} supports {} table(s)", this.getNodeRef(), tables.size());
+        for (final TableKey key : tables) {
+            logger.debug("Send aggregate stats request for flow table {} to node {}", key.getId(), this.getNodeRef());
+            this.requestAggregateFlows(key);
+        }
+
+        this.requestAllFlowsAllTables();
+        
+    }
     public void requestAllFlowsAllTables() {
         if (flowStatsService != null) {
             final GetAllFlowsStatisticsFromAllFlowTablesInputBuilder input = new GetAllFlowsStatisticsFromAllFlowTablesInputBuilder();
index 3fe68c111a1549bc6c9df7b9b19803590ffad94b..a160f6d467ca6731a8c4d485250d6697cec8b97e 100644 (file)
@@ -30,8 +30,8 @@ final class FlowTableStatsTracker extends AbstractStatsTracker<FlowTableAndStati
     private final Set<TableKey> tables = Collections.unmodifiableSet(privateTables);
     private final OpendaylightFlowTableStatisticsService flowTableStatsService;
 
-    FlowTableStatsTracker(OpendaylightFlowTableStatisticsService flowTableStatsService, final FlowCapableContext context, long lifetimeNanos) {
-        super(context, lifetimeNanos);
+    FlowTableStatsTracker(OpendaylightFlowTableStatisticsService flowTableStatsService, final FlowCapableContext context) {
+        super(context);
         this.flowTableStatsService = flowTableStatsService;
     }
 
@@ -61,6 +61,7 @@ final class FlowTableStatsTracker extends AbstractStatsTracker<FlowTableAndStati
         return item;
     }
 
+    @Override
     public void request() {
         if (flowTableStatsService != null) {
             final GetFlowTablesStatisticsInputBuilder input = new GetFlowTablesStatisticsInputBuilder();
index 8aebd6b2491a00ce27bfb8e1093517029ea87cf3..e180aaf5fc94de8b609bcab6803843c36da2fac5 100644 (file)
@@ -29,8 +29,8 @@ final class GroupDescStatsTracker extends AbstractListeningStatsTracker<GroupDes
     private static final Logger logger = LoggerFactory.getLogger(GroupDescStatsTracker.class);
     private final OpendaylightGroupStatisticsService groupStatsService;
 
-    public GroupDescStatsTracker(OpendaylightGroupStatisticsService groupStatsService, final FlowCapableContext context, final long lifetimeNanos) {
-        super(context, lifetimeNanos);
+    public GroupDescStatsTracker(OpendaylightGroupStatisticsService groupStatsService, final FlowCapableContext context) {
+        super(context);
         this.groupStatsService = groupStatsService;
     }
 
@@ -70,6 +70,7 @@ final class GroupDescStatsTracker extends AbstractListeningStatsTracker<GroupDes
         return "Group Descriptor";
     }
 
+    @Override
     public void request() {
         if (groupStatsService != null) {
             final GetGroupDescriptionInputBuilder input = new GetGroupDescriptionInputBuilder();
index 1af8e4e9f1a2cf891795d06f967ca0b12307c730..9735fea069325d7f12a87e02563a9afb24205ccf 100644 (file)
@@ -31,8 +31,8 @@ final class GroupStatsTracker extends AbstractListeningStatsTracker<GroupStats,
     private static final Logger logger = LoggerFactory.getLogger(GroupStatsTracker.class);
     private final OpendaylightGroupStatisticsService groupStatsService;
 
-    GroupStatsTracker(OpendaylightGroupStatisticsService groupStatsService, FlowCapableContext context, long lifetimeNanos) {
-        super(context, lifetimeNanos);
+    GroupStatsTracker(OpendaylightGroupStatisticsService groupStatsService, FlowCapableContext context) {
+        super(context);
         this.groupStatsService = Preconditions.checkNotNull(groupStatsService);
     }
 
@@ -72,6 +72,7 @@ final class GroupStatsTracker extends AbstractListeningStatsTracker<GroupStats,
         return "Group";
     }
 
+    @Override
     public void request() {
         final GetAllGroupStatisticsInputBuilder input = new GetAllGroupStatisticsInputBuilder();
         input.setNode(getNodeRef());
index 4b9592570565fc94d423702a7cff9923d110895f..e8b7fb7164d6d749a4b2427bc9ce591f4f0a5b54 100644 (file)
@@ -29,8 +29,8 @@ final class MeterConfigStatsTracker extends AbstractListeningStatsTracker<MeterC
     private static final Logger logger = LoggerFactory.getLogger(MeterConfigStatsTracker.class);
     private final OpendaylightMeterStatisticsService meterStatsService;
 
-    protected MeterConfigStatsTracker(OpendaylightMeterStatisticsService meterStatsService, final FlowCapableContext context, long lifetimeNanos) {
-        super(context, lifetimeNanos);
+    protected MeterConfigStatsTracker(OpendaylightMeterStatisticsService meterStatsService, final FlowCapableContext context) {
+        super(context);
         this.meterStatsService = meterStatsService;
     }
 
@@ -62,6 +62,7 @@ final class MeterConfigStatsTracker extends AbstractListeningStatsTracker<MeterC
         return item;
     }
 
+    @Override
     public void request() {
         if (meterStatsService != null) {
             GetAllMeterConfigStatisticsInputBuilder input = new GetAllMeterConfigStatisticsInputBuilder();
index 091cbcc1a078f88d54cde3eaa9300da97aaed8c2..b373020f1ca26cbd2e08faa7b033c65731344764 100644 (file)
@@ -29,8 +29,8 @@ final class MeterStatsTracker extends AbstractListeningStatsTracker<MeterStats,
     private static final Logger logger = LoggerFactory.getLogger(MeterStatsTracker.class);
     private final OpendaylightMeterStatisticsService meterStatsService;
 
-    MeterStatsTracker(OpendaylightMeterStatisticsService meterStatsService, final FlowCapableContext context, long lifetimeNanos) {
-        super(context, lifetimeNanos);
+    MeterStatsTracker(OpendaylightMeterStatisticsService meterStatsService, final FlowCapableContext context) {
+        super(context);
         this.meterStatsService = meterStatsService;
     }
 
@@ -61,6 +61,7 @@ final class MeterStatsTracker extends AbstractListeningStatsTracker<MeterStats,
         return item;
     }
 
+    @Override
     public void request() {
         if (meterStatsService != null) {
             GetAllMeterStatisticsInputBuilder input = new GetAllMeterStatisticsInputBuilder();
index 00bd27402fc3c45c82f0f9d06c8a5a562ea76a97..701911d9a2c307c03ecd48c75bfcd4099ba2490f 100644 (file)
@@ -25,8 +25,8 @@ final class NodeConnectorStatsTracker extends AbstractStatsTracker<NodeConnector
     private static final Logger logger = LoggerFactory.getLogger(NodeConnectorStatsTracker.class);
     private final OpendaylightPortStatisticsService portStatsService;
 
-    NodeConnectorStatsTracker(final OpendaylightPortStatisticsService portStatsService, final FlowCapableContext context, long lifetimeNanos) {
-        super(context, lifetimeNanos);
+    NodeConnectorStatsTracker(final OpendaylightPortStatisticsService portStatsService, final FlowCapableContext context) {
+        super(context);
         this.portStatsService = portStatsService;
     }
 
@@ -73,6 +73,7 @@ final class NodeConnectorStatsTracker extends AbstractStatsTracker<NodeConnector
         return item;
     }
 
+    @Override
     public void request() {
         if (portStatsService != null) {
             final GetAllNodeConnectorsStatisticsInputBuilder input = new GetAllNodeConnectorsStatisticsInputBuilder();
index 5ace260251673bb9fa42b9da14a95a5ece724b4c..dbcbab982a9aec997e37a2fb09e763bb3f3c5f96 100644 (file)
@@ -7,7 +7,6 @@
  */
 package org.opendaylight.controller.md.statistics.manager;
 
-import java.util.Collection;
 import java.util.List;
 import java.util.Timer;
 import java.util.TimerTask;
@@ -73,6 +72,7 @@ public final class NodeStatisticsHandler implements AutoCloseable, FlowCapableCo
     private static final int NUMBER_OF_WAIT_CYCLES = 2;
 
     private final MultipartMessageManager msgManager;
+    private final StatisticsRequestScheduler srScheduler;
     private final InstanceIdentifier<Node> targetNodeIdentifier;
     private final FlowStatsTracker flowStats;
     private final FlowTableStatsTracker flowTableStats;
@@ -103,23 +103,25 @@ public final class NodeStatisticsHandler implements AutoCloseable, FlowCapableCo
             final OpendaylightGroupStatisticsService groupStatsService,
             final OpendaylightMeterStatisticsService meterStatsService,
             final OpendaylightPortStatisticsService portStatsService,
-            final OpendaylightQueueStatisticsService queueStatsService) {
+            final OpendaylightQueueStatisticsService queueStatsService, 
+            final StatisticsRequestScheduler srScheduler) {
         this.dps = Preconditions.checkNotNull(dps);
         this.targetNodeKey = Preconditions.checkNotNull(nodeKey);
+        this.srScheduler = Preconditions.checkNotNull(srScheduler);
         this.targetNodeIdentifier = InstanceIdentifier.builder(Nodes.class).child(Node.class, targetNodeKey).build();
         this.targetNodeRef = new NodeRef(targetNodeIdentifier);
 
         final long lifetimeNanos = TimeUnit.MILLISECONDS.toNanos(STATS_COLLECTION_MILLIS * NUMBER_OF_WAIT_CYCLES);
 
         msgManager = new MultipartMessageManager(lifetimeNanos);
-        flowStats = new FlowStatsTracker(flowStatsService, this, lifetimeNanos);
-        flowTableStats = new FlowTableStatsTracker(flowTableStatsService, this, lifetimeNanos);
-        groupDescStats = new GroupDescStatsTracker(groupStatsService, this, lifetimeNanos);
-        groupStats = new GroupStatsTracker(groupStatsService, this, lifetimeNanos);
-        meterConfigStats = new MeterConfigStatsTracker(meterStatsService, this, lifetimeNanos);
-        meterStats = new MeterStatsTracker(meterStatsService, this, lifetimeNanos);
-        nodeConnectorStats = new NodeConnectorStatsTracker(portStatsService, this, lifetimeNanos);
-        queueStats = new QueueStatsTracker(queueStatsService, this, lifetimeNanos);
+        flowTableStats = new FlowTableStatsTracker(flowTableStatsService, this);
+        flowStats = new FlowStatsTracker(flowStatsService, this, flowTableStats);
+        groupDescStats = new GroupDescStatsTracker(groupStatsService, this);
+        groupStats = new GroupStatsTracker(groupStatsService, this);
+        meterConfigStats = new MeterConfigStatsTracker(meterStatsService, this);
+        meterStats = new MeterStatsTracker(meterStatsService, this);
+        nodeConnectorStats = new NodeConnectorStatsTracker(portStatsService, this);
+        queueStats = new QueueStatsTracker(queueStatsService, this);
     }
 
     public NodeKey getTargetNodeKey() {
@@ -138,7 +140,9 @@ public final class NodeStatisticsHandler implements AutoCloseable, FlowCapableCo
 
     @Override
     public DataModificationTransaction startDataModification() {
-        return dps.beginTransaction();
+        DataModificationTransaction dmt = dps.beginTransaction();
+        dmt.registerListener(this.srScheduler);
+        return dmt;
     }
 
     public synchronized void updateGroupDescStats(TransactionAware transaction, List<GroupDescStats> list) {
@@ -186,7 +190,7 @@ public final class NodeStatisticsHandler implements AutoCloseable, FlowCapableCo
     public synchronized void updateAggregateFlowStats(TransactionAware transaction, AggregateFlowStatistics flowStats) {
         final Short tableId = msgManager.isExpectedTableTransaction(transaction);
         if (tableId != null) {
-            final DataModificationTransaction trans = dps.beginTransaction();
+            final DataModificationTransaction trans = this.startDataModification();
             InstanceIdentifier<Table> tableRef = InstanceIdentifier.builder(Nodes.class).child(Node.class, targetNodeKey)
                     .augmentation(FlowCapableNode.class).child(Table.class, new TableKey(tableId)).toInstance();
 
@@ -214,7 +218,7 @@ public final class NodeStatisticsHandler implements AutoCloseable, FlowCapableCo
     }
 
     public synchronized void updateGroupFeatures(GroupFeatures notification) {
-        final DataModificationTransaction trans = dps.beginTransaction();
+        final DataModificationTransaction trans = this.startDataModification();
 
         final NodeBuilder nodeData = new NodeBuilder();
         nodeData.setKey(targetNodeKey);
@@ -232,7 +236,7 @@ public final class NodeStatisticsHandler implements AutoCloseable, FlowCapableCo
     }
 
     public synchronized void updateMeterFeatures(MeterFeatures features) {
-        final DataModificationTransaction trans = dps.beginTransaction();
+        final DataModificationTransaction trans = this.startDataModification();
 
         final NodeBuilder nodeData = new NodeBuilder();
         nodeData.setKey(targetNodeKey);
@@ -250,16 +254,15 @@ public final class NodeStatisticsHandler implements AutoCloseable, FlowCapableCo
     }
 
     public synchronized void cleanStaleStatistics() {
-        final DataModificationTransaction trans = dps.beginTransaction();
-        final long now = System.nanoTime();
-
-        flowStats.cleanup(trans, now);
-        groupDescStats.cleanup(trans, now);
-        groupStats.cleanup(trans, now);
-        meterConfigStats.cleanup(trans, now);
-        meterStats.cleanup(trans, now);
-        nodeConnectorStats.cleanup(trans, now);
-        queueStats.cleanup(trans, now);
+        final DataModificationTransaction trans = this.startDataModification();
+
+        flowStats.cleanup(trans);
+        groupDescStats.cleanup(trans);
+        groupStats.cleanup(trans);
+        meterConfigStats.cleanup(trans);
+        meterStats.cleanup(trans);
+        nodeConnectorStats.cleanup(trans);
+        queueStats.cleanup(trans);
         msgManager.cleanStaleTransactionIds();
 
         trans.commit();
@@ -268,26 +271,23 @@ public final class NodeStatisticsHandler implements AutoCloseable, FlowCapableCo
     public synchronized void requestPeriodicStatistics() {
         logger.debug("Send requests for statistics collection to node : {}", targetNodeKey);
 
-        flowTableStats.request();
-
-        // FIXME: it does not make sense to trigger this before sendAllFlowTablesStatisticsRequest()
-        //        comes back -- we do not have any tables anyway.
-        final Collection<TableKey> tables = flowTableStats.getTables();
-        logger.debug("Node {} supports {} table(s)", targetNodeKey, tables.size());
-        for (final TableKey key : tables) {
-            logger.debug("Send aggregate stats request for flow table {} to node {}", key.getId(), targetNodeKey);
-            flowStats.requestAggregateFlows(key);
-        }
-
-        flowStats.requestAllFlowsAllTables();
-        nodeConnectorStats.request();
-        groupStats.request();
-        groupDescStats.request();
-        meterStats.request();
-        meterConfigStats.request();
-        queueStats.request();
+        this.srScheduler.addRequestToSchedulerQueue(flowTableStats);
+
+        this.srScheduler.addRequestToSchedulerQueue(flowStats);
+        
+        this.srScheduler.addRequestToSchedulerQueue(nodeConnectorStats);
+        
+        this.srScheduler.addRequestToSchedulerQueue(groupStats);
+        
+        this.srScheduler.addRequestToSchedulerQueue(groupDescStats);
+        
+        this.srScheduler.addRequestToSchedulerQueue(meterStats);
+        
+        this.srScheduler.addRequestToSchedulerQueue(meterConfigStats);
+        
+        this.srScheduler.addRequestToSchedulerQueue(queueStats);
     }
-
+    
     public synchronized void start(final Timer timer) {
         flowStats.start(dps);
         groupDescStats.start(dps);
index f187c7082e6e3b2093e2e0b0654a406dd9315950..6f93eeb6172dcdaf24db8301214abe12d92857e0 100644 (file)
@@ -36,8 +36,8 @@ final class QueueStatsTracker extends AbstractListeningStatsTracker<QueueIdAndSt
     private static final Logger logger = LoggerFactory.getLogger(QueueStatsTracker.class);
     private final OpendaylightQueueStatisticsService queueStatsService;
 
-    QueueStatsTracker(OpendaylightQueueStatisticsService queueStatsService, final FlowCapableContext context, long lifetimeNanos) {
-        super(context, lifetimeNanos);
+    QueueStatsTracker(OpendaylightQueueStatisticsService queueStatsService, final FlowCapableContext context) {
+        super(context);
         this.queueStatsService = queueStatsService;
     }
 
@@ -82,6 +82,7 @@ final class QueueStatsTracker extends AbstractListeningStatsTracker<QueueIdAndSt
         return queueEntry;
     }
 
+    @Override
     public void request() {
         if (queueStatsService != null) {
             GetAllQueuesStatisticsFromAllPortsInputBuilder input = new GetAllQueuesStatisticsFromAllPortsInputBuilder();
index 892d304daa8d6cd20c7010082f2698cb8de90266..d8bea7c63a4606fffaed51a9dce5fe889dca2d36 100644 (file)
@@ -66,9 +66,12 @@ public class StatisticsProvider implements AutoCloseable {
     private OpendaylightFlowTableStatisticsService flowTableStatsService;
 
     private OpendaylightQueueStatisticsService queueStatsService;
+    
+    private final StatisticsRequestScheduler srScheduler;
 
     public StatisticsProvider(final DataProviderService dataService) {
         this.dps = Preconditions.checkNotNull(dataService);
+        this.srScheduler = new StatisticsRequestScheduler();
     }
 
     private final StatisticsListener updateCommiter = new StatisticsListener(StatisticsProvider.this);
@@ -86,7 +89,8 @@ public class StatisticsProvider implements AutoCloseable {
         portStatsService = rpcRegistry.getRpcService(OpendaylightPortStatisticsService.class);
         flowTableStatsService = rpcRegistry.getRpcService(OpendaylightFlowTableStatisticsService.class);
         queueStatsService = rpcRegistry.getRpcService(OpendaylightQueueStatisticsService.class);
-
+        this.srScheduler.start();
+        
         // Start receiving notifications
         this.listenerRegistration = nps.registerNotificationListener(this.updateCommiter);
 
@@ -144,7 +148,7 @@ public class StatisticsProvider implements AutoCloseable {
 
             final NodeStatisticsHandler h = new NodeStatisticsHandler(dps, key,
                     flowStatsService, flowTableStatsService, groupStatsService,
-                    meterStatsService, portStatsService, queueStatsService);
+                    meterStatsService, portStatsService, queueStatsService,srScheduler);
             final NodeStatisticsHandler old = handlers.putIfAbsent(key.getId(), h);
             if (old == null) {
                 spLogger.debug("Started node handler for {}", key.getId());
diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsRequestScheduler.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsRequestScheduler.java
new file mode 100644 (file)
index 0000000..9ebfd6f
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * Copyright IBM Corporation, 2013.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.statistics.manager;
+
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.concurrent.TimeUnit;
+
+import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
+import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
+import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction.DataTransactionListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Main responsibility of the class is to check the MD-SAL data store read/write
+ * transaction accumulation level and send statistics request if number of pending 
+ * read/write transactions are zero.
+ * @author avishnoi@in.ibm.com
+ *
+ */
+@SuppressWarnings("rawtypes")
+public class StatisticsRequestScheduler implements DataTransactionListener {
+
+    private static final Logger srsLogger = LoggerFactory.getLogger(StatisticsRequestScheduler.class);
+    private final Timer timer = new Timer("request-monitor", true);
+
+    // We need ordered retrieval, and O(1) contains operation
+    private final Map<AbstractStatsTracker,Integer> requestQueue = 
+            Collections.synchronizedMap(new LinkedHashMap<AbstractStatsTracker,Integer>());
+    
+    private Long PendingTransactions;
+    
+    private long lastRequestTime = System.nanoTime();
+    
+    private static final long REQUEST_MONITOR_INTERVAL = 1000;
+    
+    private final TimerTask task = new TimerTask() {
+        @Override
+        public void run() {
+            long now = System.nanoTime();
+            if(now > lastRequestTime+TimeUnit.MILLISECONDS.toNanos(REQUEST_MONITOR_INTERVAL)){
+                requestStatistics();
+            }
+        }
+    };
+
+    public StatisticsRequestScheduler(){
+        PendingTransactions = (long) 0;
+    }
+    
+    public void addRequestToSchedulerQueue(AbstractStatsTracker statsRequest){
+        requestQueue.put(statsRequest, null);
+    }
+    
+    public AbstractStatsTracker getNextRequestFromSchedulerQueue(){
+        //Remove first element
+        AbstractStatsTracker stats = null;
+        synchronized(requestQueue){
+            Iterator<Map.Entry<AbstractStatsTracker, Integer>> nodesItr = requestQueue.entrySet().iterator();
+            if(nodesItr.hasNext()){
+                stats = nodesItr.next().getKey();
+                srsLogger.debug("{} chosen up for execution",stats.getNodeRef());
+                nodesItr.remove();
+                return stats;
+            }
+        }
+        return stats;
+    }
+
+    private void requestStatistics(){
+        AbstractStatsTracker stats = this.getNextRequestFromSchedulerQueue();
+        if(stats != null) {
+            stats.request();
+            stats.increaseRequestCounter();
+        }
+    }
+    @Override
+    public void onStatusUpdated(DataModificationTransaction transaction, TransactionStatus status) {
+        
+        AbstractStatsTracker stats = null;
+        synchronized(PendingTransactions){
+            switch(status){
+            case SUBMITED:
+                this.PendingTransactions++;
+                break;
+            case COMMITED:
+            case FAILED:
+                this.PendingTransactions--;
+                if(PendingTransactions == 0){
+                    lastRequestTime = System.nanoTime();
+                    stats = this.getNextRequestFromSchedulerQueue();
+                }
+                srsLogger.debug("Pending MD-SAL transactions : {} & Scheduler queue size : {}",this.PendingTransactions,this.requestQueue.size());
+                break;
+            default:
+                break;
+            }
+        }
+        if(stats != null){
+            stats.request();
+            stats.increaseRequestCounter();
+        }
+    }
+    
+    public void start(){
+        timer.schedule(task, 0, REQUEST_MONITOR_INTERVAL);
+    }
+}
index 2d003f8079f9296db0b9a45b2bb09582c5e73aa2..a51f6c2f9f0eb6669ace2e8febe1404f8189df51 100644 (file)
       <groupId>equinoxSDK381</groupId>
       <artifactId>org.eclipse.osgi</artifactId>
     </dependency>
-    <dependency>
-      <groupId>org.eclipse.xtend</groupId>
-      <artifactId>org.eclipse.xtend.lib</artifactId>
-    </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
           <manifestLocation>${project.basedir}/META-INF</manifestLocation>
         </configuration>
       </plugin>
-      <plugin>
-        <groupId>org.eclipse.xtend</groupId>
-        <artifactId>xtend-maven-plugin</artifactId>
-      </plugin>
     </plugins>
   </build>
   <scm>
diff --git a/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPActivator.java b/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPActivator.java
new file mode 100644 (file)
index 0000000..0e003db
--- /dev/null
@@ -0,0 +1,30 @@
+/**
+ * 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.md.controller.topology.lldp;
+
+import org.opendaylight.controller.sal.binding.api.AbstractBindingAwareProvider;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.osgi.framework.BundleContext;
+
+public class LLDPActivator extends AbstractBindingAwareProvider {
+    private static LLDPDiscoveryProvider provider = new LLDPDiscoveryProvider();
+
+    public void onSessionInitiated(final ProviderContext session) {
+        DataProviderService dataService = session.<DataProviderService>getSALService(DataProviderService.class);
+        provider.setDataService(dataService);
+        NotificationProviderService notificationService = session.<NotificationProviderService>getSALService(NotificationProviderService.class);
+        provider.setNotificationService(notificationService);
+        provider.start();
+    }
+
+    protected void stopImpl(final BundleContext context) {
+        provider.close();
+    }
+}
diff --git a/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPActivator.xtend b/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPActivator.xtend
deleted file mode 100644 (file)
index 674e919..0000000
+++ /dev/null
@@ -1,30 +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.md.controller.topology.lldp
-
-import org.opendaylight.controller.sal.binding.api.AbstractBindingAwareProvider
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext
-import org.opendaylight.controller.sal.binding.api.NotificationProviderService
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService
-import org.osgi.framework.BundleContext
-
-class LLDPActivator extends AbstractBindingAwareProvider {
-
-    static var LLDPDiscoveryProvider provider = new LLDPDiscoveryProvider();
-
-    override onSessionInitiated(ProviderContext session) {
-        provider.dataService = session.getSALService(DataProviderService)
-        provider.notificationService = session.getSALService(NotificationProviderService)
-        provider.start();
-    }
-
-    override protected stopImpl(BundleContext context) {
-        provider.close();
-    }
-
-}
diff --git a/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPDiscoveryProvider.java b/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPDiscoveryProvider.java
new file mode 100644 (file)
index 0000000..b219722
--- /dev/null
@@ -0,0 +1,58 @@
+/**
+ * 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.md.controller.topology.lldp;
+
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.yangtools.concepts.Registration;
+import org.opendaylight.yangtools.yang.binding.NotificationListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class LLDPDiscoveryProvider implements AutoCloseable {
+    private final static Logger LOG =  LoggerFactory.getLogger(LLDPDiscoveryProvider.class);
+    private DataProviderService dataService;
+    private NotificationProviderService notificationService;
+    private final LLDPDiscoveryListener commiter = new LLDPDiscoveryListener(LLDPDiscoveryProvider.this);
+    private Registration<NotificationListener> listenerRegistration;
+
+    public DataProviderService getDataService() {
+        return this.dataService;
+    }
+
+    public void setDataService(final DataProviderService dataService) {
+        this.dataService = dataService;
+    }
+
+    public NotificationProviderService getNotificationService() {
+        return this.notificationService;
+    }
+
+    public void setNotificationService(final NotificationProviderService notificationService) {
+        this.notificationService = notificationService;
+    }
+
+    public void start() {
+        Registration<NotificationListener> registerNotificationListener = this.getNotificationService().registerNotificationListener(this.commiter);
+        this.listenerRegistration = registerNotificationListener;
+        LLDPLinkAger.getInstance().setManager(this);
+        LOG.info("LLDPDiscoveryListener Started.");
+    }
+
+    public void close() {
+        try {
+            LOG.info("LLDPDiscoveryListener stopped.");
+            if (this.listenerRegistration!=null) {
+                this.listenerRegistration.close();
+            }
+            LLDPLinkAger.getInstance().close();
+        } catch (Exception e) {
+            throw new Error(e);
+        }
+    }
+}
diff --git a/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPDiscoveryProvider.xtend b/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPDiscoveryProvider.xtend
deleted file mode 100644 (file)
index fc724ac..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- * 
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.md.controller.topology.lldp
-
-import org.opendaylight.controller.sal.binding.api.NotificationProviderService
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService
-import org.opendaylight.yangtools.concepts.Registration
-import org.opendaylight.yangtools.yang.binding.NotificationListener
-import org.slf4j.LoggerFactory
-
-class LLDPDiscoveryProvider implements AutoCloseable {
-
-
-    static val LOG = LoggerFactory.getLogger(LLDPDiscoveryProvider);
-
-    @Property
-    DataProviderService dataService;        
-
-    @Property
-    NotificationProviderService notificationService;
-
-    val LLDPDiscoveryListener commiter = new LLDPDiscoveryListener(this);
-
-    Registration<NotificationListener> listenerRegistration
-
-    def void start() {
-        listenerRegistration = notificationService.registerNotificationListener(commiter);
-        LLDPLinkAger.instance.manager = this;
-        LOG.info("LLDPDiscoveryListener Started.");
-        
-    }   
-    
-    override close() {
-       LOG.info("LLDPDiscoveryListener stopped.");
-        listenerRegistration?.close();
-        LLDPLinkAger.instance.close();
-    }
-    
-}
-
-
index 54d24a4cec3823c0a07e1bfaf5e36b2c69815d0d..c08be06c9f619bfc48ff144f523f64535cb8a605 100644 (file)
@@ -23,7 +23,7 @@ import org.opendaylight.yangtools.yang.model.api.type.BinaryTypeDefinition;
 
 public abstract class AttributeIfcSwitchStatement<T> {
 
-    protected AttributeIfc lastAttribute;
+    private AttributeIfc lastAttribute;
 
     public T switchAttribute(AttributeIfc attributeIfc) {
 
@@ -39,8 +39,9 @@ public abstract class AttributeIfcSwitchStatement<T> {
                     return caseJavaUnionAttribute(openType);
                 } else if(((JavaAttribute)attributeIfc).isIdentityRef()) {
                     return caseJavaIdentityRefAttribute(openType);
-                } else
+                } else {
                     return caseJavaAttribute(openType);
+                }
             } catch (UnknownOpenTypeException e) {
                 throw getIllegalArgumentException(attributeIfc);
             }
@@ -58,6 +59,10 @@ public abstract class AttributeIfcSwitchStatement<T> {
         throw getIllegalArgumentException(attributeIfc);
     }
 
+    public AttributeIfc getLastAttribute() {
+        return lastAttribute;
+    }
+
     protected T caseJavaIdentityRefAttribute(OpenType<?> openType) {
         return caseJavaAttribute(openType);
     }
index dbc1b48d4f9abebe5fc89c306f65b68fcee924d2..dcc2fa15439b01ecd15eca5144f15eaa3a77086b 100644 (file)
@@ -9,6 +9,7 @@
 package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml;
 
 import com.google.common.base.Optional;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.resolving.AttributeResolvingStrategy;
 
 import javax.management.openmbean.OpenType;
@@ -39,7 +40,7 @@ public class AttributeConfigElement {
     }
 
     public void resolveValue(AttributeResolvingStrategy<?, ? extends OpenType<?>> attributeResolvingStrategy,
-            String attrName) {
+            String attrName) throws NetconfDocumentedException {
         resolvedValue = attributeResolvingStrategy.parseAttribute(attrName, value);
         Optional<?> resolvedDefault = attributeResolvingStrategy.parseAttribute(attrName, dafaultValue);
         resolvedDefaultValue = resolvedDefault.isPresent() ? resolvedDefault.get() : null;
index 5f44c16dcaefb754f7732143c41f59968cea9fda..bf9eee7f267fd5ded0f73f431443eecb9fa76183 100644 (file)
@@ -55,7 +55,7 @@ public class ObjectNameAttributeReadingStrategy extends AbstractAttributeReading
     public static String checkPrefixAndExtractServiceName(XmlElement typeElement, Map.Entry<String, String> prefixNamespace) throws NetconfDocumentedException {
         String serviceName = typeElement.getTextContent();
 
-        Preconditions.checkState(prefixNamespace.equals("") == false, "Service %s value not prefixed with namespace",
+        Preconditions.checkState(!prefixNamespace.equals(""), "Service %s value not prefixed with namespace",
                 XmlNetconfConstants.TYPE_KEY);
         String prefix = prefixNamespace.getKey() + PREFIX_SEPARATOR;
         Preconditions.checkState(serviceName.startsWith(prefix),
index 61db74feb570bc1f0c20e3ee24a938cce0d849ea..61ea76bbfeb9504f456132ba7cfebd67bcc6e508 100644 (file)
@@ -50,31 +50,31 @@ public class ObjectXmlReader extends AttributeIfcSwitchStatement<AttributeReadin
 
     @Override
     protected AttributeReadingStrategy caseJavaBinaryAttribute(OpenType<?> openType) {
-        return new SimpleBinaryAttributeReadingStrategy(lastAttribute.getNullableDefault());
+        return new SimpleBinaryAttributeReadingStrategy(getLastAttribute().getNullableDefault());
     }
 
     @Override
     protected AttributeReadingStrategy caseJavaUnionAttribute(OpenType<?> openType) {
         String mappingKey = JavaAttribute.DESCRIPTION_OF_VALUE_ATTRIBUTE_FOR_UNION;
-        return new SimpleUnionAttributeReadingStrategy(lastAttribute.getNullableDefault(), mappingKey);
+        return new SimpleUnionAttributeReadingStrategy(getLastAttribute().getNullableDefault(), mappingKey);
     }
 
     @Override
     public AttributeReadingStrategy caseJavaSimpleAttribute(SimpleType<?> openType) {
-        return new SimpleAttributeReadingStrategy(lastAttribute.getNullableDefault());
+        return new SimpleAttributeReadingStrategy(getLastAttribute().getNullableDefault());
     }
 
     @Override
     public AttributeReadingStrategy caseJavaArrayAttribute(ArrayType<?> openType) {
-        SimpleAttributeReadingStrategy innerStrategy = new SimpleAttributeReadingStrategy(lastAttribute.getNullableDefault());
-        return new ArrayAttributeReadingStrategy(lastAttribute.getNullableDefault(), innerStrategy);
+        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(lastAttribute.getNullableDefault(), mappingKey);
+        return new SimpleCompositeAttributeReadingStrategy(getLastAttribute().getNullableDefault(), mappingKey);
     }
 
     @Override
@@ -83,18 +83,18 @@ public class ObjectXmlReader extends AttributeIfcSwitchStatement<AttributeReadin
         Set<String> keys = ((CompositeType) openType).keySet();
         Preconditions.checkState(keys.size() == 1, "Unexpected number of elements for open type %s, should be 1", openType);
         String mappingKey = keys.iterator().next();
-        return new SimpleIdentityRefAttributeReadingStrategy(lastAttribute.getNullableDefault(), mappingKey, identityMap);
+        return new SimpleIdentityRefAttributeReadingStrategy(getLastAttribute().getNullableDefault(), mappingKey, identityMap);
     }
 
     @Override
     protected AttributeReadingStrategy caseDependencyAttribute(SimpleType<?> openType) {
-        return new ObjectNameAttributeReadingStrategy(lastAttribute.getNullableDefault());
+        return new ObjectNameAttributeReadingStrategy(getLastAttribute().getNullableDefault());
     }
 
     @Override
     protected AttributeReadingStrategy caseTOAttribute(CompositeType openType) {
-        Preconditions.checkState(lastAttribute instanceof TOAttribute);
-        Map<String, AttributeIfc> inner = ((TOAttribute)lastAttribute).getYangPropertiesToTypesMap();
+        Preconditions.checkState(getLastAttribute() instanceof TOAttribute);
+        Map<String, AttributeIfc> inner = ((TOAttribute)getLastAttribute()).getYangPropertiesToTypesMap();
 
         Map<String, AttributeReadingStrategy> innerStrategies = Maps.newHashMap();
 
@@ -104,21 +104,21 @@ public class ObjectXmlReader extends AttributeIfcSwitchStatement<AttributeReadin
             innerStrategies.put(innerAttrEntry.getKey(), innerStrat);
         }
 
-        return new CompositeAttributeReadingStrategy(lastAttribute.getNullableDefault(), innerStrategies);
+        return new CompositeAttributeReadingStrategy(getLastAttribute().getNullableDefault(), innerStrategies);
     }
 
     @Override
     protected AttributeReadingStrategy caseListAttribute(ArrayType<?> openType) {
-        Preconditions.checkState(lastAttribute instanceof ListAttribute);
-        AttributeReadingStrategy innerStrategy = prepareReadingStrategy(key, ((ListAttribute) lastAttribute).getInnerAttribute());
-        return new ArrayAttributeReadingStrategy(lastAttribute.getNullableDefault(), innerStrategy);
+        Preconditions.checkState(getLastAttribute() instanceof ListAttribute);
+        AttributeReadingStrategy innerStrategy = prepareReadingStrategy(key, ((ListAttribute) getLastAttribute()).getInnerAttribute());
+        return new ArrayAttributeReadingStrategy(getLastAttribute().getNullableDefault(), innerStrategy);
     }
 
     @Override
     protected AttributeReadingStrategy caseListDependeciesAttribute(ArrayType<?> openType) {
-        Preconditions.checkState(lastAttribute instanceof ListDependenciesAttribute);
+        Preconditions.checkState(getLastAttribute() instanceof ListDependenciesAttribute);
         AttributeReadingStrategy innerStrategy = caseDependencyAttribute(SimpleType.OBJECTNAME);
-        return new ArrayAttributeReadingStrategy(lastAttribute.getNullableDefault(), innerStrategy);
+        return new ArrayAttributeReadingStrategy(getLastAttribute().getNullableDefault(), innerStrategy);
     }
 
 }
index 58f91a7deec8c9ce7522f426bb4428b2dee3d691..8e7ba708c6cea71ba46400f99fb765a2113bf762 100644 (file)
@@ -54,9 +54,9 @@ public class SimpleIdentityRefAttributeReadingStrategy extends SimpleAttributeRe
                     revision = date;
                 }
             }
-        } else
+        } else {
             revision = revisions.keySet().iterator().next();
-
+        }
 
         return QName.create(URI.create(namespace), revision, localName).toString();
     }
index 30436bb42f077c72de371e45fc5453849a40f9bc..54ffe08cfbd455f19e2d8996588e19ce7e706cc0 100644 (file)
@@ -30,8 +30,9 @@ public class ArrayAttributeMappingStrategy extends AbstractAttributeMappingStrat
 
     @Override
     public Optional<List<Object>> mapAttribute(Object value) {
-        if (value == null)
+        if (value == null){
             return Optional.absent();
+        }
 
         Preconditions.checkArgument(value.getClass().isArray(), "Value has to be instanceof Array ");
 
@@ -39,19 +40,11 @@ public class ArrayAttributeMappingStrategy extends AbstractAttributeMappingStrat
 
         for (int i = 0; i < Array.getLength(value); i++) {
             Object innerValue = Array.get(value, i);
-            // String expectedClassName =
-            // getOpenType().getElementOpenType().getClassName();
-            // String realClassName = value.getClass().getName();
-
-            // Preconditions.checkState(realClassName.contains(expectedClassName),
-            // "Element in collection/array should be of type " +
-            // expectedClassName + " but was "
-            // + realClassName + " for attribute: " + getOpenType());
-
             Optional<?> mapAttribute = innerElementStrategy.mapAttribute(innerValue);
 
-            if (mapAttribute.isPresent())
+            if (mapAttribute.isPresent()){
                 retVal.add(mapAttribute.get());
+            }
         }
 
         return Optional.of(retVal);
index 368e1f12a642e54dc90ac8231818619a0de96815..594953e569e6c0c2c5531a8100e5e7f106f2d114 100644 (file)
@@ -35,8 +35,9 @@ public class CompositeAttributeMappingStrategy extends
 
     @Override
     public Optional<Map<String, Object>> mapAttribute(Object value) {
-        if (value == null)
+        if (value == null){
             return Optional.absent();
+        }
 
         Util.checkType(value, CompositeDataSupport.class);
 
@@ -54,8 +55,9 @@ public class CompositeAttributeMappingStrategy extends
 
         for (String jmxName : jmxToJavaNameMapping.keySet()) {
             Optional<?> mapped = mapInnerAttribute(compositeData, jmxName, expectedType.getDescription(jmxName));
-            if(mapped.isPresent())
+            if(mapped.isPresent()){
                 retVal.put(jmxToJavaNameMapping.get(jmxName), mapped.get());
+            }
         }
 
         return Optional.of(retVal);
@@ -66,8 +68,7 @@ public class CompositeAttributeMappingStrategy extends
 
         AttributeMappingStrategy<?, ? extends OpenType<?>> attributeMappingStrategy = innerStrategies
                 .get(jmxName);
-        Optional<?> mapAttribute = attributeMappingStrategy.mapAttribute(innerValue);
-        return mapAttribute;
+        return attributeMappingStrategy.mapAttribute(innerValue);
     }
 
 }
index 506d7d61c347016ef76a6601500ed773762dafb0..01844f27d4cb8609d8df9b4916f7fbe69a47eac2 100644 (file)
@@ -112,7 +112,7 @@ public class ObjectMapper extends AttributeIfcSwitchStatement<AttributeMappingSt
     @Override
     protected AttributeMappingStrategy<?, ? extends OpenType<?>> caseDependencyAttribute(
             SimpleType<?> openType) {
-        return new ObjectNameAttributeMappingStrategy(openType, dependencyTracker,
+        return new ObjectNameAttributeMappingStrategy(openType,
                 serviceNameOfDepAttr, namespaceOfDepAttr);
     }
 
@@ -120,10 +120,10 @@ public class ObjectMapper extends AttributeIfcSwitchStatement<AttributeMappingSt
     protected AttributeMappingStrategy<?, ? extends OpenType<?>> caseTOAttribute(CompositeType openType) {
         Map<String, AttributeMappingStrategy<?, ? extends OpenType<?>>> innerStrategies = Maps.newHashMap();
 
-        Preconditions.checkState(lastAttribute instanceof TOAttribute);
-        TOAttribute lastTO = (TOAttribute) lastAttribute;
+        Preconditions.checkState(getLastAttribute() instanceof TOAttribute);
+        TOAttribute lastTO = (TOAttribute) getLastAttribute();
 
-        for (Entry<String, AttributeIfc> innerAttrEntry : ((TOAttribute)lastAttribute).getJmxPropertiesToTypesMap().entrySet()) {
+        for (Entry<String, AttributeIfc> innerAttrEntry : ((TOAttribute)getLastAttribute()).getJmxPropertiesToTypesMap().entrySet()) {
             innerStrategies.put(innerAttrEntry.getKey(), prepareStrategy(innerAttrEntry.getValue()));
         }
 
@@ -133,14 +133,14 @@ public class ObjectMapper extends AttributeIfcSwitchStatement<AttributeMappingSt
 
     @Override
     protected AttributeMappingStrategy<?, ? extends OpenType<?>> caseListAttribute(ArrayType<?> openType) {
-        Preconditions.checkState(lastAttribute instanceof ListAttribute);
+        Preconditions.checkState(getLastAttribute() instanceof ListAttribute);
         return new ArrayAttributeMappingStrategy(openType,
-                prepareStrategy(((ListAttribute) lastAttribute).getInnerAttribute()));
+                prepareStrategy(((ListAttribute) getLastAttribute()).getInnerAttribute()));
     }
 
     @Override
     protected AttributeMappingStrategy<?, ? extends OpenType<?>> caseListDependeciesAttribute(ArrayType<?> openType) {
-        Preconditions.checkState(lastAttribute instanceof ListDependenciesAttribute);
+        Preconditions.checkState(getLastAttribute() instanceof ListDependenciesAttribute);
         return new ArrayAttributeMappingStrategy(openType, caseDependencyAttribute(SimpleType.OBJECTNAME));
     }
 
index 83e8086eef2507b648d918cf4592d9d7c553c1b6..b827a5b03965d7f7471731a646b80e44ee835266 100644 (file)
@@ -10,31 +10,28 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attri
 
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
-import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
-import org.opendaylight.controller.netconf.confignetconfconnector.util.Util;
-
 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;
 
 public class ObjectNameAttributeMappingStrategy extends
         AbstractAttributeMappingStrategy<ObjectNameAttributeMappingStrategy.MappedDependency, SimpleType<?>> {
 
-    private final ServiceRegistryWrapper tracker;
     private final String serviceName;
     private final String namespace;
 
-    public ObjectNameAttributeMappingStrategy(SimpleType<?> openType, ServiceRegistryWrapper dependencyTracker, String serviceName, String namespace) {
+    public ObjectNameAttributeMappingStrategy(SimpleType<?> openType,  String serviceName, String namespace) {
         super(openType);
-        this.tracker = dependencyTracker;
         this.serviceName = serviceName;
         this.namespace = namespace;
     }
 
     @Override
     public Optional<MappedDependency> mapAttribute(Object value) {
-        if (value == null)
+        if (value == null){
             return Optional.absent();
+        }
 
         String expectedClass = getOpenType().getClassName();
         String realClass = value.getClass().getName();
index d92b7c432df344ae989f3fff8acbe94876ea512f..7dbf4f41bc6fc16eecf5b92bde33130b8261e910 100644 (file)
@@ -25,8 +25,9 @@ public class SimpleAttributeMappingStrategy extends AbstractAttributeMappingStra
 
     @Override
     public Optional<String> mapAttribute(Object value) {
-        if (value == null)
+        if (value == null){
             return Optional.absent();
+        }
 
         String expectedClass = getOpenType().getClassName();
         String realClass = value.getClass().getName();
index 81a1e535989192474d34fa49fa0f99d07c71b2f4..1754fc7e0945d4f43b69d5280ce9791ae7c16c0f 100644 (file)
@@ -26,9 +26,9 @@ public class UnionCompositeAttributeMappingStrategy extends
 
     @Override
     protected Optional<?> mapInnerAttribute(CompositeDataSupport compositeData, String jmxName, String description) {
-        if(description.equals(JavaAttribute.DESCRIPTION_OF_VALUE_ATTRIBUTE_FOR_UNION) == false)
+        if(!description.equals(JavaAttribute.DESCRIPTION_OF_VALUE_ATTRIBUTE_FOR_UNION)){
             return Optional.absent();
-
+        }
         return super.mapInnerAttribute(compositeData, jmxName, description);
     }
 }
index adee8bec58086a02a92835deea84c578a8c94cd6..f0d7960085f21bd5e4a220797d648521c93f51d8 100644 (file)
@@ -9,6 +9,7 @@
 package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.resolving;
 
 import com.google.common.base.Optional;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
 import org.opendaylight.controller.netconf.confignetconfconnector.util.Util;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -33,7 +34,7 @@ final class ArrayAttributeResolvingStrategy extends AbstractAttributeResolvingSt
     }
 
     @Override
-    public Optional<Object> parseAttribute(String attrName, Object value) {
+    public Optional<Object> parseAttribute(String attrName, Object value) throws NetconfDocumentedException {
         if (value == null) {
             return Optional.absent();
         }
@@ -45,31 +46,31 @@ final class ArrayAttributeResolvingStrategy extends AbstractAttributeResolvingSt
 
         if (innerTypeResolvingStrategy.getOpenType() instanceof CompositeType) {
             innerTypeClass = CompositeDataSupport.class;
-        } else
+        } else {
             try {
                 innerTypeClass = Class.forName(getOpenType().getElementOpenType().getClassName());
             } catch (ClassNotFoundException e) {
-                throw new RuntimeException("Unable to locate class for "
+                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
+        } else {
             parsedArray = Array.newInstance(innerTypeClass, valueList.size());
+        }
 
         int i = 0;
         for (Object innerValue : valueList) {
             Optional<?> parsedElement = innerTypeResolvingStrategy.parseAttribute(attrName + "_" + i, innerValue);
-
-            if (!parsedElement.isPresent())
+            if (!parsedElement.isPresent()){
                 continue;
-
+            }
             Array.set(parsedArray, i, parsedElement.get());
-            // parsedArray[i] = parsedElement.get();
             i++;
         }
 
@@ -94,7 +95,7 @@ final class ArrayAttributeResolvingStrategy extends AbstractAttributeResolvingSt
         try {
             return (Class<?>) innerTypeClass.getField("TYPE").get(null);
         } catch (Exception e) {
-            throw new RuntimeException("Unable to determine primitive type to " + innerTypeClass);
+            throw new IllegalStateException("Unable to determine primitive type to " + innerTypeClass);
         }
     }
 
index 0bb274ae413c2fbd4c4712cd31ec8b25e2442c5f..599d81396e6fea26dbe5c83778e90592f46e15e3 100644 (file)
@@ -11,6 +11,7 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attri
 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.
@@ -18,5 +19,5 @@ import javax.management.openmbean.OpenType;
 public interface AttributeResolvingStrategy<T, O extends OpenType<?>> {
     O getOpenType();
 
-    Optional<T> parseAttribute(String attrName, Object value);
+    Optional<T> parseAttribute(String attrName, Object value) throws NetconfDocumentedException;
 }
index e8e97f990f44cd45608fb8df92e042437351e319..83ebf65d7fb71c1e5791dcfac416e4097a94f675 100644 (file)
@@ -11,6 +11,7 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attri
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.Maps;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
 import org.opendaylight.controller.netconf.confignetconfconnector.util.Util;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -41,7 +42,7 @@ class CompositeAttributeResolvingStrategy extends
     }
 
     @Override
-    public Optional<CompositeDataSupport> parseAttribute(String attrName, Object value) {
+    public Optional<CompositeDataSupport> parseAttribute(String attrName, Object value) throws NetconfDocumentedException {
 
         if (value == null) {
             return Optional.absent();
@@ -75,7 +76,7 @@ class CompositeAttributeResolvingStrategy extends
         try {
             parsedValue = new CompositeDataSupport(getOpenType(), items);
         } catch (OpenDataException e) {
-            throw new RuntimeException("An error occured during restoration of composite type " + this
+            throw new IllegalStateException("An error occured during restoration of composite type " + this
                     + " for attribute " + attrName + " from value " + value, e);
         }
 
index 82c8c1ec6b537f2ca25cc585dfe4c795cd2b7350..4a4281a55e04489beb1a8ed9360a457ec9899dad 100644 (file)
@@ -106,8 +106,8 @@ public class ObjectResolver extends AttributeIfcSwitchStatement<AttributeResolvi
 
     @Override
     protected AttributeResolvingStrategy<?, ? extends OpenType<?>> caseTOAttribute(CompositeType openType) {
-        Preconditions.checkState(lastAttribute instanceof TOAttribute);
-        TOAttribute toAttribute = (TOAttribute) lastAttribute;
+        Preconditions.checkState(getLastAttribute() instanceof TOAttribute);
+        TOAttribute toAttribute = (TOAttribute) getLastAttribute();
 
         Map<String, AttributeResolvingStrategy<?, ? extends OpenType<?>>> innerMap = Maps.newHashMap();
 
@@ -122,14 +122,14 @@ public class ObjectResolver extends AttributeIfcSwitchStatement<AttributeResolvi
 
     @Override
     protected AttributeResolvingStrategy<?, ? extends OpenType<?>> caseListAttribute(ArrayType<?> openType) {
-        Preconditions.checkState(lastAttribute instanceof ListAttribute);
-        AttributeIfc innerAttribute = ((ListAttribute) lastAttribute).getInnerAttribute();
+        Preconditions.checkState(getLastAttribute() instanceof ListAttribute);
+        AttributeIfc innerAttribute = ((ListAttribute) getLastAttribute()).getInnerAttribute();
         return new ArrayAttributeResolvingStrategy(prepareStrategy(innerAttribute), openType);
     }
 
     @Override
     protected AttributeResolvingStrategy<?, ? extends OpenType<?>> caseListDependeciesAttribute(ArrayType<?> openType) {
-        Preconditions.checkState(lastAttribute instanceof ListDependenciesAttribute);
+        Preconditions.checkState(getLastAttribute() instanceof ListDependenciesAttribute);
         return new ArrayAttributeResolvingStrategy(caseDependencyAttribute(SimpleType.OBJECTNAME), openType);
     }
 
index e1b8ecf17ee50c1a4895d73301025faabd5f88e6..26709dbe6b97e2b8fcb37cde22526053debe51df 100644 (file)
@@ -10,6 +10,9 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attri
 
 import com.google.common.base.Optional;
 import com.google.common.collect.Maps;
+import java.lang.reflect.InvocationTargetException;
+import java.text.ParseException;
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
 import org.opendaylight.controller.netconf.confignetconfconnector.util.Util;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -35,7 +38,7 @@ final class SimpleAttributeResolvingStrategy extends AbstractAttributeResolvingS
     }
 
     @Override
-    public Optional<Object> parseAttribute(String attrName, Object value) {
+    public Optional<Object> parseAttribute(String attrName, Object value) throws NetconfDocumentedException {
         if (value == null) {
             return Optional.absent();
         }
@@ -70,32 +73,42 @@ final class SimpleAttributeResolvingStrategy extends AbstractAttributeResolvingS
     }
 
     static interface Resolver {
-        Object resolveObject(Class<?> type, String attrName, String value);
+        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) {
+        public Object resolveObject(Class<?> type, String attrName, String value) throws NetconfDocumentedException {
             try {
-                Object parsedValue = parseObject(type, value);
-                return parsedValue;
+                return parseObject(type, value);
             } catch (Exception e) {
-                throw new RuntimeException("Unable to resolve attribute " + attrName + " from " + value, 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 Exception {
-            Method method = type.getMethod("valueOf", String.class);
-            Object parsedValue = method.invoke(null, value);
-            return parsedValue;
+        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) {
+                logger.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) throws Exception {
+        protected Object parseObject(Class<?> type, String value) {
             return value;
         }
     }
@@ -103,7 +116,7 @@ final class SimpleAttributeResolvingStrategy extends AbstractAttributeResolvingS
     static class BigIntegerResolver extends DefaultResolver {
 
         @Override
-        protected Object parseObject(Class<?> type, String value) throws Exception {
+        protected Object parseObject(Class<?> type, String value) {
             return new BigInteger(value);
         }
     }
@@ -111,7 +124,7 @@ final class SimpleAttributeResolvingStrategy extends AbstractAttributeResolvingS
     static class BigDecimalResolver extends DefaultResolver {
 
         @Override
-        protected Object parseObject(Class<?> type, String value) throws Exception {
+        protected Object parseObject(Class<?> type, String value) {
             return new BigDecimal(value);
         }
     }
@@ -119,16 +132,23 @@ final class SimpleAttributeResolvingStrategy extends AbstractAttributeResolvingS
     static class CharResolver extends DefaultResolver {
 
         @Override
-        protected Object parseObject(Class<?> type, String value) throws Exception {
+        protected Object parseObject(Class<?> type, String value)  {
             return new Character(value.charAt(0));
         }
     }
 
     static class DateResolver extends DefaultResolver {
-
         @Override
-        protected Object parseObject(Class<?> type, String value) throws Exception {
-            return Util.readDate(value);
+        protected Object parseObject(Class<?> type, String value) throws NetconfDocumentedException {
+            try {
+                return Util.readDate(value);
+            } catch (ParseException e) {
+                logger.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);
+            }
         }
     }
 
index bc99ecf09a90b480f71b6444776fefc354177559..cdebcfaa34620595134ce868f2ac743e9eabd606 100644 (file)
@@ -34,10 +34,11 @@ final class UnionCompositeAttributeResolvingStrategy extends CompositeAttributeR
         Map<String, Object> newMap = Maps.newHashMap();
 
         for (String key : openType.keySet()) {
-            if (openType.getDescription(key).equals(JavaAttribute.DESCRIPTION_OF_VALUE_ATTRIBUTE_FOR_UNION))
+            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
+            } 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/AbstractAttributeWritingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/AbstractAttributeWritingStrategy.java
new file mode 100644 (file)
index 0000000..61465f9
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * 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;
+
+public abstract class AbstractAttributeWritingStrategy {
+    protected Object preprocess(Object value) {
+        return value;
+    }
+}
index 051f365086624ce5acf8bf2cb3d52d268044f892..b17842b8e20f50e6aa468f10800dfe43f7d4f6ae 100644 (file)
@@ -20,9 +20,9 @@ import com.google.common.base.Optional;
 
 public class CompositeAttributeWritingStrategy implements AttributeWritingStrategy {
 
-    protected final String key;
-    protected final Document document;
-    protected final Map<String, AttributeWritingStrategy> innerStrats;
+    private final String key;
+    private final Document document;
+    private final Map<String, AttributeWritingStrategy> innerStrats;
 
     public CompositeAttributeWritingStrategy(Document document, String key,
             Map<String, AttributeWritingStrategy> innerStrats) {
@@ -49,4 +49,16 @@ public class CompositeAttributeWritingStrategy implements AttributeWritingStrate
         }
         parentElement.appendChild(innerNode);
     }
+
+    public String getKey() {
+        return key;
+    }
+
+    public Document getDocument() {
+        return document;
+    }
+
+    public Map<String, AttributeWritingStrategy> getInnerStrats() {
+        return innerStrats;
+    }
 }
index 8d63bb05d8b8a275dc8984d4ebb2f438772d7ab4..4e07ec8c31e7beb81e369f9c7c68fcac5d65058f 100644 (file)
@@ -90,11 +90,11 @@ public class ObjectXmlWriter extends AttributeIfcSwitchStatement<AttributeWritin
 
     @Override
     protected AttributeWritingStrategy caseTOAttribute(CompositeType openType) {
-        Preconditions.checkState(lastAttribute instanceof TOAttribute);
+        Preconditions.checkState(getLastAttribute() instanceof TOAttribute);
 
         Map<String, AttributeWritingStrategy> innerStrats = Maps.newHashMap();
         String currentKey = key;
-        for (Entry<String, AttributeIfc> innerAttrEntry : ((TOAttribute) lastAttribute).getYangPropertiesToTypesMap().entrySet()) {
+        for (Entry<String, AttributeIfc> innerAttrEntry : ((TOAttribute) getLastAttribute()).getYangPropertiesToTypesMap().entrySet()) {
 
             AttributeWritingStrategy innerStrategy = prepareWritingStrategy(innerAttrEntry.getKey(),
                     innerAttrEntry.getValue(), document);
@@ -106,8 +106,8 @@ public class ObjectXmlWriter extends AttributeIfcSwitchStatement<AttributeWritin
 
     @Override
     protected AttributeWritingStrategy caseListAttribute(ArrayType<?> openType) {
-        Preconditions.checkState(lastAttribute instanceof ListAttribute);
-        AttributeIfc innerAttribute = ((ListAttribute) lastAttribute).getInnerAttribute();
+        Preconditions.checkState(getLastAttribute() instanceof ListAttribute);
+        AttributeIfc innerAttribute = ((ListAttribute) getLastAttribute()).getInnerAttribute();
 
         AttributeWritingStrategy innerStrategy = prepareWritingStrategy(key, innerAttribute, document);
         return new ArrayAttributeWritingStrategy(innerStrategy);
@@ -115,7 +115,7 @@ public class ObjectXmlWriter extends AttributeIfcSwitchStatement<AttributeWritin
 
     @Override
     protected AttributeWritingStrategy caseListDependeciesAttribute(ArrayType<?> openType) {
-        Preconditions.checkState(lastAttribute instanceof ListDependenciesAttribute);
+        Preconditions.checkState(getLastAttribute() instanceof ListDependenciesAttribute);
         AttributeWritingStrategy innerStrategy = caseDependencyAttribute(SimpleType.OBJECTNAME);
         return new ArrayAttributeWritingStrategy(innerStrategy);
     }
index b2555f712a0b2bd175d47fc19c482ef5713ddfab..a74afd08122ef026d235f90192207dc121a627d8 100644 (file)
@@ -8,15 +8,14 @@
 
 package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.toxml;
 
-import java.util.Map;
-import java.util.Map.Entry;
-
+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;
 
-import com.google.common.base.Optional;
+import java.util.Map;
+import java.util.Map.Entry;
 
 public class RuntimeBeanEntryWritingStrategy extends CompositeAttributeWritingStrategy {
 
@@ -36,7 +35,7 @@ public class RuntimeBeanEntryWritingStrategy extends CompositeAttributeWritingSt
     public void writeElement(Element parentElement, String namespace, Object value) {
         Util.checkType(value, Map.class);
 
-        Element innerNode = XmlUtil.createElement(document, key, Optional.<String>absent());
+        Element innerNode = XmlUtil.createElement(getDocument(), getKey(), Optional.<String>absent());
 
         Map<?, ?> map = (Map<?, ?>) value;
 
@@ -46,7 +45,7 @@ public class RuntimeBeanEntryWritingStrategy extends CompositeAttributeWritingSt
             // bean
             Util.checkType(runtimeBeanInstanceMappingEntry.getValue(), Map.class);
             Map<?, ?> innerMap = (Map<?, ?>) runtimeBeanInstanceMappingEntry.getValue();
-            Element runtimeInstanceNode = XmlUtil.createElement(document, "_"
+            Element runtimeInstanceNode = XmlUtil.createElement(getDocument(), "_"
                     + (String) runtimeBeanInstanceMappingEntry.getKey(), Optional.<String>absent());
             innerNode.appendChild(runtimeInstanceNode);
 
@@ -57,7 +56,7 @@ public class RuntimeBeanEntryWritingStrategy extends CompositeAttributeWritingSt
                 String innerKey = (String) innerObjectEntry.getKey();
                 Object innerValue = innerObjectEntry.getValue();
 
-                innerStrats.get(innerKey).writeElement(runtimeInstanceNode, namespace, innerValue);
+                getInnerStrats().get(innerKey).writeElement(runtimeInstanceNode, namespace, innerValue);
             }
         }
         parentElement.appendChild(innerNode);
index bb5a67cb9ce9051570b6ea736cc83d5e89cd1977..854f99c5c0522902f1c2f7288c353ba66dfe28aa 100644 (file)
@@ -8,20 +8,20 @@
 
 package org.opendaylight.controller.netconf.confignetconfconnector.mapping.config;
 
-import static com.google.common.base.Preconditions.checkState;
-import static java.lang.String.format;
-
+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.HashMap;
 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.confignetconfconnector.operations.editconfig.EditConfig;
@@ -29,24 +29,15 @@ import org.opendaylight.controller.netconf.confignetconfconnector.operations.edi
 import org.opendaylight.controller.netconf.util.xml.XmlElement;
 import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
 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 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;
 
 public class Config {
-    private final Logger logger = LoggerFactory.getLogger(Config.class);
 
     private final Map<String/* Namespace from yang file */,
             Map<String /* Name of module entry from yang file */, ModuleConfig>> moduleConfigs;
-    private final Map<String, ModuleConfig> moduleNamesToConfigs;
 
     private final Map<String, Map<Date, EditConfig.IdentityMapping>> identityMap;
 
@@ -56,11 +47,6 @@ public class Config {
 
     public Config(Map<String, Map<String, ModuleConfig>> moduleConfigs, Map<String, Map<Date,EditConfig.IdentityMapping>> identityMap) {
         this.moduleConfigs = moduleConfigs;
-        Map<String, ModuleConfig> moduleNamesToConfigs = new HashMap<>();
-        for (Entry<String, Map<String, ModuleConfig>> entry : moduleConfigs.entrySet()) {
-            moduleNamesToConfigs.putAll(entry.getValue());
-        }
-        this.moduleNamesToConfigs = Collections.unmodifiableMap(moduleNamesToConfigs);
         this.identityMap = identityMap;
     }
 
@@ -82,8 +68,9 @@ public class Config {
                 // TODO, this code does not support same module names from different namespaces
                 // Namespace should be present in ObjectName
 
-                if (instances == null)
+                if (instances == null){
                     continue;
+                }
 
                 innerRetVal.put(moduleName, instances);
 
@@ -104,11 +91,6 @@ public class Config {
         return retVal;
     }
 
-    // public Element toXml(Set<ObjectName> instancesToMap, String namespace,
-    // Document document) {
-    // return toXml(instancesToMap, Optional.of(namespace), document);
-    // }
-
     public Element toXml(Set<ObjectName> instancesToMap, Optional<String> maybeNamespace, Document document,
             Element dataElement, ServiceRegistryWrapper serviceTracker) {
 
@@ -264,10 +246,12 @@ public class Config {
         Optional<XmlElement> modulesOpt = getModulesElement(parent);
 
         List<XmlElement> recognised = Lists.newArrayList();
-        if(servicesOpt.isPresent())
+        if(servicesOpt.isPresent()){
             recognised.add(servicesOpt.get());
-        if(modulesOpt.isPresent())
+        }
+        if(modulesOpt.isPresent()){
             recognised.add(modulesOpt.get());
+        }
 
         parent.checkUnrecognisedElements(recognised);
     }
@@ -275,7 +259,7 @@ public class Config {
     private String getFactoryName(String factoryNameWithPrefix, String prefixOrEmptyString) {
         checkState(
                 factoryNameWithPrefix.startsWith(prefixOrEmptyString),
-                format("Internal error: text " + "content '%s' of type node does not start with prefix '%s'",
+                String.format("Internal error: text " + "content '%s' of type node does not start with prefix '%s'",
                         factoryNameWithPrefix, prefixOrEmptyString));
 
         int factoryNameAfterPrefixIndex;
index 1da9fabdb38390dd0a153b37f4f30a3560fdd03d..0fe5fad29c1d4ad20e5cb67c3d8c21357e791f46 100644 (file)
@@ -63,26 +63,24 @@ public final class InstanceConfig {
         Map<String, Object> toXml = Maps.newHashMap();
 
         for (Entry<String, AttributeIfc> configDefEntry : jmxToAttrConfig.entrySet()) {
-
             // Skip children runtime beans as they are mapped by InstanceRuntime
-            if (configDefEntry.getValue() instanceof RuntimeBeanEntry)
+            if (configDefEntry.getValue() instanceof RuntimeBeanEntry){
                 continue;
-
+            }
             Object value = configRegistryClient.getAttributeCurrentValue(on, configDefEntry.getKey());
             try {
                 AttributeMappingStrategy<?, ? extends OpenType<?>> attributeMappingStrategy = mappingStrategies
                         .get(configDefEntry.getKey());
                 Optional<?> a = attributeMappingStrategy.mapAttribute(value);
-                if (a.isPresent() == false)
+                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;
     }
 
index f3d75d07bef7ec9dc33ac1d0a189f9e37d30e50d..a5a625a2d6859a373511a1c22ffc9b98c9df6521 100644 (file)
@@ -8,12 +8,9 @@
 
 package org.opendaylight.controller.netconf.confignetconfconnector.mapping.config;
 
-import java.util.Collection;
-import java.util.Date;
-import java.util.Map;
-
-import javax.management.ObjectName;
-
+import com.google.common.base.Optional;
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.Multimap;
 import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
 import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfig;
@@ -25,9 +22,10 @@ import org.opendaylight.yangtools.yang.common.QName;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
-import com.google.common.base.Optional;
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.Multimap;
+import javax.management.ObjectName;
+import java.util.Collection;
+import java.util.Date;
+import java.util.Map;
 
 public class ModuleConfig {
 
@@ -64,7 +62,7 @@ public class ModuleConfig {
         Element root = XmlUtil.createElement(document, XmlNetconfConstants.MODULE_KEY, Optional.<String>absent());
         // Xml.addNamespaceAttr(document, root, namespace);
 
-        final String prefix = getPrefix(namespace);
+        final String prefix = getPrefix();
         Element typeElement = XmlUtil.createPrefixedTextElement(document, XmlUtil.createPrefixedValue(prefix, XmlNetconfConstants.TYPE_KEY), prefix,
                 moduleName, Optional.<String>of(namespace));
         // Xml.addNamespaceAttr(document, typeElement,
@@ -82,12 +80,8 @@ public class ModuleConfig {
         return root;
     }
 
-    private String getPrefix(String namespace) {
-        // if(namespace.contains(":")==false)
+    private String getPrefix() {
         return XmlNetconfConstants.PREFIX;
-        // return namespace.substring(namespace.lastIndexOf(':') + 1,
-        // namespace.length());
-
     }
 
     public ModuleElementResolved fromXml(XmlElement moduleElement, ServiceRegistryWrapper depTracker, String instanceName,
index 8d2d149822011ccc856e934e84271550846b1ed1..1f63555e83d93b57565ec44027114bd801eea0e1 100644 (file)
@@ -35,7 +35,9 @@ public class ServiceRegistryWrapper {
     public boolean hasRefName(String namespace, String serviceName, ObjectName on) {
         String qname = configServiceRefRegistry.getServiceInterfaceName(namespace, serviceName);
         Map<String, ObjectName> forQName = configServiceRefRegistry.getServiceMapping().get(qname);
-        if(forQName==null) return false;
+        if(forQName==null){
+            return false;
+        }
         return forQName.values().contains(on);
     }
 
@@ -70,7 +72,7 @@ public class ServiceRegistryWrapper {
         Map<String, Map<String, Map<String, String>>> retVal = Maps.newHashMap();
 
         Map<String, Map<String, ObjectName>> serviceMapping = configServiceRefRegistry.getServiceMapping();
-        for (String serviceQName : serviceMapping.keySet())
+        for (String serviceQName : serviceMapping.keySet()){
             for (String refName : serviceMapping.get(serviceQName).keySet()) {
 
                 ObjectName on = serviceMapping.get(serviceQName).get(refName);
@@ -91,11 +93,12 @@ public class ServiceRegistryWrapper {
                     serviceToRefs.put(localName, refsToSis);
                 }
 
-                Preconditions.checkState(refsToSis.containsKey(refName) == false,
+                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;
     }
@@ -108,10 +111,11 @@ public class ServiceRegistryWrapper {
         Map<String, Map<String, String>> serviceNameToRefNameToInstance = getMappedServices().get(namespace);
 
         Map<String, String> refNameToInstance;
-        if(serviceNameToRefNameToInstance == null || serviceNameToRefNameToInstance.containsKey(serviceName) == false) {
+        if(serviceNameToRefNameToInstance == null || !serviceNameToRefNameToInstance.containsKey(serviceName)) {
             refNameToInstance = Collections.emptyMap();
-        } else
+        } else {
             refNameToInstance = serviceNameToRefNameToInstance.get(serviceName);
+        }
 
         final Set<String> refNamesAsSet = toSet(refNameToInstance.keySet());
         if (refNamesAsSet.contains(refName)) {
@@ -135,12 +139,13 @@ public class ServiceRegistryWrapper {
     }
 
     private String findAvailableRefName(String refName, Set<String> refNamesAsSet) {
-        String intitialRefName = refName;
+        String availableRefName = "";
 
         while (true) {
-            refName = intitialRefName + "_" + suffix++;
-            if (refNamesAsSet.contains(refName) == false)
-                return refName;
+            availableRefName = refName + "_" + suffix++;
+            if (!refNamesAsSet.contains(availableRefName)){
+                return availableRefName;
+            }
         }
     }
 }
index f9df71700870d12e7f14e7121c14e088cd5ce474..eb5c018cf3db0af76ced902576543861b732a4f6 100644 (file)
@@ -8,33 +8,27 @@
 
 package org.opendaylight.controller.netconf.confignetconfconnector.mapping.config;
 
-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 com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Maps;
 import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
 import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
 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.XmlNetconfConstants;
 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 com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Maps;
+import javax.management.ObjectName;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 public final class Services {
 
-    private static final Logger logger = LoggerFactory.getLogger(Services.class);
-
     private static final String PROVIDER_KEY = "provider";
     private static final String NAME_KEY = "name";
     public static final String TYPE_KEY = "type";
@@ -98,7 +92,7 @@ public final class Services {
             XmlElement typeElement = service.getOnlyChildElement(TYPE_KEY);
             Entry<String, String> prefixNamespace = typeElement.findNamespaceOfTextContent();
 
-            Preconditions.checkState(prefixNamespace.getKey()!=null && prefixNamespace.getKey().equals("") == false, "Type attribute was not prefixed");
+            Preconditions.checkState(prefixNamespace.getKey()!=null && !prefixNamespace.getKey().equals(""), "Type attribute was not prefixed");
 
             Map<String, Map<String, String>> namespaceToServices = retVal.get(prefixNamespace.getValue());
             if(namespaceToServices == null) {
@@ -169,7 +163,7 @@ public final class Services {
         public static ServiceInstance fromString(String instanceId) {
             instanceId = instanceId.trim();
             Matcher matcher = p.matcher(instanceId);
-            if(matcher.matches() == false) {
+            if(!matcher.matches()) {
                 matcher = pDeprecated.matcher(instanceId);
             }
 
@@ -237,23 +231,30 @@ public final class Services {
 
         @Override
         public boolean equals(Object obj) {
-            if (this == obj)
+            if (this == obj){
                 return true;
-            if (obj == null)
+            }
+            if (obj == null){
                 return false;
-            if (getClass() != obj.getClass())
+            }
+            if (getClass() != obj.getClass()){
                 return false;
+            }
             ServiceInstance other = (ServiceInstance) obj;
             if (instanceName == null) {
-                if (other.instanceName != null)
+                if (other.instanceName != null){
                     return false;
-            } else if (!instanceName.equals(other.instanceName))
+                }
+            } else if (!instanceName.equals(other.instanceName)){
                 return false;
+            }
             if (moduleName == null) {
-                if (other.moduleName != null)
+                if (other.moduleName != null){
                     return false;
-            } else if (!moduleName.equals(other.moduleName))
+                }
+            } else if (!moduleName.equals(other.moduleName)){
                 return false;
+            }
             return true;
         }
 
index a081890d398c1c8fd2f349b8e5127b83e5a57cbf..28b14178937aeca68acc76dcebd3370a0f45aaf2 100644 (file)
@@ -17,12 +17,12 @@ import java.util.Map;
 
 public final class ModuleRpcs {
 
-    Map<String, String> yangToJavaNames = Maps.newHashMap();
-    Map<String, Map<String, InstanceRuntimeRpc>> rpcMapping = Maps.newHashMap();
+    private final Map<String, String> yangToJavaNames = Maps.newHashMap();
+    private final Map<String, Map<String, InstanceRuntimeRpc>> rpcMapping = Maps.newHashMap();
 
     public void addNameMapping(RuntimeBeanEntry runtimeEntry) {
         String yangName = runtimeEntry.getYangName();
-        Preconditions.checkState(yangToJavaNames.containsKey(yangName) == false,
+        Preconditions.checkState(!yangToJavaNames.containsKey(yangName),
                 "RuntimeBean %s found twice in same namespace", yangName);
         yangToJavaNames.put(yangName, runtimeEntry.getJavaNamePrefix());
     }
@@ -35,7 +35,7 @@ public final class ModuleRpcs {
             rpcMapping.put(yangName, map);
         }
 
-        Preconditions.checkState(map.containsKey(rpc.getYangName()) == false, "Rpc %s for runtime bean %s added twice",
+        Preconditions.checkState(!map.containsKey(rpc.getYangName()), "Rpc %s for runtime bean %s added twice",
                 rpc.getYangName(), yangName);
         map.put(rpc.getYangName(), new InstanceRuntimeRpc(rpc));
     }
@@ -55,4 +55,12 @@ public final class ModuleRpcs {
         Preconditions.checkState(rpc != null, "No rpc found for runtime bean %s with name %s", rbeName, rpcName);
         return rpc;
     }
+
+    public Map<String, String> getYangToJavaNames() {
+        return yangToJavaNames;
+    }
+
+    public Map<String, Map<String, InstanceRuntimeRpc>> getRpcMapping() {
+        return rpcMapping;
+    }
 }
index 8c3b35122c2061af455222b70b464b3471ad6fc5..6a49275f260d7c0d047d3b3642d1886b35458b93 100644 (file)
@@ -8,22 +8,19 @@
 
 package org.opendaylight.controller.netconf.confignetconfconnector.mapping.runtime;
 
-import java.util.Hashtable;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-import javax.management.ObjectName;
-
+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 org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfig;
 import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
-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 javax.management.ObjectName;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
 
 public class InstanceRuntime {
 
@@ -48,20 +45,23 @@ public class InstanceRuntime {
      * root + any number of additional properties
      */
     private Set<ObjectName> findChildren(ObjectName innerRootBean, Set<ObjectName> childRbeOns) {
-        final Hashtable<String, String> wantedProperties = innerRootBean.getKeyPropertyList();
+        final Map<String, String> wantedProperties = innerRootBean.getKeyPropertyList();
 
         return Sets.newHashSet(Collections2.filter(childRbeOns, new Predicate<ObjectName>() {
 
             @Override
             public boolean apply(ObjectName on) {
-                Hashtable<String, String> localProperties = on.getKeyPropertyList();
+                Map<String, String> localProperties = on.getKeyPropertyList();
                 for (Entry<String, String> propertyEntry : wantedProperties.entrySet()) {
-                    if (!localProperties.containsKey(propertyEntry.getKey()))
+                    if (!localProperties.containsKey(propertyEntry.getKey())){
                         return false;
-                    if (!localProperties.get(propertyEntry.getKey()).equals(propertyEntry.getValue()))
+                    }
+                    if (!localProperties.get(propertyEntry.getKey()).equals(propertyEntry.getValue())){
                         return false;
-                    if (localProperties.size() <= wantedProperties.size())
+                    }
+                    if (localProperties.size() <= wantedProperties.size()){
                         return false;
+                    }
                 }
                 return true;
             }
@@ -77,10 +77,12 @@ public class InstanceRuntime {
 
             @Override
             public boolean apply(ObjectName on) {
-                if (on.getKeyPropertyList().size() != keyListSize + 1)
+                if (on.getKeyPropertyList().size() != keyListSize + 1){
                     return false;
-                if (!on.getKeyPropertyList().containsKey(string))
+                }
+                if (!on.getKeyPropertyList().containsKey(string)){
                     return false;
+                }
                 return true;
             }
         }));
index 4936d1dbcda833b7fb5fdfe904d8b5e1493f6b34..59767fec6e79546595d9a6bf9207e80482b09a94 100644 (file)
@@ -20,11 +20,9 @@ import java.util.Set;
 
 public class ModuleRuntime {
 
-    private final String moduleName;
     private final InstanceRuntime instanceRuntime;
 
     public ModuleRuntime(String moduleName, InstanceRuntime instanceRuntime) {
-        this.moduleName = moduleName;
         this.instanceRuntime = instanceRuntime;
     }
 
@@ -34,8 +32,9 @@ public class ModuleRuntime {
 
     private ObjectName findRoot(Collection<ObjectName> runtimeBeanOns) {
         for (ObjectName objectName : runtimeBeanOns) {
-            if (objectName.getKeyPropertyList().size() == 3)
+            if (objectName.getKeyPropertyList().size() == 3){
                 return objectName;
+            }
         }
         throw new IllegalStateException("Root runtime bean not found among " + runtimeBeanOns);
     }
index 8fc3ee14233b31cf04c7703f2ba4ff65a1b28728..439dea2a80c352252228333cc19b9a66adc7775f 100644 (file)
@@ -85,7 +85,7 @@ public class Runtime {
 
                     Element runtimeXml;
                     ModuleConfig moduleConfig = moduleConfigs.get(localNamespace).get(moduleName);
-                    if(instanceToRbe==null || instanceToRbe.containsKey(instanceName) == false) {
+                    if(instanceToRbe==null || !instanceToRbe.containsKey(instanceName)) {
                         runtimeXml = moduleConfig.toXml(instanceON, serviceRegistry, document, localNamespace);
                     } else {
                         ModuleRuntime moduleRuntime = moduleRuntimes.get(localNamespace).get(moduleName);
@@ -101,14 +101,4 @@ public class Runtime {
         return root;
     }
 
-    private ObjectName findInstance(Collection<ObjectName> objectNames, String instanceName) {
-        for (ObjectName objectName : objectNames) {
-            String name = ObjectNameUtil.getInstanceName(objectName);
-            if(name.equals(instanceName))
-                return objectName;
-        }
-
-        throw new UnsupportedOperationException("Unable to find config bean instance under name " + instanceName + " among " + objectNames);
-    }
-
 }
index cd99ac4d8d672b039fffb3fcdbed0fa62fc4790e..c4217106cee221cc543b405eb6e4423a64437d8f 100644 (file)
@@ -13,11 +13,15 @@ import org.opendaylight.controller.netconf.util.mapping.AbstractLastNetconfOpera
 
 public abstract class AbstractConfigNetconfOperation extends AbstractLastNetconfOperation {
 
-    protected final ConfigRegistryClient configRegistryClient;
+    private final ConfigRegistryClient configRegistryClient;
 
     protected AbstractConfigNetconfOperation(ConfigRegistryClient configRegistryClient,
             String netconfSessionIdForReporting) {
         super(netconfSessionIdForReporting);
         this.configRegistryClient = configRegistryClient;
     }
+
+    public ConfigRegistryClient getConfigRegistryClient() {
+        return configRegistryClient;
+    }
 }
index e88863c685ace15c486c9b5c263345a81ace9a44..c5fadb097f2d64f4d8b694e345f98dd71136d1c6 100644 (file)
@@ -8,8 +8,9 @@
 
 package org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig;
 
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.Multimap;
+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;
@@ -18,23 +19,10 @@ import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import javax.management.InstanceNotFoundException;
-import javax.management.ObjectName;
-import java.util.Map;
-
 public class DeleteEditConfigStrategy extends AbstractEditConfigStrategy {
 
     private static final Logger logger = LoggerFactory.getLogger(DeleteEditConfigStrategy.class);
 
-    private final Multimap<String, String> providedServices;
-
-    public DeleteEditConfigStrategy() {
-        this.providedServices = HashMultimap.create();
-    }
-
-    public DeleteEditConfigStrategy(Multimap<String, String> providedServices) {
-        this.providedServices = providedServices;
-    }
 
     @Override
     void handleMissingInstance(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta,
index 428ddb3b740dfbb5e34e62bff86035d0e9464b03..3ea26055f33c79212debc907caa259109f7101a2 100644 (file)
@@ -72,11 +72,11 @@ public class EditConfig extends AbstractConfigNetconfOperation {
             final EditConfigXmlParser.EditConfigExecution editConfigExecution) throws NetconfDocumentedException, NetconfConfigHandlingException {
 
         if (editConfigExecution.shouldTest()) {
-            executeTests(configRegistryClient, editConfigExecution);
+            executeTests(getConfigRegistryClient(), editConfigExecution);
         }
 
         if (editConfigExecution.shouldSet()) {
-            executeSet(configRegistryClient, editConfigExecution);
+            executeSet(getConfigRegistryClient(), editConfigExecution);
         }
 
         logger.trace("Operation {} successful", EditConfigXmlParser.EDIT_CONFIG);
@@ -224,7 +224,7 @@ public class EditConfig extends AbstractConfigNetconfOperation {
 
         void addIdSchemaNode(IdentitySchemaNode node) {
             String name = node.getQName().getLocalName();
-            Preconditions.checkState(identityNameToSchemaNode.containsKey(name) == false);
+            Preconditions.checkState(!identityNameToSchemaNode.containsKey(name));
             identityNameToSchemaNode.put(name, node);
         }
 
@@ -250,7 +250,7 @@ public class EditConfig extends AbstractConfigNetconfOperation {
             }
 
             Date revision = module.getRevision();
-            Preconditions.checkState(revisionsByNamespace.containsKey(revision) == false,
+            Preconditions.checkState(!revisionsByNamespace.containsKey(revision),
                     "Duplicate revision %s for namespace %s", revision, namespace);
 
             IdentityMapping identityMapping = revisionsByNamespace.get(revision);
@@ -306,8 +306,8 @@ public class EditConfig extends AbstractConfigNetconfOperation {
     protected Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws NetconfDocumentedException {
 
         EditConfigXmlParser.EditConfigExecution editConfigExecution;
-        Config cfg = getConfigMapping(configRegistryClient, yangStoreSnapshot);
-        editConfigExecution = editConfigXmlParser.fromXml(xml, cfg, transactionProvider, configRegistryClient);
+        Config cfg = getConfigMapping(getConfigRegistryClient(), yangStoreSnapshot);
+        editConfigExecution = editConfigXmlParser.fromXml(xml, cfg, transactionProvider, getConfigRegistryClient());
 
         Element responseInternal;
         responseInternal = getResponseInternal(document, editConfigExecution);
index de6979565e3fe225fc7150dbbe645d4042decdc0..547ffcda3db0941459d4c2163a7fdc9596bc5bb2 100644 (file)
@@ -98,9 +98,10 @@ public class EditConfigXmlParser {
                 .getOnlyChildElementWithSameNamespaceOptionally(EditConfigXmlParser.ERROR_OPTION_KEY);
         if (errorOptionElement.isPresent()) {
             String errorOptionParsed = errorOptionElement.get().getTextContent();
-            if (false == errorOptionParsed.equals(EditConfigXmlParser.DEFAULT_ERROR_OPTION))
+            if (!errorOptionParsed.equals(EditConfigXmlParser.DEFAULT_ERROR_OPTION)){
                 throw new UnsupportedOperationException("Only " + EditConfigXmlParser.DEFAULT_ERROR_OPTION
                         + " supported for " + EditConfigXmlParser.ERROR_OPTION_KEY + ", was " + errorOptionParsed);
+            }
         }
 
         // Default op
index 2f41defac8ff880a9733e21513f6a3dd96d914f5..6b81603dcd01cdffa0ce3d4b5c9486fc66db2b8d 100644 (file)
@@ -65,7 +65,7 @@ public enum EditStrategyType {
         case replace:
             return new ReplaceEditConfigStrategy(providedServices);
         case delete:
-            return new DeleteEditConfigStrategy(providedServices);
+            return new DeleteEditConfigStrategy();
         case remove:
             return new RemoveEditConfigStrategy();
         case none:
index 0a72547d78454cc242756a5a683045ad2f034fa0..3e5707cf6ddbc29f842d50fe5cde929458604a91 100644 (file)
@@ -54,8 +54,9 @@ public class MergeEditConfigStrategy extends AbstractEditConfigStrategy {
         for (Entry<String, String> namespaceToService : providedServices.entries()) {
 
             if(services.hasRefName(namespaceToService.getKey(),
-                    namespaceToService.getValue(), on))
+                    namespaceToService.getValue(), on)){
                 continue;
+            }
 
             String refName = services.getNewDefaultRefName(namespaceToService.getKey(), namespaceToService.getValue(),
                     ObjectNameUtil.getFactoryName(on), ObjectNameUtil.getInstanceName(on));
index b61fcbadc07cd3caaa6582538f734077c79839ba..bc3082ff50f51b4365280e6f37861c7c36cdaaf0 100644 (file)
@@ -55,8 +55,9 @@ public class ReplaceEditConfigStrategy extends AbstractEditConfigStrategy {
         for (Entry<String, String> namespaceToService : providedServices.entries()) {
 
             if(services.hasRefName(namespaceToService.getKey(),
-                    namespaceToService.getValue(), on))
+                    namespaceToService.getValue(), on)){
                 continue;
+            }
 
             String refName = services.getNewDefaultRefName(namespaceToService.getKey(), namespaceToService.getValue(),
                     ObjectNameUtil.getFactoryName(on), ObjectNameUtil.getInstanceName(on));
index dd0e53b1bbb42f8fb2b91fb8b1eb1cc97671aa52..4665c2cc89cf23d9f5efbb876b532b377ef22896 100644 (file)
@@ -69,12 +69,14 @@ public class Get extends AbstractConfigNetconfOperation {
                 RuntimeBeanEntry root = null;
                 for (RuntimeBeanEntry rbe : mbe.getRuntimeBeans()) {
                     cache.put(rbe, new InstanceConfig(configRegistryClient, rbe.getYangPropertiesToTypesMap()));
-                    if (rbe.isRoot())
+                    if (rbe.isRoot()){
                         root = rbe;
+                    }
                 }
 
-                if (root == null)
+                if (root == null){
                     continue;
+                }
 
                 InstanceRuntime rootInstanceRuntime = createInstanceRuntime(root, cache);
                 ModuleRuntime moduleRuntime = new ModuleRuntime(module, rootInstanceRuntime);
@@ -108,8 +110,9 @@ public class Get extends AbstractConfigNetconfOperation {
         xml.checkNamespace(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
 
         // Filter option - unsupported
-        if (xml.getChildElements(XmlNetconfConstants.FILTER).size() != 0)
+        if (xml.getChildElements(XmlNetconfConstants.FILTER).size() != 0){
             throw new UnsupportedOperationException("Unsupported option " + XmlNetconfConstants.FILTER + " for " + XmlNetconfConstants.GET);
+        }
     }
 
     @Override
@@ -121,21 +124,21 @@ public class Get extends AbstractConfigNetconfOperation {
     protected Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws NetconfDocumentedException {
         checkXml(xml);
 
-        final Set<ObjectName> runtimeBeans = configRegistryClient.lookupRuntimeBeans();
+        final Set<ObjectName> runtimeBeans = getConfigRegistryClient().lookupRuntimeBeans();
 
         //Transaction provider required only for candidate datastore
         final Set<ObjectName> configBeans = Datastore.getInstanceQueryStrategy(Datastore.running, null)
-                .queryInstances(configRegistryClient);
+                .queryInstances(getConfigRegistryClient());
 
-        final Map<String, Map<String, ModuleRuntime>> moduleRuntimes = createModuleRuntimes(configRegistryClient,
+        final Map<String, Map<String, ModuleRuntime>> moduleRuntimes = createModuleRuntimes(getConfigRegistryClient(),
                 yangStoreSnapshot.getModuleMXBeanEntryMap());
         final Map<String, Map<String, ModuleConfig>> moduleConfigs = EditConfig.transformMbeToModuleConfigs(
-                configRegistryClient, yangStoreSnapshot.getModuleMXBeanEntryMap());
+                getConfigRegistryClient(), yangStoreSnapshot.getModuleMXBeanEntryMap());
 
         final Runtime runtime = new Runtime(moduleRuntimes, moduleConfigs);
 
         ObjectName txOn = transactionProvider.getOrCreateTransaction();
-        ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(txOn);
+        ConfigTransactionClient ta = getConfigRegistryClient().getConfigTransactionClient(txOn);
         final Element element = runtime.toXml(runtimeBeans, configBeans, document, new ServiceRegistryWrapper(ta));
 
         logger.trace("{} operation successful", XmlNetconfConstants.GET);
index 11d3e32edf6748fe811a9a25174330afae5b1d28..82e07c1e7b29bd5b8eaffafc6e1a53cdeaa82828 100644 (file)
@@ -66,9 +66,10 @@ public class GetConfig extends AbstractConfigNetconfOperation {
         Datastore sourceDatastore = Datastore.valueOf(sourceParsed);
 
         // Filter option - unsupported
-        if (xml.getChildElements(XmlNetconfConstants.FILTER).size() != 0)
+        if (xml.getChildElements(XmlNetconfConstants.FILTER).size() != 0){
             throw new UnsupportedOperationException("Unsupported option " + XmlNetconfConstants.FILTER + " for "
                     + GET_CONFIG);
+        }
 
         return sourceDatastore;
 
@@ -104,6 +105,6 @@ public class GetConfig extends AbstractConfigNetconfOperation {
     public Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws NetconfDocumentedException {
         Datastore source;
         source = fromXml(xml);
-        return getResponseInternal(document, configRegistryClient, source);
+        return getResponseInternal(document, getConfigRegistryClient(), source);
     }
 }
index 5a30fc8352600f524f86224c88ff09a6c5365a68..7790e09ceeb245b926f9c1c4c71fe1f2dde16589 100644 (file)
@@ -139,8 +139,9 @@ public class RuntimeRpc extends AbstractConfigNetconfOperation {
         final Optional<XmlElement> contextInstanceElement = operationElement
                 .getOnlyChildElementOptionally(CONTEXT_INSTANCE);
 
-        if (contextInstanceElement.isPresent() == false)
+        if (!contextInstanceElement.isPresent()){
             return HandlingPriority.CANNOT_HANDLE;
+        }
 
         final RuntimeRpcElementResolved id = RuntimeRpcElementResolved.fromXpath(contextInstanceElement.get()
                 .getTextContent(), netconfOperationName, netconfOperationNamespace);
@@ -182,7 +183,7 @@ public class RuntimeRpc extends AbstractConfigNetconfOperation {
 
         logger.debug("Invoking operation {} on {} with arguments {}", execution.operationName, execution.on,
                 execution.attributes);
-        final Object result = executeOperation(configRegistryClient, execution.on, execution.operationName,
+        final Object result = executeOperation(getConfigRegistryClient(), execution.on, execution.operationName,
                 execution.attributes);
 
         logger.trace("Operation {} called successfully on {} with arguments {} with result {}", execution.operationName,
@@ -225,7 +226,7 @@ public class RuntimeRpc extends AbstractConfigNetconfOperation {
 
         for (XmlElement xmlElement : xml.getChildElements()) {
             final String name = xmlElement.getName();
-            if (CONTEXT_INSTANCE.equals(name) == false) { // skip context
+            if (!CONTEXT_INSTANCE.equals(name)) { // skip context
                                                           // instance child node
                                                           // because it
                                                           // specifies
index 0f0b1227a625cd717840f2841dcb4706b270e47c..5cf7f30abcaa5cf356a2faf89635c0cb1ee06f63 100644 (file)
@@ -93,12 +93,12 @@ public final class RuntimeRpcElementResolved {
                 RuntimeRpc.CONTEXT_INSTANCE, xpath, elementName, xpathPatternBlueprint);
 
         PatternGroupResolver groups = new PatternGroupResolver(matcher.group("key1"), matcher.group("value1"),
-                matcher.group("key2"), matcher.group("value2"), matcher.group("additional"));
+                matcher.group("value2"), matcher.group("additional"));
 
         String moduleName = groups.getModuleName();
         String instanceName = groups.getInstanceName();
 
-        HashMap<String, String> additionalAttributes = groups.getAdditionalKeys(elementName, moduleName);
+        Map<String, String> additionalAttributes = groups.getAdditionalKeys(elementName, moduleName);
 
         return new RuntimeRpcElementResolved(namespace, moduleName, instanceName, groups.getRuntimeBeanYangName(),
                 additionalAttributes);
@@ -106,15 +106,14 @@ public final class RuntimeRpcElementResolved {
 
     private static final class PatternGroupResolver {
 
-        private final String key1, key2, value1, value2;
+        private final String key1, value1, value2;
         private final String additional;
         private String runtimeBeanYangName;
 
-        PatternGroupResolver(String key1, String value1, String key2, String value2, String additional) {
+        PatternGroupResolver(String key1, String value1,  String value2, String additional) {
             this.key1 = Preconditions.checkNotNull(key1);
             this.value1 = Preconditions.checkNotNull(value1);
 
-            this.key2 = Preconditions.checkNotNull(key2);
             this.value2 = Preconditions.checkNotNull(value2);
 
             this.additional = Preconditions.checkNotNull(additional);
@@ -128,13 +127,14 @@ public final class RuntimeRpcElementResolved {
             return key1.equals(XmlNetconfConstants.NAME_KEY) ? value1 : value2;
         }
 
-        HashMap<String, String> getAdditionalKeys(String elementName, String moduleName) {
+        Map<String, String> getAdditionalKeys(String elementName, String moduleName) {
             HashMap<String, String> additionalAttributes = Maps.newHashMap();
 
             runtimeBeanYangName = moduleName;
             for (String additionalKeyValue : additional.split("/")) {
-                if (Strings.isNullOrEmpty(additionalKeyValue))
+                if (Strings.isNullOrEmpty(additionalKeyValue)){
                     continue;
+                }
                 Matcher matcher = additionalPattern.matcher(additionalKeyValue);
                 Preconditions
                         .checkState(
index 421870ca3611bb6e35a8e7ddd9ec574d0e62e4ab..3ba92b092ed2f5ccb067a8ee25aae3efd08a4d82 100644 (file)
@@ -73,7 +73,7 @@ public class Activator implements BundleActivator {
     }
 
     @Override
-    public void stop(BundleContext context) throws Exception {
+    public void stop(BundleContext context) {
         if (configRegistryLookup != null) {
             configRegistryLookup.interrupt();
         }
index 09966b8c3bd6c74f29ed93f20cd12e6654ee9a04..7f4f8fccb50740c9a9c990e0f942c11b80a5fa64 100644 (file)
@@ -24,17 +24,11 @@ import org.opendaylight.controller.netconf.mapping.api.NetconfOperation;
 import java.util.Set;
 
 final class NetconfOperationProvider {
-    private final YangStoreSnapshot yangStoreSnapshot;
     private final Set<NetconfOperation> operations;
-    private final ConfigRegistryClient configRegistryClient;
-    private final TransactionProvider transactionProvider;
 
     NetconfOperationProvider(YangStoreSnapshot yangStoreSnapshot, ConfigRegistryClient configRegistryClient,
             TransactionProvider transactionProvider, String netconfSessionIdForReporting) {
 
-        this.yangStoreSnapshot = yangStoreSnapshot;
-        this.configRegistryClient = configRegistryClient;
-        this.transactionProvider = transactionProvider;
         operations = setUpOperations(yangStoreSnapshot, configRegistryClient, transactionProvider,
                 netconfSessionIdForReporting);
     }
index b8b7fcb47f137f5d422c0239f9159cec3c5ad234..12469f66b7be00d2649f231f8e1471073eaa66bd 100644 (file)
@@ -52,7 +52,7 @@ public class NetconfOperationServiceFactoryImpl implements NetconfOperationServi
                     Thread.sleep(ATTEMPT_TIMEOUT_MS);
                 } catch (InterruptedException e1) {
                     Thread.currentThread().interrupt();
-                    throw new RuntimeException("Interrupted while reattempting connection", e1);
+                    throw new IllegalStateException("Interrupted while reattempting connection", e1);
                 }
             }
         }
index c6248df41bc133f7754f9c78f0ec2bb15fa69bcb..1069858b4777008a321b7021beb172ca951675df 100644 (file)
@@ -61,8 +61,9 @@ public class NetconfOperationServiceImpl implements NetconfOperationService {
         for (Map<String, ModuleMXBeanEntry> moduleNameToMBE : moduleMXBeanEntryMap.values()) {
             for (ModuleMXBeanEntry moduleMXBeanEntry : moduleNameToMBE.values()) {
                 String moduleSeenByYangStore = moduleMXBeanEntry.getYangModuleQName().toString();
-                if(modulesSeenByConfig.contains(moduleSeenByYangStore) == false)
+                if(!modulesSeenByConfig.contains(moduleSeenByYangStore)){
                     missingModulesFromConfig.add(moduleSeenByYangStore);
+                }
             }
         }
 
@@ -149,7 +150,7 @@ public class NetconfOperationServiceImpl implements NetconfOperationService {
         }
     }
 
-    private static class YangStoreCapability extends BasicCapability {
+    private static final class YangStoreCapability extends BasicCapability {
 
         private final String content;
         private final String revision;
index 756a38ed940be7e910dc82a90523bbf3cbf48b50..250af688eac0db0a796b2e4dd668f84684949b99 100644 (file)
@@ -34,6 +34,7 @@ public class TransactionProvider implements AutoCloseable {
     private final String netconfSessionIdForReporting;
     private ObjectName transaction;
     private final List<ObjectName> allOpenedTransactions = new ArrayList<>();
+    private static final String  NO_TRANSACTION_FOUND_FOR_SESSION = "No transaction found for session ";
 
     public TransactionProvider(ConfigRegistryClient configRegistryClient, String netconfSessionIdForReporting) {
         this.configRegistryClient = configRegistryClient;
@@ -56,11 +57,12 @@ public class TransactionProvider implements AutoCloseable {
 
     public Optional<ObjectName> getTransaction() {
 
-        if (transaction == null)
+        if (transaction == null){
             return Optional.absent();
+        }
 
         // Transaction was already closed somehow
-        if (isStillOpenTransaction(transaction) == false) {
+        if (!isStillOpenTransaction(transaction)) {
             logger.warn("Fixing illegal state: transaction {} was closed in {}", transaction,
                     netconfSessionIdForReporting);
             transaction = null;
@@ -70,8 +72,7 @@ public class TransactionProvider implements AutoCloseable {
     }
 
     private boolean isStillOpenTransaction(ObjectName transaction) {
-        boolean isStillOpenTransaction = configRegistryClient.getOpenConfigs().contains(transaction);
-        return isStillOpenTransaction;
+        return configRegistryClient.getOpenConfigs().contains(transaction);
     }
 
     public synchronized ObjectName getOrCreateTransaction() {
@@ -126,7 +127,7 @@ public class TransactionProvider implements AutoCloseable {
     public synchronized void abortTransaction() {
         logger.debug("Aborting current transaction");
         Optional<ObjectName> taON = getTransaction();
-        Preconditions.checkState(taON.isPresent(), "No transaction found for session " + netconfSessionIdForReporting);
+        Preconditions.checkState(taON.isPresent(), NO_TRANSACTION_FOUND_FOR_SESSION + netconfSessionIdForReporting);
 
         ConfigTransactionClient transactionClient = configRegistryClient.getConfigTransactionClient(taON.get());
         transactionClient.abortConfig();
@@ -143,7 +144,7 @@ public class TransactionProvider implements AutoCloseable {
 
     public void validateTransaction() throws ValidationException {
         Optional<ObjectName> taON = getTransaction();
-        Preconditions.checkState(taON.isPresent(), "No transaction found for session " + netconfSessionIdForReporting);
+        Preconditions.checkState(taON.isPresent(), NO_TRANSACTION_FOUND_FOR_SESSION + netconfSessionIdForReporting);
 
         ConfigTransactionClient transactionClient = configRegistryClient.getConfigTransactionClient(taON.get());
         transactionClient.validateConfig();
@@ -171,10 +172,11 @@ public class TransactionProvider implements AutoCloseable {
             try {
                 transactionClient.destroyModule(instance);
             } catch (InstanceNotFoundException e) {
-                if (isTest)
+                if (isTest){
                     logger.debug("Unable to clean configuration in transactiom {}", taON, e);
-                else
+                } else {
                     logger.warn("Unable to clean configuration in transactiom {}", taON, e);
+                }
 
                 throw new IllegalStateException("Unable to clean configuration in transactiom " + taON, e);
             }
@@ -187,7 +189,7 @@ public class TransactionProvider implements AutoCloseable {
 
     public void wipeTransaction() {
         Optional<ObjectName> taON = getTransaction();
-        Preconditions.checkState(taON.isPresent(), "No transaction found for session " + netconfSessionIdForReporting);
+        Preconditions.checkState(taON.isPresent(), NO_TRANSACTION_FOUND_FOR_SESSION + netconfSessionIdForReporting);
         wipeInternal(taON.get(), false, null);
     }
 
index f151949abc3c859018e02daca7620d25b2d1b34e..2e8d1f64ab62cded6bde037c0d082e4604c8785a 100644 (file)
@@ -145,7 +145,7 @@ public class NetconfMappingTest extends AbstractConfigTest {
         this.factory = new NetconfTestImplModuleFactory();
         this.factory2 = new DepTestImplModuleFactory();
         this.factory3 = new IdentityTestModuleFactory();
-        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(this.factory, this.factory2,
+        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext, this.factory, this.factory2,
                 this.factory3));
 
         transactionProvider = new TransactionProvider(this.configRegistryClient, NETCONF_SESSION_ID);
index 1616857949d91c0678e7740ae2b277bfc12b25a0..40a15be70616217d81529b003f899236865d8ac8 100644 (file)
@@ -50,7 +50,7 @@ public class ConfigPersisterNotificationHandler implements Closeable {
         try {
             mBeanServerConnection.addNotificationListener(DefaultCommitOperationMXBean.OBJECT_NAME, listener, null, null);
         } catch (InstanceNotFoundException | IOException e) {
-            throw new RuntimeException("Cannot register as JMX listener to netconf", e);
+            throw new IllegalStateException("Cannot register as JMX listener to netconf", e);
         }
     }
 
@@ -79,9 +79,8 @@ class ConfigPersisterNotificationListener implements NotificationListener {
 
     @Override
     public void handleNotification(Notification notification, Object handback) {
-        if (notification instanceof NetconfJMXNotification == false) {
+        if (!(notification instanceof NetconfJMXNotification))
             return;
-        }
 
         // Socket should not be closed at this point
         // Activator unregisters this as JMX listener before close is called
index 31a4f080368515c075872173e9ba066c830f5e0e..a0e7974b942951c521305ae4726baa4a5a74d74a 100644 (file)
@@ -9,20 +9,19 @@
 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.opendaylight.controller.netconf.persist.impl.osgi.PropertiesProviderBaseImpl;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.ListIterator;
-
 /**
  * {@link Persister} implementation that delegates persisting functionality to
  * underlying {@link Persister} storages. Each storage has unique id, class, readonly value.
@@ -88,7 +87,7 @@ public final class PersisterAggregator implements Persister {
         }
     }
 
-    private static PersisterWithConfiguration loadConfiguration(final String index, final PropertiesProviderBaseImpl propertiesProvider) {
+    private static PersisterWithConfiguration loadConfiguration(final String index, final PropertiesProvider propertiesProvider) {
 
         String classKey = index + "." + ConfigPersisterActivator.STORAGE_ADAPTER_CLASS_PROP_SUFFIX;
         String storageAdapterClass = propertiesProvider.getProperty(classKey);
@@ -102,7 +101,7 @@ public final class PersisterAggregator implements Persister {
         try {
             Class<?> clazz = Class.forName(storageAdapterClass);
             boolean implementsCorrectIfc = StorageAdapter.class.isAssignableFrom(clazz);
-            if (implementsCorrectIfc == false) {
+            if (!implementsCorrectIfc) {
                 throw new IllegalArgumentException("Storage adapter " + clazz + " does not implement " + StorageAdapter.class);
             }
             storageAdapter = StorageAdapter.class.cast(clazz.newInstance());
@@ -131,10 +130,10 @@ public final class PersisterAggregator implements Persister {
 
     }
 
-    public static PersisterAggregator createFromProperties(PropertiesProviderBaseImpl propertiesProvider) {
+    public static PersisterAggregator createFromProperties(PropertiesProvider propertiesProvider) {
         List<PersisterWithConfiguration> persisterWithConfigurations = new ArrayList<>();
         String prefixes = propertiesProvider.getProperty("active");
-        if (prefixes!=null && prefixes.isEmpty() == false) {
+        if (prefixes!=null && !prefixes.isEmpty()) {
             String [] keys = prefixes.split(",");
             for (String index: keys) {
                 persisterWithConfigurations.add(PersisterAggregator.loadConfiguration(index, propertiesProvider));
@@ -169,7 +168,7 @@ public final class PersisterAggregator implements Persister {
             } catch (IOException e) {
                 throw new RuntimeException("Error while calling loadLastConfig on " +  persisterWithConfiguration, e);
             }
-            if (configs.isEmpty() == false) {
+            if (!configs.isEmpty()) {
                 logger.debug("Found non empty configs using {}:{}", persisterWithConfiguration, configs);
                 return configs;
             }
index d9466ff00b6d6a0d1e9c034d43ad310600407dd3..238661f638afd870d55c7d441fb8bcffe1c1b392 100644 (file)
@@ -8,13 +8,12 @@
 package org.opendaylight.controller.netconf.persist.impl;
 
 import org.opendaylight.controller.config.persist.api.PropertiesProvider;
-import org.opendaylight.controller.netconf.persist.impl.osgi.PropertiesProviderBaseImpl;
 
 public class PropertiesProviderAdapterImpl implements PropertiesProvider {
-    private final PropertiesProviderBaseImpl inner;
+    private final PropertiesProvider inner;
     private final String index;
 
-    public PropertiesProviderAdapterImpl(PropertiesProviderBaseImpl inner, String index) {
+    public PropertiesProviderAdapterImpl(PropertiesProvider inner, String index) {
         this.inner = inner;
         this.index = index;
     }
@@ -29,6 +28,12 @@ public class PropertiesProviderAdapterImpl implements PropertiesProvider {
         return inner.getPrefix() + "." + index + ".properties";
     }
 
+    @Override
+    public String getPropertyWithoutPrefix(String fullKey) {
+        return inner.getPropertyWithoutPrefix(fullKey);
+    }
+
+
     @Override
     public String getFullKeyForReporting(String key) {
         return getPrefix()  + "." + key;
index 1a261da32342525c1eeaf52aca44e33803692a7c..87bbb50860322bcfcfc24be4b912700269757179 100644 (file)
@@ -62,7 +62,7 @@ public class ConfigPersisterActivator implements BundleActivator {
         long maxWaitForCapabilitiesMillis = getMaxWaitForCapabilitiesMillis(propertiesProvider);
         List<ConfigSnapshotHolder> configs = persisterAggregator.loadLastConfigs();
         long conflictingVersionTimeoutMillis = getConflictingVersionTimeoutMillis(propertiesProvider);
-        logger.trace("Following configs will be pushed: {}", configs);
+        logger.debug("Following configs will be pushed: {}", configs);
 
         InnerCustomizer innerCustomizer = new InnerCustomizer(configs, maxWaitForCapabilitiesMillis,
                 conflictingVersionTimeoutMillis, persisterAggregator);
index b1bf23292875611d40c6875fd1a05bb8d81b328e..e02e27a745a032e1f36414c63e9e93dfd55e41c1 100644 (file)
@@ -81,7 +81,7 @@ public class ConfigPersisterTest {
 
     // this means pushing of config was successful
     public void assertCannotRegisterAsJMXListener_pushWasSuccessful() {
-        handler.assertException(RuntimeException.class, "Cannot register as JMX listener to netconf");
+        handler.assertException(IllegalStateException.class, "Cannot register as JMX listener to netconf");
     }
 
     public NetconfOperationService getWorkingService(Document document) throws SAXException, IOException, NetconfDocumentedException {
index 0a084b0ff6fd3989bf4e0e98b72e444ab5da5ce4..8e62a147d25276535b656a4ed606701163de6111 100644 (file)
@@ -13,7 +13,7 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.mon
 
 /**
 **/
-public class LocationBuilder {
+public final class LocationBuilder {
 
     public static Location getDefaultInstance(String defaultValue) {
         return defaultValue.equals("NETCONF") ? new Location(Location.Enumeration.NETCONF) : new Location(new Uri(
diff --git a/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClient.java b/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClient.java
new file mode 100644 (file)
index 0000000..d98211d
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+ * 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.client;
+
+import io.netty.util.concurrent.Future;
+import io.netty.util.concurrent.GlobalEventExecutor;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.util.Set;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import org.opendaylight.controller.netconf.api.NetconfMessage;
+import org.opendaylight.protocol.framework.NeverReconnectStrategy;
+import org.opendaylight.protocol.framework.ReconnectStrategy;
+import org.opendaylight.protocol.framework.TimedReconnectStrategy;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Preconditions;
+import com.google.common.base.Stopwatch;
+import com.google.common.collect.Sets;
+
+/**
+ * @deprecated Use {@link NetconfClientDispatcher.createClient()} or {@link NetconfClientDispatcher.createReconnectingClient()} instead.
+ */
+@Deprecated
+public class NetconfClient implements Closeable {
+
+    private static final Logger logger = LoggerFactory.getLogger(NetconfClient.class);
+
+    public static final int DEFAULT_CONNECT_TIMEOUT = 5000;
+    private final NetconfClientDispatcher dispatch;
+    private final String label;
+    private final NetconfClientSession clientSession;
+    private final NetconfClientSessionListener sessionListener;
+    private final long sessionId;
+    private final InetSocketAddress address;
+
+    // TODO test reconnecting constructor
+    public NetconfClient(String clientLabelForLogging, InetSocketAddress address, int connectionAttempts,
+            int attemptMsTimeout, NetconfClientDispatcher netconfClientDispatcher) throws InterruptedException {
+        this(clientLabelForLogging, address, getReconnectStrategy(connectionAttempts, attemptMsTimeout),
+                netconfClientDispatcher);
+    }
+
+    private NetconfClient(String clientLabelForLogging, InetSocketAddress address, ReconnectStrategy strat, NetconfClientDispatcher netconfClientDispatcher) throws InterruptedException {
+        this.label = clientLabelForLogging;
+        dispatch = netconfClientDispatcher;
+        sessionListener = new SimpleNetconfClientSessionListener();
+        Future<NetconfClientSession> clientFuture = dispatch.createClient(address, sessionListener, strat);
+        this.address = address;
+        clientSession = get(clientFuture);
+        this.sessionId = clientSession.getSessionId();
+    }
+
+    private NetconfClientSession get(Future<NetconfClientSession> clientFuture) throws InterruptedException {
+        try {
+            return clientFuture.get();
+        } catch (CancellationException e) {
+            throw new RuntimeException("Cancelling " + this, e);
+        } catch (ExecutionException e) {
+            throw new IllegalStateException("Unable to create " + this, e);
+        }
+    }
+
+    public static NetconfClient clientFor(String clientLabelForLogging, InetSocketAddress address, ReconnectStrategy strategy, NetconfClientDispatcher netconfClientDispatcher) throws InterruptedException {
+        return new NetconfClient(clientLabelForLogging,address,strategy,netconfClientDispatcher);
+    }
+
+    public static NetconfClient clientFor(String clientLabelForLogging, InetSocketAddress address,
+            ReconnectStrategy strategy, NetconfClientDispatcher netconfClientDispatcher, NetconfClientSessionListener listener) throws InterruptedException {
+        return new NetconfClient(clientLabelForLogging,address,strategy,netconfClientDispatcher,listener);
+    }
+
+    public NetconfClient(String clientLabelForLogging, InetSocketAddress address, int connectTimeoutMs,
+            NetconfClientDispatcher netconfClientDispatcher) throws InterruptedException {
+        this(clientLabelForLogging, address,
+                new NeverReconnectStrategy(GlobalEventExecutor.INSTANCE, connectTimeoutMs), netconfClientDispatcher);
+    }
+
+    public NetconfClient(String clientLabelForLogging, InetSocketAddress address,
+            NetconfClientDispatcher netconfClientDispatcher) throws InterruptedException {
+        this(clientLabelForLogging, address, new NeverReconnectStrategy(GlobalEventExecutor.INSTANCE,
+                DEFAULT_CONNECT_TIMEOUT), netconfClientDispatcher);
+    }
+
+    public NetconfClient(String clientLabelForLogging, InetSocketAddress address, ReconnectStrategy strategy,
+            NetconfClientDispatcher netconfClientDispatcher, NetconfClientSessionListener listener) throws InterruptedException{
+        this.label = clientLabelForLogging;
+        dispatch = netconfClientDispatcher;
+        sessionListener = listener;
+        Future<NetconfClientSession> clientFuture = dispatch.createClient(address, sessionListener, strategy);
+        this.address = address;
+        clientSession = get(clientFuture);
+        this.sessionId = clientSession.getSessionId();
+    }
+
+    public Future<NetconfMessage> sendRequest(NetconfMessage message) {
+        return ((SimpleNetconfClientSessionListener)sessionListener).sendRequest(message);
+    }
+
+    /**
+     * @deprecated Use {@link sendRequest} instead
+     */
+    @Deprecated
+    public NetconfMessage sendMessage(NetconfMessage message) throws ExecutionException, InterruptedException, TimeoutException {
+        return sendMessage(message, 5, 1000);
+    }
+
+    /**
+     * @deprecated Use {@link sendRequest} instead
+     */
+    @Deprecated
+    public NetconfMessage sendMessage(NetconfMessage message, int attempts, int attemptMsDelay) throws ExecutionException, InterruptedException, TimeoutException {
+        final Stopwatch stopwatch = new Stopwatch().start();
+
+        try {
+            return sendRequest(message).get(attempts * attemptMsDelay, TimeUnit.MILLISECONDS);
+        } finally {
+            stopwatch.stop();
+            logger.debug("Total time spent waiting for response from {}: {} ms", address, stopwatch.elapsed(TimeUnit.MILLISECONDS));
+        }
+    }
+
+    @Override
+    public void close() throws IOException {
+        clientSession.close();
+    }
+
+    public NetconfClientDispatcher getNetconfClientDispatcher() {
+        return dispatch;
+    }
+
+    private static ReconnectStrategy getReconnectStrategy(int connectionAttempts, int attemptMsTimeout) {
+        return new TimedReconnectStrategy(GlobalEventExecutor.INSTANCE, attemptMsTimeout, 1000, 1.0, null,
+                Long.valueOf(connectionAttempts), null);
+    }
+
+    @Override
+    public String toString() {
+        final StringBuffer sb = new StringBuffer("NetconfClient{");
+        sb.append("label=").append(label);
+        sb.append(", sessionId=").append(sessionId);
+        sb.append('}');
+        return sb.toString();
+    }
+
+    public long getSessionId() {
+        return sessionId;
+    }
+
+    public Set<String> getCapabilities() {
+        Preconditions.checkState(clientSession != null, "Client was not initialized successfully");
+        return Sets.newHashSet(clientSession.getServerCapabilities());
+    }
+
+    public NetconfClientSession getClientSession() {
+        return clientSession;
+    }
+}
index 20da6aa86934a71eb91a4461988d8d1097babba8..c7c723cb27b552fa51b7a7a287f66306649f35ca 100644 (file)
@@ -79,7 +79,7 @@ public class NetconfClientDispatcher extends AbstractDispatcher<NetconfClientSes
         });
     }
 
-    private static class ClientChannelInitializer extends AbstractChannelInitializer<NetconfClientSession> {
+    private static final class ClientChannelInitializer extends AbstractChannelInitializer<NetconfClientSession> {
 
         private final NetconfClientSessionNegotiatorFactory negotiatorFactory;
         private final NetconfClientSessionListener sessionListener;
index ad50fedf6b564fbef12cfd6f8e3308b717d9515a..f4efb1fc7dc9bf56cd3176c769f72c312ee351d2 100644 (file)
@@ -8,7 +8,8 @@
 
 package org.opendaylight.controller.netconf.client;
 
-import io.netty.channel.Channel;
+import java.util.Collection;
+
 import org.opendaylight.controller.netconf.util.AbstractNetconfSession;
 import org.opendaylight.controller.netconf.util.handler.NetconfEXICodec;
 import org.opendaylight.controller.netconf.util.handler.NetconfEXIToMessageDecoder;
@@ -18,7 +19,7 @@ import org.opendaylight.controller.netconf.util.handler.NetconfXMLToMessageDecod
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.util.Collection;
+import io.netty.channel.Channel;
 
 public final class NetconfClientSession extends AbstractNetconfSession<NetconfClientSession, NetconfClientSessionListener> {
 
@@ -36,7 +37,6 @@ public final class NetconfClientSession extends AbstractNetconfSession<NetconfCl
         return capabilities;
     }
 
-
     @Override
     protected NetconfClientSession thisInstance() {
         return this;
index f8f73fc8e5296b9534e0759bc43f24bbf493521e..0c5935b57162b44354a0db08a734886d18bd386a 100644 (file)
@@ -8,13 +8,14 @@
 
 package org.opendaylight.controller.netconf.client;
 
-import io.netty.channel.Channel;
 import io.netty.channel.ChannelFuture;
 import io.netty.channel.ChannelFutureListener;
 import io.netty.channel.ChannelHandlerContext;
 import io.netty.channel.ChannelInboundHandlerAdapter;
-import io.netty.util.Timer;
-import io.netty.util.concurrent.Promise;
+import java.util.Collection;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpression;
+
 import org.opendaylight.controller.netconf.api.NetconfClientSessionPreferences;
 import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
 import org.opendaylight.controller.netconf.api.NetconfMessage;
@@ -22,6 +23,7 @@ import org.opendaylight.controller.netconf.util.AbstractChannelInitializer;
 import org.opendaylight.controller.netconf.util.AbstractNetconfSessionNegotiator;
 import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessage;
 import org.opendaylight.controller.netconf.util.messages.NetconfMessageUtil;
+import org.opendaylight.controller.netconf.util.messages.NetconfStartExiMessage;
 import org.opendaylight.controller.netconf.util.xml.XMLNetconfUtil;
 import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
 import org.opendaylight.controller.netconf.util.xml.XmlUtil;
@@ -31,8 +33,9 @@ import org.w3c.dom.Document;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
 
-import javax.xml.xpath.XPathConstants;
-import javax.xml.xpath.XPathExpression;
+import io.netty.channel.Channel;
+import io.netty.util.Timer;
+import io.netty.util.concurrent.Promise;
 
 public class NetconfClientSessionNegotiator extends
         AbstractNetconfSessionNegotiator<NetconfClientSessionPreferences, NetconfClientSession, NetconfClientSessionListener>
@@ -55,19 +58,45 @@ public class NetconfClientSessionNegotiator extends
 
     @Override
     protected void handleMessage(NetconfHelloMessage netconfMessage) throws NetconfDocumentedException {
-        NetconfClientSession session = super.getSessionForHelloMessage(netconfMessage);
-
-        if (shouldUseExi(netconfMessage.getDocument())){
-            logger.debug("Netconf session: {} should use exi.", session);
-            tryToStartExi(session);
+        final NetconfClientSession session = getSessionForHelloMessage(netconfMessage);
+        replaceHelloMessageInboundHandler(session);
+
+        // If exi should be used, try to initiate exi communication
+        // Call negotiationSuccessFul after exi negotiation is finished successfully or not
+        if (shouldUseExi(netconfMessage)) {
+            logger.debug("Netconf session {} should use exi.", session);
+            NetconfStartExiMessage startExiMessage = (NetconfStartExiMessage) sessionPreferences.getStartExiMessage();
+            tryToInitiateExi(session, startExiMessage);
+        // Exi is not supported, release session immediately
         } else {
             logger.debug("Netconf session {} isn't capable using exi.", session);
             negotiationSuccessful(session);
         }
     }
 
-    private boolean shouldUseExi(Document doc) {
-        return containsExi10Capability(doc)
+    /**
+     * Initiates exi communication by sending start-exi message and waiting for positive/negative response.
+     *
+     * @param startExiMessage
+     */
+    void tryToInitiateExi(final NetconfClientSession session, final NetconfStartExiMessage startExiMessage) {
+        session.sendMessage(startExiMessage).addListener(new ChannelFutureListener() {
+            @Override
+            public void operationComplete(final ChannelFuture f) {
+                if (!f.isSuccess()) {
+                    logger.warn("Failed to send start-exi message {} on session {}", startExiMessage, this, f.cause());
+                } else {
+                    logger.trace("Start-exi message {} sent to socket on session {}", startExiMessage, this);
+                    channel.pipeline().addAfter(
+                            AbstractChannelInitializer.NETCONF_MESSAGE_DECODER, ExiConfirmationInboundHandler.EXI_CONFIRMED_HANDLER,
+                            new ExiConfirmationInboundHandler(session, startExiMessage));
+                }
+            }
+        });
+    }
+
+    private boolean shouldUseExi(NetconfHelloMessage helloMsg) {
+        return containsExi10Capability(helloMsg.getDocument())
                 && containsExi10Capability(sessionPreferences.getHelloMessage().getDocument());
     }
 
@@ -81,23 +110,6 @@ public class NetconfClientSessionNegotiator extends
         return false;
     }
 
-    private void tryToStartExi(final NetconfClientSession session) {
-        final NetconfMessage startExi = sessionPreferences.getStartExiMessage();
-        session.sendMessage(startExi).addListener(new ChannelFutureListener() {
-            @Override
-            public void operationComplete(final ChannelFuture f) {
-                if (!f.isSuccess()) {
-                    logger.warn("Failed to send start-exi message {} on session {}", startExi, session, f.cause());
-                } else {
-                    logger.trace("Start-exi message {} sent to socket on session {}", startExi, session);
-                    NetconfClientSessionNegotiator.this.channel.pipeline().addAfter(
-                            AbstractChannelInitializer.NETCONF_MESSAGE_DECODER, ExiConfirmationInboundHandler.EXI_CONFIRMED_HANDLER,
-                            new ExiConfirmationInboundHandler(session));
-                }
-            }
-        });
-    }
-
     private long extractSessionId(Document doc) {
         final Node sessionIdNode = (Node) XmlUtil.evaluateXPath(sessionIdXPath, doc, XPathConstants.NODE);
         String textContent = sessionIdNode.getTextContent();
@@ -109,9 +121,11 @@ public class NetconfClientSessionNegotiator extends
     }
 
     @Override
-    protected NetconfClientSession getSession(NetconfClientSessionListener sessionListener, Channel channel, NetconfHelloMessage message) throws NetconfDocumentedException {
-        return new NetconfClientSession(sessionListener, channel, extractSessionId(message.getDocument()),
-                NetconfMessageUtil.extractCapabilitiesFromHello(message.getDocument()));
+    protected NetconfClientSession getSession(NetconfClientSessionListener sessionListener, Channel channel,
+            NetconfHelloMessage message) throws NetconfDocumentedException {
+        long sessionId = extractSessionId(message.getDocument());
+        Collection<String> capabilities = NetconfMessageUtil.extractCapabilitiesFromHello(message.getDocument());
+        return new NetconfClientSession(sessionListener, channel, sessionId, capabilities);
     }
 
     /**
@@ -121,9 +135,11 @@ public class NetconfClientSessionNegotiator extends
         private static final String EXI_CONFIRMED_HANDLER = "exiConfirmedHandler";
 
         private final NetconfClientSession session;
+        private NetconfStartExiMessage startExiMessage;
 
-        ExiConfirmationInboundHandler(NetconfClientSession session) {
+        ExiConfirmationInboundHandler(NetconfClientSession session, final NetconfStartExiMessage startExiMessage) {
             this.session = session;
+            this.startExiMessage = startExiMessage;
         }
 
         @Override
@@ -136,19 +152,19 @@ public class NetconfClientSessionNegotiator extends
             if (NetconfMessageUtil.isOKMessage(netconfMessage)) {
                 logger.trace("Positive response on start-exi call received on session {}", session);
                 try {
-                    session.startExiCommunication(sessionPreferences.getStartExiMessage());
+                    session.startExiCommunication(startExiMessage);
                 } catch (RuntimeException e) {
                     // Unable to add exi, continue without exi
                     logger.warn("Unable to start exi communication, Communication will continue without exi on session {}", session, e);
                 }
 
-            // Error response
+                // Error response
             } else if(NetconfMessageUtil.isErrorMessage(netconfMessage)) {
                 logger.warn(
                         "Error response to start-exi message {}, Communication will continue without exi on session {}",
                         XmlUtil.toString(netconfMessage.getDocument()), session);
 
-            // Unexpected response to start-exi, throwing message away, continue without exi
+                // Unexpected response to start-exi, throwing message away, continue without exi
             } else {
                 logger.warn(
                         "Unexpected response to start-exi message, should be ok, was {}, " +
@@ -159,4 +175,5 @@ public class NetconfClientSessionNegotiator extends
             negotiationSuccessful(session);
         }
     }
+
 }
index 9e15b49a843c677cdc12ae6bee2a927a2f891df7..e65adc3fdf5b736522592a55e5c81d8fa8f37451 100644 (file)
@@ -33,8 +33,8 @@ import org.slf4j.LoggerFactory;
 public class NetconfClientSessionNegotiatorFactory implements SessionNegotiatorFactory<NetconfMessage, NetconfClientSession, NetconfClientSessionListener> {
 
     public static final java.util.Set<String> CLIENT_CAPABILITIES = Sets.newHashSet(
-            XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0,
-            XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_1,
+            XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_BASE_1_0,
+            XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_BASE_1_1,
             XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_CAPABILITY_EXI_1_0);
 
     private static final String START_EXI_MESSAGE_ID = "default-start-exi";
@@ -74,7 +74,7 @@ public class NetconfClientSessionNegotiatorFactory implements SessionNegotiatorF
             throw new IllegalStateException(e);
         }
 
-        NetconfClientSessionPreferences proposal = new NetconfClientSessionPreferences(helloMessage,startExiMessage);
+        NetconfClientSessionPreferences proposal = new NetconfClientSessionPreferences(helloMessage, startExiMessage);
         return new NetconfClientSessionNegotiator(proposal, promise, channel, timer,
                 sessionListenerFactory.getSessionListener(),connectionTimeoutMillis);
     }
index 504e4c994915aeafc5d303fc2a56ab4bcf2722d8..524f0b52b7e22f4dc01317d5c7cf7dbcc1c045a0 100644 (file)
@@ -26,8 +26,8 @@ import com.google.common.base.Preconditions;
 
 public class SimpleNetconfClientSessionListener implements NetconfClientSessionListener {
     private static final class RequestEntry {
-        final Promise<NetconfMessage> promise;
-        final NetconfMessage request;
+        private final Promise<NetconfMessage> promise;
+        private final NetconfMessage request;
 
         public RequestEntry(Promise<NetconfMessage> future, NetconfMessage request) {
             this.promise = Preconditions.checkNotNull(future);
index 6a86ecd21f4d81fdfa9db9de1a81d6e28e1d9488..91385bab33e5102659e72c7f42a435f509b5c1fa 100644 (file)
@@ -68,12 +68,11 @@ public class CapabilityProviderImpl implements CapabilityProvider {
             final Set<Capability> caps = netconfOperationService.getCapabilities();
 
             for (Capability cap : caps) {
-                if (cap.getModuleName().isPresent() == false)
-                    continue;
-                if (cap.getRevision().isPresent() == false)
-                    continue;
-                if (cap.getCapabilitySchema().isPresent() == false)
+                if (!cap.getModuleName().isPresent()
+                        || !cap.getRevision().isPresent()
+                        || !cap.getCapabilitySchema().isPresent()){
                     continue;
+                }
 
                 final String currentModuleName = cap.getModuleName().get();
                 Map<String, String> revisionMap = mappedModulesToRevisionToSchema.get(currentModuleName);
index 4461054437ce61ef47fd2eea76a9b23ae15b5ef3..203fdf272584015f40f8bde0dd4e80b753eb51f0 100644 (file)
@@ -35,6 +35,7 @@ public class DefaultCommitNotificationProducer extends NotificationBroadcasterSu
 
     public DefaultCommitNotificationProducer(MBeanServer mBeanServer) {
         this.mbeanServer = mBeanServer;
+        logger.debug("Registering to JMX under {}", on);
         registerMBean(this, mbeanServer, on);
     }
 
@@ -42,7 +43,7 @@ public class DefaultCommitNotificationProducer extends NotificationBroadcasterSu
         try {
             mbs.registerMBean(instance, on);
         } catch (InstanceAlreadyExistsException | MBeanRegistrationException | NotCompliantMBeanException e) {
-            throw new RuntimeException("Unable to register " + instance + " as " + on, e);
+            throw new IllegalStateException("Unable to register " + instance + " as " + on, e);
         }
     }
 
index b3245fff2b812775803acf59e1c2e53aa875d77e..75be1f8fe01647beeabbcb1101bd5265c7813578 100644 (file)
@@ -9,6 +9,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.netconf.api.NetconfMessage;
 import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationRouter;
@@ -26,9 +28,6 @@ import org.w3c.dom.Document;
 import org.w3c.dom.NamedNodeMap;
 import org.w3c.dom.Node;
 
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableMap;
-
 public class NetconfServerSessionListener implements NetconfSessionListener<NetconfServerSession> {
 
     static final Logger logger = LoggerFactory.getLogger(NetconfServerSessionListener.class);
@@ -97,8 +96,9 @@ public class NetconfServerSessionListener implements NetconfSessionListener<Netc
             // TODO: should send generic error or close session?
             logger.error("Unexpected exception", e);
             session.onIncommingRpcFail();
-            throw new RuntimeException("Unable to process incoming message " + netconfMessage, e);
+            throw new IllegalStateException("Unable to process incoming message " + netconfMessage, e);
         } catch (NetconfDocumentedException e) {
+            logger.trace("Error occured while processing mesage {}",e);
             session.onOutgoingRpcError();
             session.onIncommingRpcFail();
             SendErrorExceptionUtil.sendErrorMessage(session, e, netconfMessage);
index 5c389fa966af340ef277f5d51ebe992b2c6081ff..6528fe251775694e8ea47cf59b094d0efcc07ddf 100644 (file)
@@ -8,10 +8,9 @@
 
 package org.opendaylight.controller.netconf.impl;
 
-import com.google.common.base.Optional;
-import io.netty.channel.Channel;
-import io.netty.util.Timer;
-import io.netty.util.concurrent.Promise;
+import java.net.InetSocketAddress;
+
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
 import org.opendaylight.controller.netconf.api.NetconfServerSessionPreferences;
 import org.opendaylight.controller.netconf.util.AbstractNetconfSessionNegotiator;
 import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessage;
@@ -19,7 +18,11 @@ import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAddi
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.net.InetSocketAddress;
+import com.google.common.base.Optional;
+
+import io.netty.channel.Channel;
+import io.netty.util.Timer;
+import io.netty.util.concurrent.Promise;
 
 public class NetconfServerSessionNegotiator extends
         AbstractNetconfSessionNegotiator<NetconfServerSessionPreferences, NetconfServerSession, NetconfServerSessionListener> {
@@ -32,6 +35,14 @@ public class NetconfServerSessionNegotiator extends
         super(sessionPreferences, promise, channel, timer, sessionListener, connectionTimeoutMillis);
     }
 
+    @Override
+    protected void handleMessage(NetconfHelloMessage netconfMessage) throws NetconfDocumentedException {
+        NetconfServerSession session = getSessionForHelloMessage(netconfMessage);
+        replaceHelloMessageInboundHandler(session);
+        // Negotiation successful after all non hello messages were processed
+        negotiationSuccessful(session);
+    }
+
     @Override
     protected NetconfServerSession getSession(NetconfServerSessionListener sessionListener, Channel channel, NetconfHelloMessage message) {
         Optional<NetconfHelloMessageAdditionalHeader> additionalHeader = message.getAdditionalHeader();
index 9d958660615c27c27e86fee68e669f7e17c6a1b1..d5a34d11b244681b1540ff95bae22b26ba607670 100644 (file)
@@ -8,10 +8,12 @@
 
 package org.opendaylight.controller.netconf.impl;
 
-import com.google.common.collect.Sets;
-import io.netty.channel.Channel;
-import io.netty.util.Timer;
-import io.netty.util.concurrent.Promise;
+import static org.opendaylight.controller.netconf.mapping.api.NetconfOperationProvider.NetconfOperationProviderUtil.getNetconfSessionIdForReporting;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableSet;
+import java.util.Set;
+
 import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
 import org.opendaylight.controller.netconf.api.NetconfServerSessionPreferences;
 import org.opendaylight.controller.netconf.impl.mapping.CapabilityProvider;
@@ -23,18 +25,22 @@ import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
 import org.opendaylight.protocol.framework.SessionListenerFactory;
 import org.opendaylight.protocol.framework.SessionNegotiator;
 import org.opendaylight.protocol.framework.SessionNegotiatorFactory;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
-import java.util.Set;
+import com.google.common.collect.Sets;
 
-import static org.opendaylight.controller.netconf.mapping.api.NetconfOperationProvider.NetconfOperationProviderUtil.getNetconfSessionIdForReporting;
+import io.netty.channel.Channel;
+import io.netty.util.Timer;
+import io.netty.util.concurrent.Promise;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class NetconfServerSessionNegotiatorFactory implements SessionNegotiatorFactory<NetconfHelloMessage, NetconfServerSession, NetconfServerSessionListener> {
 
-    private static final Set<String> DEFAULT_CAPABILITIES = Sets.newHashSet(
-            XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0,
-            XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_CAPABILITY_EXI_1_0);
+    public static final Set<String> DEFAULT_BASE_CAPABILITIES = ImmutableSet.of(
+            XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_BASE_1_0,
+            XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_BASE_1_1,
+            XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_CAPABILITY_EXI_1_0
+    );
 
     private final Timer timer;
 
@@ -44,16 +50,42 @@ public class NetconfServerSessionNegotiatorFactory implements SessionNegotiatorF
     private final DefaultCommitNotificationProducer commitNotificationProducer;
     private final SessionMonitoringService monitoringService;
     private static final Logger logger = LoggerFactory.getLogger(NetconfServerSessionNegotiatorFactory.class);
+    private final Set<String> baseCapabilities;
+
+    // TODO too many params, refactor
+    public NetconfServerSessionNegotiatorFactory(Timer timer, NetconfOperationProvider netconfOperationProvider,
+                                                 SessionIdProvider idProvider, long connectionTimeoutMillis,
+                                                 DefaultCommitNotificationProducer commitNot,
+                                                 SessionMonitoringService monitoringService) {
+        this(timer, netconfOperationProvider, idProvider, connectionTimeoutMillis, commitNot, monitoringService, DEFAULT_BASE_CAPABILITIES);
+    }
 
+    // TODO too many params, refactor
     public NetconfServerSessionNegotiatorFactory(Timer timer, NetconfOperationProvider netconfOperationProvider,
                                                  SessionIdProvider idProvider, long connectionTimeoutMillis,
-                                                 DefaultCommitNotificationProducer commitNot, SessionMonitoringService monitoringService) {
+                                                 DefaultCommitNotificationProducer commitNot,
+                                                 SessionMonitoringService monitoringService, Set<String> baseCapabilities) {
         this.timer = timer;
         this.netconfOperationProvider = netconfOperationProvider;
         this.idProvider = idProvider;
         this.connectionTimeoutMillis = connectionTimeoutMillis;
         this.commitNotificationProducer = commitNot;
         this.monitoringService = monitoringService;
+        this.baseCapabilities = validateBaseCapabilities(baseCapabilities);
+    }
+
+    private ImmutableSet<String> validateBaseCapabilities(final Set<String> baseCapabilities) {
+        // Check base capabilities to be supported by the server
+        Sets.SetView<String> unknownBaseCaps = Sets.difference(baseCapabilities, DEFAULT_BASE_CAPABILITIES);
+        Preconditions.checkArgument(unknownBaseCaps.isEmpty(),
+                "Base capabilities that will be supported by netconf server have to be subset of %s, unknown base capabilities: %s",
+                DEFAULT_BASE_CAPABILITIES, unknownBaseCaps);
+
+        ImmutableSet.Builder<String> b = ImmutableSet.builder();
+        b.addAll(baseCapabilities);
+        // Base 1.0 capability is supported by default
+        b.add(XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_BASE_1_0);
+        return b.build();
     }
 
     /**
@@ -91,7 +123,7 @@ public class NetconfServerSessionNegotiatorFactory implements SessionNegotiatorF
     }
 
     private NetconfHelloMessage createHelloMessage(long sessionId, CapabilityProvider capabilityProvider) throws NetconfDocumentedException {
-        return NetconfHelloMessage.createServerHello(Sets.union(capabilityProvider.getCapabilities(), DEFAULT_CAPABILITIES), sessionId);
+        return NetconfHelloMessage.createServerHello(Sets.union(capabilityProvider.getCapabilities(), baseCapabilities), sessionId);
     }
 
 }
index d6940a1a453fcaaf14f4e6e30292f8dbc427256d..d4545430b47834ae8604737a50762056fd712526 100644 (file)
@@ -64,14 +64,14 @@ public class DefaultCommit extends AbstractNetconfOperation {
 
     @Override
     public Document handle(Document requestMessage, NetconfOperationChainedExecution subsequentOperation) throws NetconfDocumentedException {
-        Preconditions.checkArgument(subsequentOperation.isExecutionTermination() == false,
+        Preconditions.checkArgument(!subsequentOperation.isExecutionTermination(),
                 "Subsequent netconf operation expected by %s", this);
 
         if (isCommitWithoutNotification(requestMessage)) {
             logger.debug("Skipping commit notification");
         } else {
             // Send commit notification if commit was not issued by persister
-            requestMessage = removePersisterAttributes(requestMessage);
+            removePersisterAttributes(requestMessage);
             Element cfgSnapshot = getConfigSnapshot(operationRouter);
             logger.debug("Config snapshot retrieved successfully {}", cfgSnapshot);
             notificationProducer.sendCommitNotification("ok", cfgSnapshot, cap.getCapabilities());
@@ -90,10 +90,8 @@ public class DefaultCommit extends AbstractNetconfOperation {
         return HandlingPriority.HANDLE_WITH_DEFAULT_PRIORITY.increasePriority(1);
     }
 
-    private Document removePersisterAttributes(Document message) {
-        final Element documentElement = message.getDocumentElement();
-        documentElement.removeAttribute(NOTIFY_ATTR);
-        return message;
+    private void removePersisterAttributes(Document message) {
+        message.getDocumentElement().removeAttribute(NOTIFY_ATTR);
     }
 
     private boolean isCommitWithoutNotification(Document message) {
@@ -108,9 +106,9 @@ public class DefaultCommit extends AbstractNetconfOperation {
 
         String attr = xmlElement.getAttribute(NOTIFY_ATTR);
 
-        if (attr == null || attr.equals(""))
+        if (attr == null || attr.equals("")){
             return false;
-        else if (attr.equals(Boolean.toString(false))) {
+        else if (attr.equals(Boolean.toString(false))) {
             logger.debug("Commit operation received with notify=false attribute {}", message);
             return true;
         } else {
index bbd07e42bf515c46dec0a6900bd2105f3140596f..303047df12b6fae6c77e964b702cb23a9ed52b59 100644 (file)
@@ -39,7 +39,7 @@ public class NetconfImplActivator implements BundleActivator {
     private ServiceRegistration<NetconfMonitoringService> regMonitoring;
 
     @Override
-    public void start(final BundleContext context) throws Exception {
+    public void start(final BundleContext context)  {
         InetSocketAddress address = NetconfConfigUtil.extractTCPNetconfAddress(context,
                 "TCP is not configured, netconf not available.", false);
 
@@ -85,7 +85,7 @@ public class NetconfImplActivator implements BundleActivator {
     }
 
     @Override
-    public void stop(final BundleContext context) throws Exception {
+    public void stop(final BundleContext context) {
         logger.info("Shutting down netconf because YangStoreService service was removed");
 
         commitNot.close();
index a7560fadb602cc450f84c71e2f9936cb131cd495..81fac5f12f9c7dc9d3bf40922c19723836c036ce 100644 (file)
@@ -51,7 +51,7 @@ public class NetconfMonitoringServiceImpl implements NetconfMonitoringService, S
     @Override
     public void onSessionUp(NetconfManagementSession session) {
         logger.debug("Session {} up", session);
-        Preconditions.checkState(sessions.contains(session) == false, "Session %s was already added", session);
+        Preconditions.checkState(!sessions.contains(session), "Session %s was already added", session);
         sessions.add(session);
     }
 
index c2ab36f2c68ac8478d89fc14b02b6729e0ccf072..ff96ad779fbc974539ced455494129381bb09635 100644 (file)
@@ -17,9 +17,9 @@ import org.opendaylight.controller.netconf.impl.mapping.CapabilityProvider;
 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.DefaultGetSchema;
+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;
-import org.opendaylight.controller.netconf.impl.mapping.operations.DefaultNetconfOperation;
 import org.opendaylight.controller.netconf.mapping.api.HandlingPriority;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperation;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperationChainedExecution;
@@ -33,6 +33,7 @@ import org.w3c.dom.Document;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.Map;
+import java.util.NavigableMap;
 import java.util.Set;
 import java.util.TreeMap;
 
@@ -83,7 +84,7 @@ public class NetconfOperationRouterImpl implements NetconfOperationRouter {
         for (NetconfOperationService netconfOperationService : netconfOperationServiceSnapshot.getServices()) {
             final Set<NetconfOperation> netOpsFromService = netconfOperationService.getNetconfOperations();
             for (NetconfOperation netconfOperation : netOpsFromService) {
-                Preconditions.checkState(result.contains(netconfOperation) == false,
+                Preconditions.checkState(!result.contains(netconfOperation),
                         "Netconf operation %s already present", netconfOperation);
                 result.add(netconfOperation);
             }
@@ -97,9 +98,10 @@ public class NetconfOperationRouterImpl implements NetconfOperationRouter {
         Preconditions.checkNotNull(allNetconfOperations, "Operation router was not initialized properly");
 
         NetconfOperationExecution netconfOperationExecution;
-        String messageAsString = XmlUtil.toString(message);
 
+        String messageAsString = "";
         try {
+            messageAsString = XmlUtil.toString(message);
             netconfOperationExecution = getNetconfOperationWithHighestPriority(message, session);
         } catch (IllegalArgumentException | IllegalStateException e) {
             logger.warn("Unable to handle rpc {} on session {}", messageAsString, session, e);
@@ -155,7 +157,7 @@ public class NetconfOperationRouterImpl implements NetconfOperationRouter {
     private NetconfOperationExecution getNetconfOperationWithHighestPriority(
             Document message, NetconfServerSession session) throws NetconfDocumentedException {
 
-        TreeMap<HandlingPriority, NetconfOperation> sortedByPriority = getSortedNetconfOperationsWithCanHandle(
+        NavigableMap<HandlingPriority, NetconfOperation> sortedByPriority = getSortedNetconfOperationsWithCanHandle(
                 message, session);
 
         Preconditions.checkArgument(sortedByPriority.isEmpty() == false,
@@ -174,9 +176,9 @@ public class NetconfOperationRouterImpl implements NetconfOperationRouter {
             if (netconfOperation instanceof DefaultNetconfOperation) {
                 ((DefaultNetconfOperation) netconfOperation).setNetconfSession(session);
             }
-            if (handlingPriority.equals(HandlingPriority.CANNOT_HANDLE) == false) {
+            if (!handlingPriority.equals(HandlingPriority.CANNOT_HANDLE)) {
 
-                Preconditions.checkState(sortedPriority.containsKey(handlingPriority) == false,
+                Preconditions.checkState(!sortedPriority.containsKey(handlingPriority),
                         "Multiple %s available to handle message %s with priority %s",
                         NetconfOperation.class.getName(), message, handlingPriority);
                 sortedPriority.put(handlingPriority, netconfOperation);
@@ -220,7 +222,7 @@ public class NetconfOperationRouterImpl implements NetconfOperationRouter {
         }
 
         public static NetconfOperationExecution createExecutionChain(
-                TreeMap<HandlingPriority, NetconfOperation> sortedByPriority, HandlingPriority handlingPriority) {
+                NavigableMap<HandlingPriority, NetconfOperation> sortedByPriority, HandlingPriority handlingPriority) {
             NetconfOperation netconfOperation = sortedByPriority.get(handlingPriority);
             HandlingPriority subsequentHandlingPriority = sortedByPriority.lowerKey(handlingPriority);
 
index db5a359d7a16c72784911a447b2756de36356b42..0a0cd2208891982efce68832bb66d46e29fe9cb3 100644 (file)
@@ -8,20 +8,47 @@
 
 package org.opendaylight.controller.netconf.impl;
 
-import com.google.common.base.Optional;
-import com.google.common.collect.Sets;
-import io.netty.channel.ChannelFuture;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.mock;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Lists;
 import io.netty.channel.EventLoopGroup;
-import io.netty.channel.nio.NioEventLoopGroup;
 import io.netty.util.HashedWheelTimer;
+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;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.atomic.AtomicLong;
 import org.apache.commons.io.IOUtils;
 import org.junit.After;
+import org.junit.AfterClass;
 import org.junit.Before;
+import org.junit.BeforeClass;
 import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
 import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
 import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.client.test.TestingNetconfClient;
 import org.opendaylight.controller.netconf.client.NetconfClientDispatcher;
+import org.opendaylight.controller.netconf.client.test.TestingNetconfClient;
 import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceFactoryListenerImpl;
 import org.opendaylight.controller.netconf.impl.osgi.SessionMonitoringService;
 import org.opendaylight.controller.netconf.mapping.api.Capability;
@@ -31,45 +58,61 @@ import org.opendaylight.controller.netconf.mapping.api.NetconfOperationChainedEx
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactory;
 import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader;
+import org.opendaylight.controller.netconf.util.messages.NetconfMessageUtil;
+import org.opendaylight.controller.netconf.util.messages.NetconfStartExiMessage;
 import org.opendaylight.controller.netconf.util.test.XmlFileLoader;
+import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
 import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
 
-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.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
+import com.google.common.collect.Sets;
 
-import static com.google.common.base.Preconditions.checkNotNull;
-import static org.junit.Assert.fail;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.mock;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.nio.NioEventLoopGroup;
 
+@RunWith(Parameterized.class)
 public class ConcurrentClientsTest {
+    private static final Logger logger = LoggerFactory.getLogger(ConcurrentClientsTest.class);
 
-    private static final int CONCURRENCY = 16;
-    private EventLoopGroup nettyGroup;
-    private NetconfClientDispatcher netconfClientDispatcher;
+    private static ExecutorService clientExecutor;
 
-    private final InetSocketAddress netconfAddress = new InetSocketAddress("127.0.0.1", 8303);
+    private static final int CONCURRENCY = 32;
+    private static final InetSocketAddress netconfAddress = new InetSocketAddress("127.0.0.1", 8303);
 
-    static final Logger logger = LoggerFactory.getLogger(ConcurrentClientsTest.class);
+    private int nettyThreads;
+    private Class<? extends Runnable> clientRunnable;
+    private Set<String> serverCaps;
 
-    private DefaultCommitNotificationProducer commitNot;
-    private NetconfServerDispatcher dispatch;
+    public ConcurrentClientsTest(int nettyThreads, Class<? extends Runnable> clientRunnable, Set<String> serverCaps) {
+        this.nettyThreads = nettyThreads;
+        this.clientRunnable = clientRunnable;
+        this.serverCaps = serverCaps;
+    }
+
+    @Parameterized.Parameters()
+    public static Collection<Object[]> data() {
+        return Arrays.asList(new Object[][]{
+                {4, TestingNetconfClientRunnable.class, NetconfServerSessionNegotiatorFactory.DEFAULT_BASE_CAPABILITIES},
+                {1, TestingNetconfClientRunnable.class, NetconfServerSessionNegotiatorFactory.DEFAULT_BASE_CAPABILITIES},
+                // empty set of capabilities = only base 1.0 netconf capability
+                {4, TestingNetconfClientRunnable.class, Collections.emptySet()},
+                {4, TestingNetconfClientRunnable.class, getOnlyExiServerCaps()},
+                {4, TestingNetconfClientRunnable.class, getOnlyChunkServerCaps()},
+
+                {4, BlockingClientRunnable.class, getOnlyExiServerCaps()},
+                {1, BlockingClientRunnable.class, getOnlyExiServerCaps()},
+        });
+    }
 
+    private EventLoopGroup nettyGroup;
+    private NetconfClientDispatcher netconfClientDispatcher;
 
+    private DefaultCommitNotificationProducer commitNot;
 
     HashedWheelTimer hashedWheelTimer;
+    private TestingNetconfOperation testingNetconfOperation;
 
     public static SessionMonitoringService createMockedMonitoringService() {
         SessionMonitoringService monitoring = mock(SessionMonitoringService.class);
@@ -78,27 +121,43 @@ public class ConcurrentClientsTest {
         return monitoring;
     }
 
+    @BeforeClass
+    public static void setUpClientExecutor() {
+        clientExecutor = Executors.newFixedThreadPool(CONCURRENCY, new ThreadFactory() {
+            int i = 1;
+
+            @Override
+            public Thread newThread(final Runnable r) {
+                Thread thread = new Thread(r);
+                thread.setName("client-" + i++);
+                thread.setDaemon(true);
+                return thread;
+            }
+        });
+    }
+
     @Before
     public void setUp() throws Exception {
 
-        nettyGroup = new NioEventLoopGroup();
+        nettyGroup = new NioEventLoopGroup(nettyThreads);
         NetconfHelloMessageAdditionalHeader additionalHeader = new NetconfHelloMessageAdditionalHeader("uname", "10.10.10.1", "830", "tcp", "client");
         netconfClientDispatcher = new NetconfClientDispatcher( nettyGroup, nettyGroup, additionalHeader, 5000);
 
         NetconfOperationServiceFactoryListenerImpl factoriesListener = new NetconfOperationServiceFactoryListenerImpl();
-        factoriesListener.onAddNetconfOperationServiceFactory(mockOpF());
+
+        testingNetconfOperation = new TestingNetconfOperation();
+        factoriesListener.onAddNetconfOperationServiceFactory(new TestingOperationServiceFactory(testingNetconfOperation));
 
         SessionIdProvider idProvider = new SessionIdProvider();
         hashedWheelTimer = new HashedWheelTimer();
+
         NetconfServerSessionNegotiatorFactory serverNegotiatorFactory = new NetconfServerSessionNegotiatorFactory(
-                hashedWheelTimer, factoriesListener, idProvider, 5000, commitNot, createMockedMonitoringService());
+                hashedWheelTimer, factoriesListener, idProvider, 5000, commitNot, createMockedMonitoringService(), serverCaps);
 
         commitNot = new DefaultCommitNotificationProducer(ManagementFactory.getPlatformMBeanServer());
 
-
-
         NetconfServerDispatcher.ServerChannelInitializer serverChannelInitializer = new NetconfServerDispatcher.ServerChannelInitializer(serverNegotiatorFactory);
-        dispatch = new NetconfServerDispatcher(serverChannelInitializer, nettyGroup, nettyGroup);
+        final NetconfServerDispatcher dispatch = new NetconfServerDispatcher(serverChannelInitializer, nettyGroup, nettyGroup);
 
         ChannelFuture s = dispatch.createServer(netconfAddress);
         s.await();
@@ -106,111 +165,131 @@ public class ConcurrentClientsTest {
 
     @After
     public void tearDown(){
+        commitNot.close();
         hashedWheelTimer.stop();
-        nettyGroup.shutdownGracefully();
+        try {
+            nettyGroup.shutdownGracefully().get();
+        } catch (InterruptedException | ExecutionException e) {
+            logger.warn("Ignoring exception while cleaning up after test", e);
+        }
     }
 
-    private NetconfOperationServiceFactory mockOpF() {
-        return new NetconfOperationServiceFactory() {
-            @Override
-            public NetconfOperationService createService(String netconfSessionIdForReporting) {
-                return new NetconfOperationService() {
-                    @Override
-                    public Set<Capability> getCapabilities() {
-                        return Collections.emptySet();
-                    }
-
-                    @Override
-                    public Set<NetconfOperation> getNetconfOperations() {
-                        return Sets.<NetconfOperation> newHashSet(new NetconfOperation() {
-                            @Override
-                            public HandlingPriority canHandle(Document message) {
-                                return HandlingPriority.getHandlingPriority(Integer.MAX_VALUE);
-                            }
-
-                            @Override
-                            public Document handle(Document requestMessage, NetconfOperationChainedExecution subsequentOperation) throws NetconfDocumentedException {
-                                try {
-                                    return XmlUtil.readXmlToDocument("<test/>");
-                                } catch (Exception e) {
-                                    throw new RuntimeException(e);
-                                }
-                            }
-                        });
-                    }
-
-                    @Override
-                    public void close() {
-                    }
-                };
-            }
-        };
+    @AfterClass
+    public static void tearDownClientExecutor() {
+        clientExecutor.shutdownNow();
     }
 
-    @After
-    public void cleanUp() throws Exception {
-        commitNot.close();
-    }
+    @Test(timeout = CONCURRENCY * 1000)
+    public void testConcurrentClients() throws Exception {
 
-    @Test
-    public void multipleClients() throws Exception {
-        List<TestingThread> threads = new ArrayList<>();
+        List<Future<?>> futures = Lists.newArrayListWithCapacity(CONCURRENCY);
 
-        final int attempts = 5;
         for (int i = 0; i < CONCURRENCY; i++) {
-            TestingThread thread = new TestingThread(String.valueOf(i), attempts);
-            threads.add(thread);
-            thread.start();
+            futures.add(clientExecutor.submit(getInstanceOfClientRunnable()));
         }
 
-        for (TestingThread thread : threads) {
-            thread.join();
-            if(thread.thrownException.isPresent()) {
-                Exception exception = thread.thrownException.get();
-                logger.error("Thread for testing client failed", exception);
-                fail("Client thread " + thread + " failed: " + exception.getMessage());
+        for (Future<?> future : futures) {
+            try {
+                future.get();
+            } catch (InterruptedException e) {
+                throw new IllegalStateException(e);
+            } catch (ExecutionException e) {
+                logger.error("Thread for testing client failed", e);
+                fail("Client failed: " + e.getMessage());
             }
         }
+
+        assertEquals(CONCURRENCY, testingNetconfOperation.getMessageCount());
     }
 
-    @Test
-    public void synchronizationTest() throws Exception {
-        new BlockingThread("foo").run2();
+    public static Set<String> getOnlyExiServerCaps() {
+        return Sets.newHashSet(
+                XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_BASE_1_0,
+                XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_CAPABILITY_EXI_1_0
+        );
     }
 
-    @Test
-    public void multipleBlockingClients() throws Exception {
-        List<BlockingThread> threads = new ArrayList<>();
-        for (int i = 0; i < CONCURRENCY; i++) {
-            BlockingThread thread = new BlockingThread(String.valueOf(i));
-            threads.add(thread);
-            thread.start();
+    public static Set<String> getOnlyChunkServerCaps() {
+        return Sets.newHashSet(
+                XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_BASE_1_0,
+                XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_BASE_1_1
+        );
+    }
+
+    public Runnable getInstanceOfClientRunnable() throws Exception {
+        return clientRunnable.getConstructor(ConcurrentClientsTest.class).newInstance(this);
+    }
+
+    /**
+     * Responds to all operations except start-exi and counts all requests
+     */
+    private static class TestingNetconfOperation implements NetconfOperation {
+
+        private final AtomicLong counter = new AtomicLong();
+
+        @Override
+        public HandlingPriority canHandle(Document message) {
+            return XmlUtil.toString(message).contains(NetconfStartExiMessage.START_EXI) ?
+                    HandlingPriority.CANNOT_HANDLE :
+                    HandlingPriority.HANDLE_WITH_MAX_PRIORITY;
         }
 
-        for (BlockingThread thread : threads) {
-            thread.join();
-            if(thread.thrownException.isPresent()) {
-                Exception exception = thread.thrownException.get();
-                logger.error("Thread for testing client failed", exception);
-                fail("Client thread " + thread + " failed: " + exception.getMessage());
+        @Override
+        public Document handle(Document requestMessage, NetconfOperationChainedExecution subsequentOperation) throws NetconfDocumentedException {
+            try {
+                logger.info("Handling netconf message from test {}", XmlUtil.toString(requestMessage));
+                counter.getAndIncrement();
+                return XmlUtil.readXmlToDocument("<test/>");
+            } catch (Exception e) {
+                throw new RuntimeException(e);
             }
         }
+
+        public long getMessageCount() {
+            return counter.get();
+        }
     }
 
-    class BlockingThread extends Thread {
-        private Optional<Exception> thrownException;
+    /**
+     * Hardcoded operation service factory
+     */
+    private static class TestingOperationServiceFactory implements NetconfOperationServiceFactory {
+        private final NetconfOperation[] operations;
+
+        public TestingOperationServiceFactory(final NetconfOperation... operations) {
+            this.operations = operations;
+        }
 
-        public BlockingThread(String name) {
-            super("client-" + name);
+        @Override
+        public NetconfOperationService createService(String netconfSessionIdForReporting) {
+            return new NetconfOperationService() {
+                @Override
+                public Set<Capability> getCapabilities() {
+                    return Collections.emptySet();
+                }
+
+                @Override
+                public Set<NetconfOperation> getNetconfOperations() {
+                    return Sets.newHashSet(operations);
+                }
+
+                @Override
+                public void close() {}
+            };
         }
+    }
+
+    /**
+     * Pure socket based blocking client
+     */
+    public final class BlockingClientRunnable implements Runnable {
 
         @Override
         public void run() {
             try {
                 run2();
-                thrownException = Optional.absent();
             } catch (Exception e) {
-                thrownException = Optional.of(e);
+                throw new IllegalStateException(Thread.currentThread().getName(), e);
             }
         }
 
@@ -246,34 +325,32 @@ public class ConcurrentClientsTest {
         }
     }
 
-    class TestingThread extends Thread {
-
-        private final String clientId;
-        private final int attempts;
-        private Optional<Exception> thrownException;
-
-        TestingThread(String clientId, int attempts) {
-            this.clientId = clientId;
-            this.attempts = attempts;
-            setName("client-" + clientId);
-        }
+    /**
+     * TestingNetconfClient based runnable
+     */
+    public final class TestingNetconfClientRunnable implements Runnable {
 
         @Override
         public void run() {
             try {
-                final TestingNetconfClient netconfClient = new TestingNetconfClient(clientId, netconfAddress, netconfClientDispatcher);
+                final TestingNetconfClient netconfClient = new TestingNetconfClient(Thread.currentThread().getName(),
+                        netconfAddress, netconfClientDispatcher);
                 long sessionId = netconfClient.getSessionId();
-                logger.info("Client with sessionid {} hello exchanged", sessionId);
+                logger.info("Client with session id {}: hello exchanged", sessionId);
 
                 final NetconfMessage getMessage = XmlFileLoader
                         .xmlFileToNetconfMessage("netconfMessages/getConfig.xml");
                 NetconfMessage result = netconfClient.sendRequest(getMessage).get();
-                logger.info("Client with sessionid {} got result {}", sessionId, result);
+                logger.info("Client with session id {}: got result {}", sessionId, result);
+
+                Preconditions.checkState(NetconfMessageUtil.isErrorMessage(result) == false,
+                        "Received error response: " + XmlUtil.toString(result.getDocument()) + " to request: "
+                                + XmlUtil.toString(getMessage.getDocument()));
+
                 netconfClient.close();
-                logger.info("Client with session id {} ended", sessionId);
-                thrownException = Optional.absent();
+                logger.info("Client with session id {}: ended", sessionId);
             } catch (final Exception e) {
-                thrownException = Optional.of(e);
+                throw new IllegalStateException(Thread.currentThread().getName(), e);
             }
         }
     }
diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/chunked1.txt b/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/chunked1.txt
deleted file mode 100644 (file)
index aad7239..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-
-#24
-<rpc message-id="101" xm
-#28
-lns="urn:ietf:params:xml:ns:
-#2
-ne
-#33
-tconf:base:1.0">
-  <my-own-method
-#3
- xm
-#13
-lns="http://e
-#34
-xample.net/me/my-own/1.0">
-    <my
-#8
--first-p
-#21
-arameter>14</my-first
-#26
--parameter>
-    <another-p
-#23
-arameter>fred</another-
-#31
-parameter>
- </my-own-method>
- <
-#2
-/r
-#3
-pc>
-##
diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/chunked2.txt b/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/chunked2.txt
deleted file mode 100644 (file)
index a36a85e..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-
-#22
-<rpc message-id="101" 
-#24
-xmlns="urn:ietf:params:x
-#15
-ml:ns:netconf:b
-#54
-ase:1.0">
-  <get-config>
-      <source>
-            <r
-#2
-un
-#9
-ning/>
-  
-#18
-  </source>    <fi
-#33
-lter type="subtree">
-      <top x
-#4
-mlns
-#31
-="http://example.com/schema/1.2
-#15
-/config">
-     
-#19
-   <users>
-        
-#8
-     <us
-#3
-er/
-#5
->
-   
-#77
-     </users>
-           </top>
-               </filter>
-                 </g
-#17
-et-config>
-</rpc>
-##
diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/chunked3.txt b/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/chunked3.txt
deleted file mode 100644 (file)
index d9dc43d..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-
-#43
-<rpc message-id="101" xmlns="urn:ietf:param
-#14
-s:xml:ns:netco
-#14
-nf:base:1.0">
-
-#26
-<get-config>
-    <source>
-
-#35
-     <running/>
-         </source>
-
-#39
-    <filter type="subtree">
-          <
-#40
-top xmlns="http://example.com/schema/1.2
-#26
-/config">
-        <users>
-
-#36
-     <user>
-                 <name>f
-#56
-red</name>
-          </user>
-                  </users>
-
-#28
-      </top>
-          </fil
-#1
-t
-#28
-er>
-  </get-config>
-  </rpc>
-##
diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/chunked4.txt b/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/chunked4.txt
deleted file mode 100644 (file)
index 0b8a102..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-
-#17
-<rpc message-id="
-#25
-101" xmlns="urn:ietf:para
-#19
-ms:xml:ns:netconf:b
-#3
-ase
-#19
-:1.0">
-  <get-confi
-#61
-g>
-    <source>
-          <running/>
-              </source>
-
-#43
-  <filter type="subtree">
-        <!-- requ
-#13
-est a text ve
-#22
-rsion of the configura
-#9
-tion -->
-
-#16
-   <config-text 
-#45
-xmlns="http://example.com/text/1.2/config"/>
-
-#22
-    </filter>
-      </
-#18
-get-config>
-</rpc>
-##
diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/chunked5.txt b/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/chunked5.txt
deleted file mode 100644 (file)
index f8f3c4d..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-
-#43
-<rpc message-id="101" xmlns="urn:ietf:param
-#41
-s:xml:ns:netconf:base:1.0">
-  <edit-confi
-#29
-g>
-    <target>
-          <ru
-#13
-nning/>
-    <
-#4
-/tar
-#18
-get>
-    <config>
-
-#41
-  <top xmlns="http://example.com/schema/1
-#32
-.2/config">
-        <interface>
-
-#29
-        <name>Ethernet0/0</na
-#30
-me>
-          <mtu>1500</mtu>
-
-#61
-</interface>
-      </top>
-          </config>
-            </e
-#9
-dit-confi
-#9
-g>
-</rpc>
-##
diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/listener/databaseinteractions/jolokia_config_bean_response.txt b/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/listener/databaseinteractions/jolokia_config_bean_response.txt
deleted file mode 100644 (file)
index 2ae32ef..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-curl http://localhost:17777/jolokia/read/org.opendaylight.controller:instanceName=fixed1,type=ConfigBean,interfaceName=testing-threadpool | jsonpp
-{
-    "request": {
-        "mbean": "org.opendaylight.controller:instanceName=fixed1,interfaceName=testing-threadpool,type=ConfigBean",
-        "type": "read"
-    },
-    "status": 200,
-    "timestamp": 1362416252,
-    "value": {
-        "ExportedInterfaces": [
-            "testing-threadpool",
-            "modifiable-threadpool"
-        ],
-        "ImplementationName": "fixed",
-        "ThreadCount": 10,
-        "TriggerNewInstanceCreation": false
-    }
-}
\ No newline at end of file
diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/listener/databaseinteractions/jolokia_lookupConfigBeans.txt b/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/listener/databaseinteractions/jolokia_lookupConfigBeans.txt
deleted file mode 100644 (file)
index 2ae705a..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-$ curl 'http://localhost:17777/jolokia/exec/org.opendaylight.controller:type=ConfigRegistry/lookupConfigBeans()' | jsonpp
-{
-    "request": {
-        "mbean": "org.opendaylight.controller:type=ConfigRegistry",
-        "operation": "lookupConfigBeans()",
-        "type": "exec"
-    },
-    "status": 200,
-    "timestamp": 1362417043,
-    "value": [
-        {
-            "objectName": "org.opendaylight.controller:instanceName=fixed1,interfaceName=modifiable-threadpool,type=ConfigBean"
-        },
-        {
-            "objectName": "org.opendaylight.controller:instanceName=fixed1,interfaceName=testing-threadpool,type=ConfigBean"
-        }
-    ]
-}
diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/notused/client_commit.xml b/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/notused/client_commit.xml
deleted file mode 100644 (file)
index 6eca609..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<rpc message-id="104"
-     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
-    <commit/>
-</rpc>
\ No newline at end of file
diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/notused/client_lock_candidate.xml b/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/notused/client_lock_candidate.xml
deleted file mode 100644 (file)
index 6a9ed63..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-<rpc message-id="102"
-     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
-    <lock>
-        <target>
-            <candidate/>
-        </target>
-    </lock>
-</rpc>
\ No newline at end of file
diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/notused/client_lock_running.xml b/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/notused/client_lock_running.xml
deleted file mode 100644 (file)
index 2d66c45..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-<rpc message-id="101"
-     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
-    <lock>
-        <target>
-            <running/>
-        </target>
-    </lock>
-</rpc>
\ No newline at end of file
diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/notused/client_modify_candidate.xml b/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/notused/client_modify_candidate.xml
deleted file mode 100644 (file)
index ce67845..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-<rpc message-id="103"
-     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
-    <edit-config>
-        <target>
-            <candidate/>
-        </target>
-        <default-operation>none</default-operation>
-        <test-option>test-then-set</test-option>
-        <error-option>stop-on-error</error-option>
-        <nc:config
-                xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"
-                xmlns="uri-for-my-data-model-namespace">
-            <some-existing-node>
-                <my-new-node nc:operation="create">
-                    <my-new-leaf>7</my-new-leaf>
-                </my-new-node>
-            </some-existing-node>
-        </nc:config>
-    </edit-config>
-</rpc>
\ No newline at end of file
diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/notused/client_unlock_candidate.xml b/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/notused/client_unlock_candidate.xml
deleted file mode 100644 (file)
index dd6fe1b..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-<rpc message-id="105"
-     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
-    <unlock>
-        <target>
-            <candidate/>
-        </target>
-    </unlock>
-</rpc>
\ No newline at end of file
diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/notused/client_unlock_running.xml b/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/notused/client_unlock_running.xml
deleted file mode 100644 (file)
index f94af46..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-<rpc message-id="106"
-     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
-    <unlock>
-        <target>
-            <running/>
-        </target>
-    </unlock>
-</rpc>
\ No newline at end of file
diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/notused/server_error_missing_attribute.xml b/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/notused/server_error_missing_attribute.xml
deleted file mode 100644 (file)
index c70184e..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
-    <rpc-error>
-        <error-type>rpc</error-type>
-        <error-tag>missing-attribute</error-tag>
-        <error-severity>error</error-severity>
-        <error-info>
-            <bad-attribute>message-id</bad-attribute>
-            <bad-element>rpc</bad-element>
-        </error-info>
-    </rpc-error>
-</rpc-reply>
diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/testConfigs/input.json b/opendaylight/netconf/netconf-impl/src/test/resources/testConfigs/input.json
deleted file mode 100644 (file)
index fcef6b7..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-{
-   "value":null,
-   "status":200,
-   "request": {
-                "type":"exec",
-                "mbean":"java.util.logging:type=Logging",
-                "operation":"setLoggerLevel",
-                "arguments":["global","INFO"]
-              }
-}
\ No newline at end of file
diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/testConfigs/input.xml b/opendaylight/netconf/netconf-impl/src/test/resources/testConfigs/input.xml
deleted file mode 100644 (file)
index 09ba714..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-<jmxbean>
-    <mBean>org.opendaylight.controller:type=AppDeployer</mBean>
-    <type>EXEC</type>
-    <operation>lookupConfigBeans</operation>
-    <arguments>abc,bcd.aas</arguments>
-    <arguments>64</arguments>
-</jmxbean>
\ No newline at end of file
diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/testConfigs/inputList.xml b/opendaylight/netconf/netconf-impl/src/test/resources/testConfigs/inputList.xml
deleted file mode 100644 (file)
index 011d472..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-<jmxbean>
-    <mBean>org.opendaylight.controller:type=AppDeployer</mBean>
-    <type>EXEC</type>
-    <operation>lookupConfigBeans</operation>
-    <arguments>
-        <elements>22</elements>
-        <elements>69</elements>
-    </arguments>
-</jmxbean>
\ No newline at end of file
diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/testConfigs/inputMap.xml b/opendaylight/netconf/netconf-impl/src/test/resources/testConfigs/inputMap.xml
deleted file mode 100644 (file)
index 947335d..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-<jmxbean>
-    <mBean>org.opendaylight.controller:type=AppDeployer</mBean>
-    <type>EXEC</type>
-    <operation>lookupConfigBeans</operation>
-    <arguments>
-        <map>
-            <topology-registry>single</topology-registry>
-            <bgp-update>mock</bgp-update>
-        </map>
-        <array>2</array>
-        <array>22</array>
-        <anotherArg>arg</anotherArg>
-    </arguments>
-</jmxbean>
\ No newline at end of file
diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/testConfigs/inputMultiple.xml b/opendaylight/netconf/netconf-impl/src/test/resources/testConfigs/inputMultiple.xml
deleted file mode 100644 (file)
index 2ad485f..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-<config>
-    <jmxbean>
-        <mBean>org.opendaylight.controller:type=AppDeployer</mBean>
-        <type>EXEC</type>
-        <operation>lookupConfigBeans</operation>
-        <attribute>abc,bcd.aas</attribute>
-        <attribute>22</attribute>
-    </jmxbean>
-    <jmxbean>
-        <mBean>org.opendaylight.controller:type=AppDeployer</mBean>
-        <type>WRITE</type>
-        <attribute>attribute</attribute>
-        <value>22</value>
-    </jmxbean>
-    <jmxbean>
-        <mBean>org.opendaylight.controller:type=AppDeployer</mBean>
-        <type>EXEC</type>
-        <operation>lookupConfigBeans</operation>
-        <arguments>
-            <map>
-                <topology-registry>single</topology-registry>
-                <bgp-update>mock</bgp-update>
-            </map>
-            <array>2</array>
-            <array>22</array>
-            <anotherArg>arg</anotherArg>
-        </arguments>
-    </jmxbean>
-</config>
\ No newline at end of file
diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/testConfigs/inputSetter.xml b/opendaylight/netconf/netconf-impl/src/test/resources/testConfigs/inputSetter.xml
deleted file mode 100644 (file)
index a5882d6..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-<jmxbean>
-    <mBean>org.opendaylight.controller:type=AppDeployer</mBean>
-    <type>WRITE</type>
-    <attribute>attribute</attribute>
-    <value>22</value>
-</jmxbean>
\ No newline at end of file
diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/testConfigs/inputSetterList.xml b/opendaylight/netconf/netconf-impl/src/test/resources/testConfigs/inputSetterList.xml
deleted file mode 100644 (file)
index 24d2171..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-<jmxbean>
-    <mBean>org.opendaylight.controller:type=AppDeployer</mBean>
-    <type>WRITE</type>
-    <attribute>attribute</attribute>
-    <value>22</value>
-    <value>222</value>
-    <value>223</value>
-</jmxbean>
\ No newline at end of file
diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/testConfigs/inputSetterMap.xml b/opendaylight/netconf/netconf-impl/src/test/resources/testConfigs/inputSetterMap.xml
deleted file mode 100644 (file)
index 9af105f..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-<jmxbean>
-    <mBean>org.opendaylight.controller:type=AppDeployer</mBean>
-    <type>WRITE</type>
-    <attribute>setAtr</attribute>
-    <value>
-        <abc>1</abc>
-        <bcd>2</bcd>
-    </value>
-</jmxbean>
diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/testConfigs/map.json b/opendaylight/netconf/netconf-impl/src/test/resources/testConfigs/map.json
deleted file mode 100644 (file)
index d753866..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-{
-   "timestamp":1362488209,
-   "status":200,
-   "request":{
-      "mbean":"org.opendaylight.controller:type=ConfigRegistry",
-      "attribute":"AvailableInterfacesAndImplementations",
-      "type":"read"
-   },
-   "value":{
-      "topology-registry":[
-         "single"
-      ],
-      "bgp-update":[
-         "mock",
-         "bgp-impl"
-      ],
-      "positioning-service":[
-         "combine",
-         "onehop",
-         "ondemand",
-         "pxe",
-         "precompute"
-      ],
-      "serializer":[
-         "serializer-impl"
-      ],
-      "network-topology-factory":[
-         "mock-xml",
-         "bgp-network-topology-factory",
-         "transient"
-      ],
-      "dwe-topology":[
-         "ebgp",
-         "defaultmetric",
-         "igp",
-         "network"
-      ],
-      "thread-factory":[
-         "naming-thread-factory"
-      ],
-      "bgp-parser":[
-         "parser"
-      ],
-      "pcep-dispatcher":[
-         "dispatcher"
-      ],
-      "threadpool":[
-         "flexible",
-         "fixed",
-         "scheduled"
-      ],
-      "scheduled-threadpool":[
-         "scheduled"
-      ],
-      "positioning-onehop":[
-         "onehop"
-      ],
-      "bgp-dispatcher":[
-         "bgp-dispatcher-impl"
-      ],
-      "cost-combiner":[
-         "pxe"
-      ],
-      "apsp-provider":[
-         "jgrapht",
-         "parallel",
-         "single-threaded"
-      ],
-      "topology":[
-         "ebgp",
-         "defaultmetric",
-         "igp",
-         "network"
-      ],
-      "soap-resource":[
-         "positioning-adaptor-pxe"
-      ],
-      "database-provider-factory":[
-         "transient"
-      ],
-      "bgp-proposal-checker":[
-         "bgp-proposal-checker-impl"
-      ],
-      "bgp-proposal":[
-         "bgp-proposal-impl"
-      ],
-      "listenable-network-topology-factory":[
-         "transient"
-      ],
-      "event-bus":[
-         "sync",
-         "async"
-      ],
-      "topology-registry-provider":[
-         "single"
-      ],
-      "topology-provider-factory":[
-         "transient"
-      ],
-      "rest-resource":[
-         "topology-resource-holder",
-         "alto-resource-holder",
-         "topology-visual-holder",
-         "network-resource-holder",
-         "path-resource-holder"
-      ],
-      "listenable-database-provider-factory":[
-         "transient"
-      ],
-      "topology-validator":[
-         "accept-all",
-         "threshold"
-      ],
-      "replicator":[
-         "replicator-impl"
-      ],
-      "server":[
-         "soap",
-         "rest"
-      ],
-      "combiner-pxe":[
-         "pxe"
-      ],
-      "rest":[
-         "rest"
-      ],
-      "soap":[
-         "soap"
-      ],
-      "path-service":[
-         "cariden"
-      ]
-   }
-}
\ No newline at end of file
index b330f9bcd4f05b915e76caf878dc0fa25e6489e2..0c03dda45bee20342466c35adb15f6653641d2bf 100644 (file)
   </properties>
 
   <dependencies>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>sal-binding-it</artifactId>
+      <exclusions>
+        <!-- FIXME see IdentityRefNetconfTest  -->
+        <!-- Pax-url-aether contains guava classes e.g. ImmutableSet that clashes with guava and causes tests to fail-->
+        <exclusion>
+          <groupId>org.ops4j.pax.url</groupId>
+          <artifactId>pax-url-aether</artifactId>
+        </exclusion>
+      </exclusions>
+    </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>commons.logback_settings</artifactId>
       <artifactId>netty-config-api</artifactId>
       <scope>test</scope>
     </dependency>
-    <dependency>
-      <groupId>${project.groupId}</groupId>
-      <artifactId>sal-binding-it</artifactId>
-    </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>yang-test</artifactId>
index 8b2af393439e932ac069481ad3670b3b154fe0cb..af83fe46027ee6816855ab1a6e051139fea5603d 100644 (file)
@@ -78,7 +78,7 @@ public class NetconfConfigPersisterITTest extends AbstractNetconfConfigTest {
 
     @Before
     public void setUp() throws Exception {
-        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(NetconfITTest.getModuleFactoriesS().toArray(
+        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,NetconfITTest.getModuleFactoriesS().toArray(
                 new ModuleFactory[0])));
 
         NetconfMonitoringServiceImpl monitoringService = new NetconfMonitoringServiceImpl(getNetconfOperationProvider());
index e45a249ad4e1f901075060451c6865a5fd54b585..cc9e8c367a9f3d2871842510daddd29aa95ea441 100644 (file)
@@ -46,7 +46,7 @@ public class NetconfITSecureTest extends AbstractNetconfConfigTest {
 
     @Before
     public void setUp() throws Exception {
-        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(getModuleFactories().toArray(
+        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,getModuleFactories().toArray(
                 new ModuleFactory[0])));
 
         NetconfOperationServiceFactoryListenerImpl factoriesListener = new NetconfOperationServiceFactoryListenerImpl();
index 634a18f852a05184a861fc1ab8ce1eb7073e893b..b77d92e7cb662aecdd4421d7097f0bf6b909988c 100644 (file)
@@ -13,6 +13,20 @@ import ch.ethz.ssh2.Session;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
 import io.netty.channel.ChannelFuture;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.management.ManagementFactory;
+import java.net.InetSocketAddress;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeoutException;
+import javax.management.ObjectName;
+import javax.xml.parsers.ParserConfigurationException;
 import junit.framework.Assert;
 import org.apache.commons.io.IOUtils;
 import org.junit.After;
@@ -52,22 +66,6 @@ import org.w3c.dom.Element;
 import org.w3c.dom.NamedNodeMap;
 import org.w3c.dom.Node;
 import org.xml.sax.SAXException;
-
-import javax.management.ObjectName;
-import javax.xml.parsers.ParserConfigurationException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.management.ManagementFactory;
-import java.net.InetSocketAddress;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeoutException;
-
 import static java.util.Collections.emptyList;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
@@ -96,7 +94,7 @@ public class NetconfITTest extends AbstractNetconfConfigTest {
 
     @Before
     public void setUp() throws Exception {
-        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(getModuleFactories().toArray(
+        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,getModuleFactories().toArray(
                 new ModuleFactory[0])));
 
         loadMessages();
@@ -411,7 +409,7 @@ public class NetconfITTest extends AbstractNetconfConfigTest {
                     try {
                         c = sess.getStdout().read(bytes);
                     } catch (IOException e) {
-                        e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
+                        throw new IllegalStateException("IO exception while reading data on ssh bridge.");
                     }
                     logger.info("got data:" + bytes);
                     if (c == 0) {
index 92caea17d5eaea998d5d62ab6682c765287c5329..8e98ab6320c65d28e0dd1ab29ed5f37f2e31b14b 100644 (file)
@@ -17,12 +17,12 @@ import org.junit.Test;
 import org.mockito.Mock;
 import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
 import org.opendaylight.controller.config.spi.ModuleFactory;
-import org.opendaylight.controller.netconf.client.test.TestingNetconfClient;
-import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreException;
 import org.opendaylight.controller.netconf.api.NetconfMessage;
 import org.opendaylight.controller.netconf.api.monitoring.NetconfManagementSession;
 import org.opendaylight.controller.netconf.client.NetconfClientDispatcher;
+import org.opendaylight.controller.netconf.client.test.TestingNetconfClient;
 import org.opendaylight.controller.netconf.confignetconfconnector.osgi.NetconfOperationServiceFactoryImpl;
+import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreException;
 import org.opendaylight.controller.netconf.impl.DefaultCommitNotificationProducer;
 import org.opendaylight.controller.netconf.impl.NetconfServerDispatcher;
 import org.opendaylight.controller.netconf.impl.osgi.NetconfMonitoringServiceImpl;
@@ -72,7 +72,7 @@ public class NetconfMonitoringITTest extends AbstractNetconfConfigTest {
 
     @Before
     public void setUp() throws Exception {
-        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(NetconfITTest.getModuleFactoriesS().toArray(
+        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext, NetconfITTest.getModuleFactoriesS().toArray(
                 new ModuleFactory[0])));
 
         monitoringService = new NetconfMonitoringServiceImpl(getNetconfOperationProvider());
index 96a9effcfc7cdfc4ccf9b28995b26a9eea5ef148..c54285bc908c817157287022d5dcc92011b0d145 100644 (file)
@@ -1,10 +1,10 @@
 /*
- * 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
- */
+* 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.pax;
 
 import static org.junit.Assert.fail;
@@ -26,7 +26,6 @@ import java.net.InetSocketAddress;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeoutException;
 
-import javax.inject.Inject;
 import javax.xml.parsers.ParserConfigurationException;
 
 import org.junit.Assert;
@@ -59,7 +58,11 @@ public class IdentityRefNetconfTest {
     public static final int CLIENT_CONNECTION_TIMEOUT_MILLIS = 15000;
 
     // Wait for controller to start
-    @Inject
+
+    // FIXME move this (pax) test to different module
+    // pax jars contain guava classes that clash with real guava dependencies in non-pax tests
+    //
+    //@Inject
     @Filter(timeout = 60 * 1000)
     BindingAwareBroker broker;
 
index 05122be4d245a8f09b0c566aab90337c28c513af..c08db906df51a00b5dc39d53bb30be252381b3ca 100644 (file)
@@ -11,7 +11,7 @@ package org.opendaylight.controller.netconf.mapping.api;
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 
-public class HandlingPriority implements Comparable<HandlingPriority> {
+public final class HandlingPriority implements Comparable<HandlingPriority> {
 
     public static final HandlingPriority CANNOT_HANDLE = new HandlingPriority();
     public static final HandlingPriority HANDLE_WITH_DEFAULT_PRIORITY = new HandlingPriority(Integer.MIN_VALUE);
@@ -51,34 +51,42 @@ public class HandlingPriority implements Comparable<HandlingPriority> {
 
     @Override
     public int compareTo(HandlingPriority o) {
-        if (this == o)
+        if (this == o){
             return 0;
-        if (this == CANNOT_HANDLE)
+        }
+        if (this.equals(CANNOT_HANDLE)){
             return -1;
-        if (o == CANNOT_HANDLE)
+        }
+        if (o.equals(CANNOT_HANDLE)){
             return 1;
+        }
 
-        if (priority > o.priority)
+        if (priority > o.priority){
             return 1;
-        if (priority == o.priority)
+        }
+        if (priority.equals(o.priority)){
             return 0;
-        if (priority < o.priority)
+        }
+        if (priority < o.priority){
             return -1;
-
+        }
         throw new IllegalStateException("Unexpected state");
     }
 
     @Override
     public boolean equals(Object o) {
-        if (this == o)
+        if (this == o){
             return true;
-        if (!(o instanceof HandlingPriority))
+        }
+        if (!(o instanceof HandlingPriority)){
             return false;
+        }
 
         HandlingPriority that = (HandlingPriority) o;
 
-        if (priority != null ? !priority.equals(that.priority) : that.priority != null)
+        if (priority != null ? !priority.equals(that.priority) : that.priority != null){
             return false;
+        }
 
         return true;
     }
index 6449c3e05fa39a6510e27d59ed69664e243e29b2..c277e20553fb3ed469c9f849d624f795f0acf635 100644 (file)
@@ -7,7 +7,6 @@
  */
 package org.opendaylight.controller.netconf.monitoring;
 
-import com.google.common.base.Preconditions;
 import com.google.common.collect.Maps;
 import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
 import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService;
@@ -63,8 +62,12 @@ public class Get extends AbstractNetconfOperation {
     @Override
     public Document handle(Document requestMessage, NetconfOperationChainedExecution subsequentOperation)
             throws NetconfDocumentedException {
-        Preconditions.checkArgument(subsequentOperation.isExecutionTermination() == false,
-                "Subsequent netconf operation expected by %s", this);
+        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);
+        }
 
         try {
             Document innerResult = subsequentOperation.execute(requestMessage);
index 200cd344a6617b995065b652efca10a6a2a35791..d14464d66734a3a890af70f8e49d068fbafc4c9a 100644 (file)
@@ -7,8 +7,11 @@
  */
 package org.opendaylight.controller.netconf.monitoring;
 
-public class MonitoringConstants {
+public final class MonitoringConstants {
 
+    private MonitoringConstants(){
+        // not called - private constructor for utility class
+    }
     public static final String MODULE_NAME = "ietf-netconf-monitoring";
     public static final String MODULE_REVISION = "2010-10-04";
 
index de04484d1388f411577c7b1c2537996f2e625e7d..14c47352a8409d633dca64a01db06759ad79f8f6 100644 (file)
@@ -21,14 +21,14 @@ public class NetconfMonitoringActivator implements BundleActivator {
     private NetconfMonitoringServiceTracker monitor;
 
     @Override
-    public void start(final BundleContext context) throws Exception {
+    public void start(final BundleContext context)  {
         monitor = new NetconfMonitoringServiceTracker(context);
         monitor.open();
 
     }
 
     @Override
-    public void stop(final BundleContext context) throws Exception {
+    public void stop(final BundleContext context) {
         if(monitor!=null) {
             try {
                 monitor.close();
index a42bc09591ba0160d964ebe6f4b4900b91282ff8..731aad6d1a4d7103ca12fc99541482b81a82757b 100644 (file)
@@ -7,30 +7,20 @@
 */
 package org.opendaylight.controller.netconf.monitoring.osgi;
 
-import java.io.File;
-import java.io.IOException;
-import java.net.URL;
-import java.util.HashSet;
+import com.google.common.base.Optional;
+import com.google.common.collect.Sets;
 import java.util.List;
 import java.util.Set;
-
 import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService;
 import org.opendaylight.controller.netconf.mapping.api.Capability;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperation;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService;
 import org.opendaylight.controller.netconf.monitoring.Get;
 import org.opendaylight.controller.netconf.monitoring.MonitoringConstants;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.Schemas;
-
-import com.google.common.base.Charsets;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Sets;
-import com.google.common.io.Files;
 
 public class NetconfMonitoringOperationService implements NetconfOperationService {
 
-    public static final HashSet<Capability> CAPABILITIES = Sets.<Capability>newHashSet(new Capability() {
+    public static final Set<Capability> CAPABILITIES = Sets.<Capability>newHashSet(new Capability() {
 
         @Override
         public String getCapabilityUri() {
@@ -69,18 +59,6 @@ public class NetconfMonitoringOperationService implements NetconfOperationServic
         this.monitor = monitor;
     }
 
-    private static String readSchema() {
-        String schemaLocation = "/META-INF/yang/ietf-netconf-monitoring.yang";
-        URL resource = Schemas.class.getClassLoader().getResource(schemaLocation);
-        Preconditions.checkNotNull(resource, "Unable to read schema content from %s", schemaLocation);
-        File file = new File(resource.getFile());
-        try {
-            return Files.toString(file, Charsets.UTF_8);
-        } catch (IOException e) {
-            throw new RuntimeException("Unable to load schema from " + schemaLocation, e);
-        }
-    }
-
     @Override
     public Set<Capability> getCapabilities() {
         return CAPABILITIES;
index c2d067915516b27efb44bd5a7644f942744a13d2..51054dd938ac8349447e694ea5c2698a7bc6d5c8 100644 (file)
@@ -20,7 +20,7 @@ import java.net.ServerSocket;
 import java.util.concurrent.atomic.AtomicLong;
 
 @ThreadSafe
-public class NetconfSSHServer implements Runnable {
+public final class NetconfSSHServer implements Runnable {
 
     private ServerSocket ss = null;
     private static final Logger logger =  LoggerFactory.getLogger(NetconfSSHServer.class);
@@ -29,12 +29,12 @@ public class NetconfSSHServer implements Runnable {
     private final AuthProvider authProvider;
     private boolean up = false;
 
-    private NetconfSSHServer(int serverPort,InetSocketAddress clientAddress, AuthProvider authProvider) throws Exception{
+    private NetconfSSHServer(int serverPort,InetSocketAddress clientAddress, AuthProvider authProvider) throws IllegalStateException, IOException {
 
         logger.trace("Creating SSH server socket on port {}",serverPort);
         this.ss = new ServerSocket(serverPort);
         if (!ss.isBound()){
-            throw new Exception("Socket can't be bound to requested port :"+serverPort);
+            throw new IllegalStateException("Socket can't be bound to requested port :"+serverPort);
         }
         logger.trace("Server socket created.");
         this.clientAddress = clientAddress;
@@ -42,11 +42,11 @@ public class NetconfSSHServer implements Runnable {
         this.up = true;
     }
 
-    public static NetconfSSHServer start(int serverPort, InetSocketAddress clientAddress,AuthProvider authProvider) throws Exception {
+    public static NetconfSSHServer start(int serverPort, InetSocketAddress clientAddress,AuthProvider authProvider) throws IllegalStateException, IOException {
         return new NetconfSSHServer(serverPort, clientAddress,authProvider);
     }
 
-    public void stop() throws Exception {
+    public void stop() throws IOException {
         up = false;
         logger.trace("Closing SSH server socket.");
         ss.close();
index 2d380482ba456afd4beef97c77d7a86d1bf79f14..2e9a0b9d8bbd256154ff82689e85e556b60c9e90 100644 (file)
@@ -7,42 +7,26 @@
  */
 package org.opendaylight.controller.netconf.ssh.authentication;
 
+import java.io.IOException;
 import org.opendaylight.controller.sal.authorization.AuthResultEnum;
-import org.opendaylight.controller.sal.authorization.UserLevel;
 import org.opendaylight.controller.usermanager.IUserManager;
-import org.opendaylight.controller.usermanager.UserConfig;
-
-import java.util.ArrayList;
-import java.util.List;
-
 import static com.google.common.base.Preconditions.checkNotNull;
 
 public class AuthProvider implements AuthProviderInterface {
 
-    private static IUserManager um; //FIXME static mutable state, no locks
-    private static final String DEFAULT_USER = "netconf";
-    private static final String DEFAULT_PASSWORD = "netconf";
+    private IUserManager um;
     private final String pem;
 
-    public AuthProvider(IUserManager ium, String pemCertificate) throws Exception {
+    public AuthProvider(IUserManager ium, String pemCertificate) throws IllegalArgumentException, IOException {
         checkNotNull(pemCertificate, "Parameter 'pemCertificate' is null");
-        AuthProvider.um = ium;
-        if (AuthProvider.um == null) {
-            throw new Exception("No usermanager service available.");
-        }
-
-        List<String> roles = new ArrayList<String>(1);
-        roles.add(UserLevel.SYSTEMADMIN.toString());
-        AuthProvider.um.addLocalUser(new UserConfig(DEFAULT_USER, DEFAULT_PASSWORD, roles)); //FIXME hardcoded auth
+        checkNotNull(ium, "No user manager service available.");
+        this.um = ium;
         pem = pemCertificate;
     }
 
     @Override
-    public boolean authenticated(String username, String password) throws Exception {
-        if (AuthProvider.um == null) {
-            throw new Exception("No usermanager service available.");
-        }
-        AuthResultEnum authResult = AuthProvider.um.authenticate(username, password);
+    public boolean authenticated(String username, String password) {
+        AuthResultEnum authResult = this.um.authenticate(username, password);
         return authResult.equals(AuthResultEnum.AUTH_ACCEPT) || authResult.equals(AuthResultEnum.AUTH_ACCEPT_LOC);
     }
 
@@ -53,11 +37,11 @@ public class AuthProvider implements AuthProviderInterface {
 
     @Override
     public void removeUserManagerService() {
-        AuthProvider.um = null;
+        this.um = null;
     }
 
     @Override
     public void addUserManagerService(IUserManager userManagerService) {
-        AuthProvider.um = userManagerService;
+        this.um = userManagerService;
     }
 }
index 8e40578a0e47c001676b8fb28809a9cf306364e2..fad0f79a4e7b9eb5d883b3d8086bd046343e4f6d 100644 (file)
@@ -12,7 +12,7 @@ import org.opendaylight.controller.usermanager.IUserManager;
 
 public interface AuthProviderInterface {
 
-    public boolean authenticated(String username, String password) throws Exception;
+    public boolean authenticated(String username, String password) throws IllegalStateException;
     public char[] getPEMAsCharArray() throws Exception;
     public void removeUserManagerService();
     public void addUserManagerService(IUserManager userManagerService);
index 112bf67f69b48d869fede643308dca962c317819..ca0c9454d4a5c8934a96da245b41029198e464d6 100644 (file)
@@ -8,12 +8,21 @@
 package org.opendaylight.controller.netconf.ssh.osgi;
 
 import com.google.common.base.Optional;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.commons.io.FilenameUtils;
 import org.apache.commons.io.IOUtils;
 import org.opendaylight.controller.netconf.ssh.NetconfSSHServer;
 import org.opendaylight.controller.netconf.ssh.authentication.AuthProvider;
 import org.opendaylight.controller.netconf.ssh.authentication.PEMGenerator;
 import org.opendaylight.controller.netconf.util.osgi.NetconfConfigUtil;
+import org.opendaylight.controller.sal.authorization.UserLevel;
 import org.opendaylight.controller.usermanager.IUserManager;
+import org.opendaylight.controller.usermanager.UserConfig;
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
@@ -21,16 +30,12 @@ import org.osgi.util.tracker.ServiceTracker;
 import org.osgi.util.tracker.ServiceTrackerCustomizer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.net.InetSocketAddress;
+import static com.google.common.base.Preconditions.checkNotNull;
 
 /**
  * Activator for netconf SSH bundle which creates SSH bridge between netconf client and netconf server. Activator
  * starts SSH Server in its own thread. This thread is closed when activator calls stop() method. Server opens socket
- * and listen for client connections. Each client connection creation is handled in separate
+ * and listens for client connections. Each client connection creation is handled in separate
  * {@link org.opendaylight.controller.netconf.ssh.threads.SocketThread} thread.
  * This thread creates two additional threads {@link org.opendaylight.controller.netconf.ssh.threads.IOThread}
  * forwarding data from/to client.IOThread closes servers session and server connection when it gets -1 on input stream.
@@ -44,8 +49,10 @@ public class NetconfSSHActivator implements BundleActivator{
     private static final String EXCEPTION_MESSAGE = "Netconf ssh bridge is not available.";
     private IUserManager iUserManager;
     private BundleContext context = null;
+    private Optional<String> defaultPassword;
+    private Optional<String> defaultUser;
 
-    ServiceTrackerCustomizer<IUserManager, IUserManager> customizer = new ServiceTrackerCustomizer<IUserManager, IUserManager>(){
+    private ServiceTrackerCustomizer<IUserManager, IUserManager> customizer = new ServiceTrackerCustomizer<IUserManager, IUserManager>(){
         @Override
         public IUserManager addingService(ServiceReference<IUserManager> reference) {
             logger.trace("Service {} added, let there be SSH bridge.", reference);
@@ -72,36 +79,42 @@ public class NetconfSSHActivator implements BundleActivator{
 
 
     @Override
-    public void start(BundleContext context) throws Exception {
+    public void start(BundleContext context)  {
         this.context = context;
         listenForManagerService();
     }
 
     @Override
-    public void stop(BundleContext context) throws Exception {
+    public void stop(BundleContext context) throws IOException {
+        if (this.defaultUser.isPresent()){
+            this.iUserManager.removeLocalUser(this.defaultUser.get());
+        }
         if (server != null){
             server.stop();
             logger.trace("Netconf SSH bridge is down ...");
         }
     }
-    private void startSSHServer() throws Exception {
+    private void startSSHServer() throws IllegalStateException, IOException {
+        checkNotNull(this.iUserManager, "No user manager service available.");
         logger.trace("Starting netconf SSH  bridge.");
         Optional<InetSocketAddress> sshSocketAddressOptional = NetconfConfigUtil.extractSSHNetconfAddress(context, EXCEPTION_MESSAGE);
         InetSocketAddress tcpSocketAddress = NetconfConfigUtil.extractTCPNetconfAddress(context,
                 EXCEPTION_MESSAGE, true);
 
         if (sshSocketAddressOptional.isPresent()){
-            String path = NetconfConfigUtil.getPrivateKeyPath(context);
-            path = path.replace("\\", "/");  // FIXME: shouldn't this convert lines to system dependent path separator?
+            String path =  FilenameUtils.separatorsToSystem(NetconfConfigUtil.getPrivateKeyPath(context));
             if (path.equals("")){
-                throw new Exception("Missing netconf.ssh.pk.path key in configuration file.");
+                throw new IllegalStateException("Missing netconf.ssh.pk.path key in configuration file.");
             }
 
             File privateKeyFile = new File(path);
-            String privateKeyPEMString;
+            String privateKeyPEMString = null;
             if (privateKeyFile.exists() == false) {
-                // generate & save to file
-                privateKeyPEMString = PEMGenerator.generateTo(privateKeyFile);
+                try {
+                    privateKeyPEMString = PEMGenerator.generateTo(privateKeyFile);
+                } catch (Exception e) {
+                    logger.error("Exception occurred while generating PEM string {}",e);
+                }
             } else {
                 // read from file
                 try (FileInputStream fis = new FileInputStream(path)) {
@@ -111,7 +124,23 @@ public class NetconfSSHActivator implements BundleActivator{
                     throw new IllegalStateException("Error reading RSA key from file " + path);
                 }
             }
-            AuthProvider authProvider = new AuthProvider(iUserManager, privateKeyPEMString);
+            AuthProvider authProvider = null;
+            try {
+                this.defaultPassword = NetconfConfigUtil.getSSHDefaultPassword(context);
+                this.defaultUser = NetconfConfigUtil.getSSHDefaultUser(context);
+                // Since there is no user data store yet (ldap, ...) this adds default user/password to UserManager
+                // if these parameters are set in netconf configuration file.
+                if (defaultUser.isPresent() &&
+                        defaultPassword.isPresent()){
+                    logger.trace(String.format("Default username and password for netconf ssh bridge found. Adding user %s to user manager.",defaultUser.get()));
+                    List<String> roles = new ArrayList<String>(1);
+                    roles.add(UserLevel.SYSTEMADMIN.toString());
+                    iUserManager.addLocalUser(new UserConfig(defaultUser.get(), defaultPassword.get(), roles));
+                }
+                authProvider = new AuthProvider(iUserManager, privateKeyPEMString);
+            } catch (Exception e) {
+                logger.error("Error instantiating AuthProvider {}",e);
+            }
             this.server = NetconfSSHServer.start(sshSocketAddressOptional.get().getPort(),tcpSocketAddress,authProvider);
 
             Thread serverThread = new  Thread(server,"netconf SSH server thread");
@@ -120,10 +149,10 @@ public class NetconfSSHActivator implements BundleActivator{
             logger.trace("Netconf SSH  bridge up and running.");
         } else {
             logger.trace("No valid connection configuration for SSH bridge found.");
-            throw new Exception("No valid connection configuration for SSH bridge found.");
+            throw new IllegalStateException("No valid connection configuration for SSH bridge found.");
         }
     }
-    private void onUserManagerFound(IUserManager userManager) throws Exception{
+    private void onUserManagerFound(IUserManager userManager) throws IOException {
         if (server!=null && server.isUp()){
            server.addUserManagerService(userManager);
         } else {
index ce26910b97dd449b10d395933e57cd6deccd52ea..d6566c8ffa69f3e0fd46d6775e8ced177cffd911 100644 (file)
@@ -112,18 +112,18 @@ public class SocketThread implements Runnable, ServerAuthenticationCallback, Ser
                                     if (netconf_ssh_input != null) {
                                         netconf_ssh_input.join();
                                     }
-                                } catch (InterruptedException e) {
+                                } catch (InterruptedException e1) {
                                     Thread.currentThread().interrupt();
-                                    logger.error("netconf_ssh_input join error ", e);
+                                    logger.error("netconf_ssh_input join error ", e1);
                                 }
 
                                 try {
                                     if (netconf_ssh_output != null) {
                                         netconf_ssh_output.join();
                                     }
-                                } catch (InterruptedException e) {
+                                } catch (InterruptedException e2) {
                                     Thread.currentThread().interrupt();
-                                    logger.error("netconf_ssh_output join error ", e);
+                                    logger.error("netconf_ssh_output join error ", e2);
                                 }
                             }
                         } else {
index 270af3505f63a7589ab0957c1177badb72b6ab1d..c789206436f1eecb1fd92fc1480a027eb8943d09 100644 (file)
@@ -61,7 +61,7 @@ public abstract class AbstractNetconfSession<S extends NetconfSession, L extends
     @Override
     public ChannelFuture sendMessage(final NetconfMessage netconfMessage) {
         final ChannelFuture future = channel.writeAndFlush(netconfMessage);
-        if (delayedEncoder !=null) {
+        if (delayedEncoder != null) {
                 replaceMessageEncoder(delayedEncoder);
                 delayedEncoder = null;
         }
@@ -93,23 +93,19 @@ public abstract class AbstractNetconfSession<S extends NetconfSession, L extends
         return sb.toString();
     }
 
-    protected <T extends ChannelHandler> T removeHandler(final Class<T> handlerType) {
-        return this.channel.pipeline().remove(handlerType);
-    }
-
-    protected void replaceMessageDecoder(final ChannelHandler handler) {
+    protected final void replaceMessageDecoder(final ChannelHandler handler) {
         replaceChannelHandler(AbstractChannelInitializer.NETCONF_MESSAGE_DECODER, handler);
     }
 
-    protected void replaceMessageEncoder(final ChannelHandler handler) {
+    protected final void replaceMessageEncoder(final ChannelHandler handler) {
         replaceChannelHandler(AbstractChannelInitializer.NETCONF_MESSAGE_ENCODER, handler);
     }
 
-    protected void replaceMessageEncoderAfterNextMessage(final ChannelHandler handler) {
+    protected final void replaceMessageEncoderAfterNextMessage(final ChannelHandler handler) {
         this.delayedEncoder = handler;
     }
 
-    protected void replaceChannelHandler(final String handlerName, final ChannelHandler handler) {
+    protected final void replaceChannelHandler(final String handlerName, final ChannelHandler handler) {
         channel.pipeline().replace(handlerName, handlerName, handler);
     }
 
@@ -124,7 +120,7 @@ public abstract class AbstractNetconfSession<S extends NetconfSession, L extends
         }
         final NetconfEXICodec exiCodec = new NetconfEXICodec(exiParams.getOptions());
         addExiHandlers(exiCodec);
-        logger.debug("EXI handlers added to pipeline on session {}", this);
+        logger.debug("Session {} EXI handlers added to pipeline", this);
     }
 
     protected abstract void addExiHandlers(NetconfEXICodec exiCodec);
index 5521e28818b20fcb9291089ced8867cce787e2e6..b0c8c6dc19e6b3b6c97f90b21fe0e1dc680e0ba3 100644 (file)
@@ -28,6 +28,7 @@ import org.opendaylight.controller.netconf.api.NetconfSessionPreferences;
 import org.opendaylight.controller.netconf.util.handler.FramingMechanismHandlerFactory;
 import org.opendaylight.controller.netconf.util.handler.NetconfChunkAggregator;
 import org.opendaylight.controller.netconf.util.handler.NetconfMessageToXMLEncoder;
+import org.opendaylight.controller.netconf.util.handler.NetconfXMLToHelloMessageDecoder;
 import org.opendaylight.controller.netconf.util.handler.NetconfXMLToMessageDecoder;
 import org.opendaylight.controller.netconf.util.messages.FramingMechanism;
 import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessage;
@@ -74,7 +75,7 @@ extends AbstractSessionNegotiator<NetconfHelloMessage, S> {
     }
 
     @Override
-    protected void startNegotiation() {
+    protected final void startNegotiation() {
         final Optional<SslHandler> sslHandler = getSslHandler(channel);
         if (sslHandler.isPresent()) {
             Future<Channel> future = sslHandler.get().handshakeFuture();
@@ -125,27 +126,22 @@ extends AbstractSessionNegotiator<NetconfHelloMessage, S> {
 
         // FIXME, make sessionPreferences return HelloMessage, move NetconfHelloMessage to API
         sendMessage((NetconfHelloMessage)helloMessage);
+
+        replaceHelloMessageOutboundHandler();
         changeState(State.OPEN_WAIT);
     }
+
     private void cancelTimeout() {
         if(timeout!=null) {
             timeout.cancel();
         }
     }
 
-    @Override
-    protected void handleMessage(NetconfHelloMessage netconfMessage) throws NetconfDocumentedException {
-        S session = getSessionForHelloMessage(netconfMessage)   ;
-        negotiationSuccessful(session);
-    }
-
     protected final S getSessionForHelloMessage(NetconfHelloMessage netconfMessage) throws NetconfDocumentedException {
         Preconditions.checkNotNull(netconfMessage, "netconfMessage");
 
         final Document doc = netconfMessage.getDocument();
 
-        replaceHelloMessageHandlers();
-
         if (shouldUseChunkFraming(doc)) {
             insertChunkFramingToPipeline();
         }
@@ -157,23 +153,44 @@ extends AbstractSessionNegotiator<NetconfHelloMessage, S> {
     /**
      * Insert chunk framing handlers into the pipeline
      */
-    protected void insertChunkFramingToPipeline() {
+    private void insertChunkFramingToPipeline() {
         replaceChannelHandler(channel, AbstractChannelInitializer.NETCONF_MESSAGE_FRAME_ENCODER,
                 FramingMechanismHandlerFactory.createHandler(FramingMechanism.CHUNK));
         replaceChannelHandler(channel, AbstractChannelInitializer.NETCONF_MESSAGE_AGGREGATOR,
                 new NetconfChunkAggregator());
     }
 
-    protected boolean shouldUseChunkFraming(Document doc) {
+    private boolean shouldUseChunkFraming(Document doc) {
         return containsBase11Capability(doc)
                 && containsBase11Capability(sessionPreferences.getHelloMessage().getDocument());
     }
 
     /**
-     * Remove special handlers for hello message. Insert regular netconf xml message (en|de)coders.
+     * Remove special inbound handler for hello message. Insert regular netconf xml message (en|de)coders.
+     *
+     * Inbound hello message handler should be kept until negotiation is successful
+     * It caches any non-hello messages while negotiation is still in progress
+     */
+    protected final void replaceHelloMessageInboundHandler(final S session) {
+        ChannelHandler helloMessageHandler = replaceChannelHandler(channel, AbstractChannelInitializer.NETCONF_MESSAGE_DECODER, new NetconfXMLToMessageDecoder());
+
+        Preconditions.checkState(helloMessageHandler instanceof NetconfXMLToHelloMessageDecoder,
+                "Pipeline handlers misplaced on session: %s, pipeline: %s", session, channel.pipeline());
+        Iterable<NetconfMessage> netconfMessagesFromNegotiation =
+                ((NetconfXMLToHelloMessageDecoder) helloMessageHandler).getPostHelloNetconfMessages();
+
+        // Process messages received during negotiation
+        // The hello message handler does not have to be synchronized, since it is always call from the same thread by netty
+        // It means, we are now using the thread now
+        for (NetconfMessage message : netconfMessagesFromNegotiation) {
+            session.handleMessage(message);
+        }
+    }
+
+    /**
+     * Remove special outbound handler for hello message. Insert regular netconf xml message (en|de)coders.
      */
-    protected void replaceHelloMessageHandlers() {
-        replaceChannelHandler(channel, AbstractChannelInitializer.NETCONF_MESSAGE_DECODER, new NetconfXMLToMessageDecoder());
+    private void replaceHelloMessageOutboundHandler() {
         replaceChannelHandler(channel, AbstractChannelInitializer.NETCONF_MESSAGE_ENCODER, new NetconfMessageToXMLEncoder());
     }
 
@@ -183,7 +200,7 @@ extends AbstractSessionNegotiator<NetconfHelloMessage, S> {
 
     protected abstract S getSession(L sessionListener, Channel channel, NetconfHelloMessage message) throws NetconfDocumentedException;
 
-    protected synchronized void changeState(final State newState) {
+    private synchronized void changeState(final State newState) {
         logger.debug("Changing state from : {} to : {}", state, newState);
         Preconditions.checkState(isStateChangePermitted(state, newState), "Cannot change state from %s to %s", state,
                 newState);
index ccc80a7b71248758cc2ce9a3c00225a0dab3fc49..8f4590cbb112bb6315f0ba0059e8fea417d48c3f 100644 (file)
@@ -40,7 +40,7 @@ public class ChunkedFramingMechanismEncoder extends MessageToByteEncoder<ByteBuf
     }
 
     @Override
-    protected void encode(ChannelHandlerContext ctx, ByteBuf msg, ByteBuf out) throws Exception {
+    protected void encode(ChannelHandlerContext ctx, ByteBuf msg, ByteBuf out)  {
         while (msg.readableBytes() > chunkSize) {
             ByteBuf chunk = Unpooled.buffer(chunkSize);
             chunk.writeBytes(createChunkHeader(chunkSize));
index a3efe8a16bd0c541971e7a4c0ca172b83144d3d5..8df62a67020c9b05dcac72bb0d589f42bb7a9076 100644 (file)
@@ -16,7 +16,7 @@ import org.opendaylight.controller.netconf.util.messages.NetconfMessageConstants
 
 public class EOMFramingMechanismEncoder extends MessageToByteEncoder<ByteBuf> {
     @Override
-    protected void encode(ChannelHandlerContext ctx, ByteBuf msg, ByteBuf out) throws Exception {
+    protected void encode(ChannelHandlerContext ctx, ByteBuf msg, ByteBuf out) {
         out.writeBytes(msg);
         out.writeBytes(NetconfMessageConstants.END_OF_MESSAGE);
     }
index 1f7a32dc704ca2698112b0e5e9d90c9cdb503a87..bac83e49d3c463548589c48ae367d972ae818d6e 100644 (file)
@@ -15,11 +15,13 @@ import org.slf4j.LoggerFactory;
 import io.netty.buffer.ByteBuf;
 import io.netty.handler.codec.MessageToByteEncoder;
 
-public class FramingMechanismHandlerFactory {
+public final class FramingMechanismHandlerFactory {
 
     private static final Logger logger = LoggerFactory.getLogger(FramingMechanismHandlerFactory.class);
 
-    private FramingMechanismHandlerFactory() {}
+    private FramingMechanismHandlerFactory() {
+        // not called - private constructor for utility class
+    }
 
     public static MessageToByteEncoder<ByteBuf> createHandler(FramingMechanism framingMechanism) {
         logger.debug("{} framing mechanism was selected.", framingMechanism);
index 219e92c3f14053c805d1ac204132f92d62479948..9f9f4191f7641943fe768712b94c0ec2b3f409b7 100644 (file)
@@ -21,6 +21,8 @@ import io.netty.handler.codec.ByteToMessageDecoder;
 
 public class NetconfChunkAggregator extends ByteToMessageDecoder {
     private final static Logger logger = LoggerFactory.getLogger(NetconfChunkAggregator.class);
+    private static final String GOT_PARAM_WHILE_WAITING_FOR_PARAM = "Got byte {} while waiting for {}";
+    private static final String GOT_PARAM_WHILE_WAITING_FOR_PARAM_PARAM = "Got byte {} while waiting for {}-{}";
     public static final int DEFAULT_MAXIMUM_CHUNK_SIZE = 16 * 1024 * 1024;
 
     private static enum State {
@@ -40,17 +42,35 @@ public class NetconfChunkAggregator extends ByteToMessageDecoder {
     private long chunkSize;
     private CompositeByteBuf chunk;
 
+    private void checkNewLine(byte b,String errorMessage){
+        if (b != '\n') {
+            logger.debug(GOT_PARAM_WHILE_WAITING_FOR_PARAM, b, (byte)'\n');
+            throw new IllegalStateException(errorMessage);
+        }
+    }
+
+    private void checkHash(byte b,String errorMessage){
+        if (b != '#') {
+            logger.debug(GOT_PARAM_WHILE_WAITING_FOR_PARAM, b, (byte)'#');
+            throw new IllegalStateException(errorMessage);
+        }
+    }
+
+    private void checkChunkSize(){
+        if (chunkSize > maxChunkSize) {
+            logger.debug("Parsed chunk size {}, maximum allowed is {}", chunkSize, maxChunkSize);
+            throw new IllegalStateException("Maximum chunk size exceeded");
+        }
+
+    }
     @Override
-    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
+    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws IllegalStateException {
         while (in.isReadable()) {
             switch (state) {
             case HEADER_ONE:
             {
                 final byte b = in.readByte();
-                if (b != '\n') {
-                    logger.debug("Got byte {} while waiting for {}", b, (byte)'\n');
-                    throw new IllegalStateException("Malformed chunk header encountered (byte 0)");
-                }
+                checkNewLine(b, "Malformed chunk header encountered (byte 0)");
 
                 state = State.HEADER_TWO;
 
@@ -60,10 +80,7 @@ public class NetconfChunkAggregator extends ByteToMessageDecoder {
             case HEADER_TWO:
             {
                 final byte b = in.readByte();
-                if (b != '#') {
-                    logger.debug("Got byte {} while waiting for {}", b, (byte)'#');
-                    throw new IllegalStateException("Malformed chunk header encountered (byte 1)");
-                }
+                checkHash(b, "Malformed chunk header encountered (byte 1)");
 
                 state = State.HEADER_LENGTH_FIRST;
                 break;
@@ -84,17 +101,13 @@ public class NetconfChunkAggregator extends ByteToMessageDecoder {
                 }
 
                 if (b < '0' || b > '9') {
-                    logger.debug("Got byte {} while waiting for {}-{}", b, (byte)'0', (byte)'9');
+                    logger.debug(GOT_PARAM_WHILE_WAITING_FOR_PARAM_PARAM, b, (byte)'0', (byte)'9');
                     throw new IllegalStateException("Invalid chunk size encountered");
                 }
 
                 chunkSize *= 10;
                 chunkSize += b - '0';
-
-                if (chunkSize > maxChunkSize) {
-                    logger.debug("Parsed chunk size {}, maximum allowed is {}", chunkSize, maxChunkSize);
-                    throw new IllegalStateException("Maximum chunk size exceeded");
-                }
+                checkChunkSize();
                 break;
             }
             case DATA:
@@ -109,18 +122,13 @@ public class NetconfChunkAggregator extends ByteToMessageDecoder {
                     in.discardReadBytes();
                     return;
                 }
-
                 aggregateChunks(in.readBytes((int) chunkSize));
                 state = State.FOOTER_ONE;
                 break;
             case FOOTER_ONE:
             {
                 final byte b = in.readByte();
-                if (b != '\n') {
-                    logger.debug("Got byte {} while waiting for {}", b, (byte)'\n');
-                    throw new IllegalStateException("Malformed chunk footer encountered (byte 0)");
-                }
-
+                checkNewLine(b,"Malformed chunk footer encountered (byte 0)");
                 state = State.FOOTER_TWO;
                 chunkSize = 0;
                 break;
@@ -128,12 +136,7 @@ public class NetconfChunkAggregator extends ByteToMessageDecoder {
             case FOOTER_TWO:
             {
                 final byte b = in.readByte();
-
-                if (b != '#') {
-                    logger.debug("Got byte {} while waiting for {}", b, (byte)'#');
-                    throw new IllegalStateException("Malformed chunk footer encountered (byte 1)");
-                }
-
+                checkHash(b,"Malformed chunk footer encountered (byte 1)");
                 state = State.FOOTER_THREE;
                 break;
             }
@@ -144,28 +147,14 @@ public class NetconfChunkAggregator extends ByteToMessageDecoder {
                 // In this state, either header-of-new-chunk or message-end is expected
                 // Depends on the next character
 
-                if (isHeaderLengthFirst(b)) {
-                    // Extract header length#1 from new chunk
-                    chunkSize = processHeaderLengthFirst(b);
-                    // Proceed with next chunk processing
-                    state = State.HEADER_LENGTH_OTHER;
-                } else if (b == '#') {
-                    state = State.FOOTER_FOUR;
-                } else {
-                    logger.debug("Got byte {} while waiting for {} or {}-{}", b, (byte) '#', (byte) '1', (byte) '9');
-                    throw new IllegalStateException("Malformed chunk footer encountered (byte 2)");
-                }
+                extractNewChunkOrMessageEnd(b);
 
                 break;
             }
             case FOOTER_FOUR:
             {
                 final byte b = in.readByte();
-                if (b != '\n') {
-                    logger.debug("Got byte {} while waiting for {}", b, (byte)'\n');
-                    throw new IllegalStateException("Malformed chunk footer encountered (byte 3)");
-                }
-
+                checkNewLine(b,"Malformed chunk footer encountered (byte 3)");
                 state = State.HEADER_ONE;
                 out.add(chunk);
                 chunk = null;
@@ -177,6 +166,20 @@ public class NetconfChunkAggregator extends ByteToMessageDecoder {
         in.discardReadBytes();
     }
 
+    private void extractNewChunkOrMessageEnd(byte b) {
+        if (isHeaderLengthFirst(b)) {
+            // Extract header length#1 from new chunk
+            chunkSize = processHeaderLengthFirst(b);
+            // Proceed with next chunk processing
+            state = State.HEADER_LENGTH_OTHER;
+        } else if (b == '#') {
+            state = State.FOOTER_FOUR;
+        } else {
+            logger.debug(GOT_PARAM_WHILE_WAITING_FOR_PARAM_PARAM, b, (byte) '#', (byte) '1', (byte) '9');
+            throw new IllegalStateException("Malformed chunk footer encountered (byte 2)");
+        }
+    }
+
     private void initChunk() {
         chunk = Unpooled.compositeBuffer();
     }
@@ -189,8 +192,8 @@ public class NetconfChunkAggregator extends ByteToMessageDecoder {
     }
 
     private static int processHeaderLengthFirst(byte b) {
-        if (isHeaderLengthFirst(b) == false) {
-            logger.debug("Got byte {} while waiting for {}-{}", b, (byte)'1', (byte)'9');
+        if (!isHeaderLengthFirst(b)) {
+            logger.debug(GOT_PARAM_WHILE_WAITING_FOR_PARAM_PARAM, b, (byte)'1', (byte)'9');
             throw new IllegalStateException("Invalid chunk size encountered (byte 0)");
         }
 
index 9435e6ff732cad7904a8fc71caf6ed9ee194225a..8b1bb3601ddd3df4b2b033d4d3f697acab76d210 100644 (file)
@@ -24,7 +24,7 @@ public class NetconfEOMAggregator extends ByteToMessageDecoder {
     private final static Logger logger = LoggerFactory.getLogger(NetconfEOMAggregator.class);
 
     @Override
-    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
+    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) {
         int index = indexOfSequence(in, NetconfMessageConstants.END_OF_MESSAGE);
         if (index == -1) {
             logger.debug("Message is not complete, read again.");
index cbfbfe1c05a21ebb5db74b5973ce32fc90f86c98..ae330d67e68344e16d1904b7c1547caea73cadb8 100644 (file)
@@ -34,8 +34,6 @@ public final class NetconfEXIToMessageDecoder extends ByteToMessageDecoder {
 
     private static final Logger LOG = LoggerFactory.getLogger(NetconfEXIToMessageDecoder.class);
 
-//    private static final SAXTransformerFactory saxTransformerFactory = (SAXTransformerFactory)SAXTransformerFactory.newInstance();
-
     private final NetconfEXICodec codec;
 
     public NetconfEXIToMessageDecoder(final NetconfEXICodec codec) {
@@ -50,9 +48,9 @@ public final class NetconfEXIToMessageDecoder extends ByteToMessageDecoder {
          * the use of EXI, which means the next message needs to be decoded not by us, but rather
          * by the XML decoder.
          */
-        // If empty Byte buffer is passed to r.parse, EOFException is thrown
 
-        if (in.readableBytes() == 0) {
+        // If empty Byte buffer is passed to r.parse, EOFException is thrown
+        if (in.isReadable() == false) {
             LOG.debug("No more content in incoming buffer.");
             return;
         }
@@ -69,7 +67,6 @@ public final class NetconfEXIToMessageDecoder extends ByteToMessageDecoder {
         final DOMResult domResult = new DOMResult();
         handler.setResult(domResult);
 
-
         try (final InputStream is = new ByteBufInputStream(in)) {
             r.parse(new InputSource(is));
         }
index c4808e0868d0f59b1378f5900b5151933edf696e..361d4fcee908018eac90a54844569ced70c22a21 100644 (file)
@@ -7,16 +7,20 @@
  */
 package org.opendaylight.controller.netconf.util.handler;
 
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Lists;
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.ByteBufUtil;
 import io.netty.channel.ChannelHandlerContext;
 import io.netty.handler.codec.ByteToMessageDecoder;
 
 import java.io.ByteArrayInputStream;
+import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.util.Arrays;
 import java.util.List;
 
+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;
@@ -28,12 +32,18 @@ import org.w3c.dom.Document;
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Charsets;
 import com.google.common.collect.ImmutableList;
+import org.xml.sax.SAXException;
 
 /**
  * Customized NetconfXMLToMessageDecoder that reads additional header with
  * session metadata from
  * {@link org.opendaylight.controller.netconf.util.messages.NetconfHelloMessage}
- * . Used by netconf server to retrieve information about session metadata.
+ *
+ *
+ * This handler should be replaced in pipeline by regular message handler as last step of negotiation.
+ * It serves as a message barrier and halts all non-hello netconf messages.
+ * Netconf messages after hello should be processed once the negotiation succeeded.
+ *
  */
 public final class NetconfXMLToHelloMessageDecoder extends ByteToMessageDecoder {
     private static final Logger LOG = LoggerFactory.getLogger(NetconfXMLToHelloMessageDecoder.class);
@@ -46,9 +56,15 @@ public final class NetconfXMLToHelloMessageDecoder extends ByteToMessageDecoder
             new byte[] { '\r', '\n', '[' },
             new byte[] { '\n', '[' });
 
+    // State variables do not have to by synchronized
+    // Netty uses always the same (1) thread per pipeline
+    // We use instance of this per pipeline
+    private List<NetconfMessage> nonHelloMessages = Lists.newArrayList();
+    private boolean helloReceived = false;
+
     @Override
     @VisibleForTesting
-    public void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
+    public void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws IOException, SAXException, NetconfDocumentedException {
         if (in.readableBytes() == 0) {
             LOG.debug("No more content in incoming buffer.");
             return;
@@ -76,18 +92,39 @@ public final class NetconfXMLToHelloMessageDecoder extends ByteToMessageDecoder
 
             Document doc = XmlUtil.readXmlToDocument(new ByteArrayInputStream(bytes));
 
-            final NetconfMessage message;
-            if (additionalHeader != null) {
-                message = new NetconfHelloMessage(doc, NetconfHelloMessageAdditionalHeader.fromString(additionalHeader));
+            final NetconfMessage message = getNetconfMessage(additionalHeader, doc);
+            if (message instanceof NetconfHelloMessage) {
+                Preconditions.checkState(helloReceived == false,
+                        "Multiple hello messages received, unexpected hello: %s",
+                        XmlUtil.toString(message.getDocument()));
+                out.add(message);
+                helloReceived = true;
+            // Non hello message, suspend the message and insert into cache
             } else {
-                message = new NetconfHelloMessage(doc);
+                Preconditions.checkState(helloReceived, "Hello message not received, instead received: %s",
+                        XmlUtil.toString(message.getDocument()));
+                LOG.debug("Netconf message received during negotiation, caching {}",
+                        XmlUtil.toString(message.getDocument()));
+                nonHelloMessages.add(message);
             }
-            out.add(message);
         } finally {
             in.discardReadBytes();
         }
     }
 
+    private NetconfMessage getNetconfMessage(final String additionalHeader, final Document doc) throws NetconfDocumentedException {
+        NetconfMessage msg = new NetconfMessage(doc);
+        if(NetconfHelloMessage.isHelloMessage(msg)) {
+            if (additionalHeader != null) {
+                return new NetconfHelloMessage(doc, NetconfHelloMessageAdditionalHeader.fromString(additionalHeader));
+            } else {
+                return new NetconfHelloMessage(doc);
+            }
+        }
+
+        return msg;
+    }
+
     private int getAdditionalHeaderEndIndex(byte[] bytes) {
         for (byte[] possibleEnd : POSSIBLE_ENDS) {
             int idx = findByteSequence(bytes, possibleEnd);
@@ -152,4 +189,10 @@ public final class NetconfXMLToHelloMessageDecoder extends ByteToMessageDecoder
         return Charsets.UTF_8.decode(ByteBuffer.wrap(bytes)).toString();
     }
 
+    /**
+     * @return Collection of NetconfMessages that were not hello, but were received during negotiation
+     */
+    public Iterable<NetconfMessage> getPostHelloNetconfMessages() {
+        return nonHelloMessages;
+    }
 }
index 06a4dc7207204d573f5abb2cc28c32318fee891d..23f48b31d822ff2b4c10351c844718989ca3b7c2 100644 (file)
@@ -7,12 +7,6 @@
  */
 package org.opendaylight.controller.netconf.util.handler;
 
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.ByteBufInputStream;
-import io.netty.buffer.ByteBufUtil;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.handler.codec.ByteToMessageDecoder;
-
 import java.util.List;
 
 import org.opendaylight.controller.netconf.api.NetconfMessage;
@@ -22,12 +16,19 @@ import org.slf4j.LoggerFactory;
 
 import com.google.common.annotations.VisibleForTesting;
 
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.ByteBufInputStream;
+import io.netty.buffer.ByteBufUtil;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.handler.codec.ByteToMessageDecoder;
+
 public final class NetconfXMLToMessageDecoder extends ByteToMessageDecoder {
     private static final Logger LOG = LoggerFactory.getLogger(NetconfXMLToMessageDecoder.class);
 
     @Override
     @VisibleForTesting
     public void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
+
         if (in.readableBytes() != 0) {
             LOG.trace("Received to decode: {}", ByteBufUtil.hexDump(in));
             out.add(new NetconfMessage(XmlUtil.readXmlToDocument(new ByteBufInputStream(in))));
index 4aa274c6df34f2f2e9d4151454c4b84f53a41bdb..c482e77735348833a3eeda204d51698af1f50071 100644 (file)
@@ -29,7 +29,7 @@ public class LoginPassword extends AuthenticationHandler {
     public void authenticate(Connection connection) throws IOException {
         boolean isAuthenticated = connection.authenticateWithPassword(username, password);
 
-        if (isAuthenticated == false) {
+        if (!isAuthenticated) {
             throw new IOException("Authentication failed.");
         }
     }
index 7beee649abfe0501e60850fda0db79dd96c7bb86..50f44054c16f9be42a300da8144ec3ce2866ea32 100644 (file)
@@ -58,8 +58,9 @@ public class SshClient {
     }
 
     public void close() {
-        for (SshSession session : openSessions.values())
+        for (SshSession session : openSessions.values()){
             closeSession(session);
+        }
 
         openSessions.clear();
 
index 6350dd154415b510515f919d94c88d06ecac5314..244bcc0041c963988aa8fc78c712767fc7c643c2 100644 (file)
@@ -64,7 +64,7 @@ public class SshClientAdapter implements Runnable {
                 }
             }
 
-            while (stopRequested.get() == false) {
+            while (!stopRequested.get()) {
                 byte[] readBuff = new byte[BUFFER_SIZE];
                 int c = stdOut.read(readBuff);
                 if (c == -1) {
@@ -82,7 +82,7 @@ public class SshClientAdapter implements Runnable {
             // Netty closed connection prematurely.
             // Just pass and move on.
         } catch (Exception e) {
-            throw new RuntimeException(e);
+            throw new IllegalStateException(e);
         } finally {
             sshClient.close();
 
index 313ea932413b63b36c5d20cc6cb1a9570205ab2a..b8f13699ba06d49876c6002fc27f297eceded04c 100644 (file)
@@ -12,7 +12,6 @@ import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
 import io.netty.channel.ChannelHandlerContext;
 import io.netty.channel.ChannelInboundHandler;
-
 import java.io.IOException;
 import java.io.InputStream;
 
@@ -60,7 +59,7 @@ public class ChannelInputStream extends InputStream implements ChannelInboundHan
                     lock.wait();
                 } catch (InterruptedException e) {
                     Thread.currentThread().interrupt();
-                    throw new RuntimeException(e);
+                    throw new IllegalStateException(e);
                 }
             }
             return this.bb.readByte() & 0xFF;
index 3fd25e814d697d37e607e1e0ade520db254e83a8..86b2ba1671478a022e30f7dd8c724b07c1d4d703 100644 (file)
@@ -8,17 +8,21 @@
 
 package org.opendaylight.controller.netconf.util.messages;
 
-import com.google.common.base.Optional;
-import com.google.common.collect.Sets;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
 import org.opendaylight.controller.netconf.api.NetconfMessage;
+
+import java.util.Set;
+
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.netconf.util.exception.MissingNameSpaceException;
 import org.opendaylight.controller.netconf.util.xml.XmlElement;
 import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
 import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
-import java.util.Set;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Sets;
 
 /**
  * NetconfMessage that can carry additional header with session metadata. See {@link org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader}
@@ -43,10 +47,10 @@ public final class NetconfHelloMessage extends NetconfMessage {
         return additionalHeader== null ? Optional.<NetconfHelloMessageAdditionalHeader>absent() : Optional.of(additionalHeader);
     }
 
-    private static void checkHelloMessage(Document doc) throws NetconfDocumentedException {
-        XmlElement.fromDomElementWithExpected(doc.getDocumentElement(), HELLO_TAG,
-                XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
-
+    private static void checkHelloMessage(Document doc) {
+        Preconditions.checkArgument(isHelloMessage(doc),
+                "Hello message invalid format, should contain %s tag from namespace %s, but is: %s", HELLO_TAG,
+                XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0, XmlUtil.toString(doc));
     }
 
     public static NetconfHelloMessage createClientHello(Iterable<String> capabilities,
@@ -81,4 +85,21 @@ public final class NetconfHelloMessage extends NetconfMessage {
         doc.getDocumentElement().appendChild(sessionIdElement);
         return new NetconfHelloMessage(doc);
     }
+
+    public static boolean isHelloMessage(final NetconfMessage msg) {
+        Document document = msg.getDocument();
+        return isHelloMessage(document);
+    }
+
+    private static boolean isHelloMessage(final Document document) {
+        XmlElement element = XmlElement.fromDomElement(document.getDocumentElement());
+        try {
+            return element.getName().equals(HELLO_TAG) &&
+                   element.hasNamespace() &&
+                   element.getNamespace().equals(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
+        } catch (MissingNameSpaceException e) {
+            // Cannot happen, since we check for hasNamespace
+            throw new IllegalStateException(e);
+        }
+    }
 }
index 8bd6b8865933d7191a063055834ce3fb98b0bbe4..5c2770a8c1f2387211f4cdcf1a1ef762ef8f11d8 100644 (file)
@@ -10,7 +10,9 @@ package org.opendaylight.controller.netconf.util.messages;
 
 import com.google.common.base.Charsets;
 
-public class NetconfMessageConstants {
+public final class NetconfMessageConstants {
+
+    private NetconfMessageConstants(){}
     /**
      * The NETCONF 1.0 old-style message separator. This is framing mechanism
      * is used by default.
@@ -26,4 +28,5 @@ public class NetconfMessageConstants {
     public static final int MAX_HEADER_LENGTH = 13;
 
     public static final byte[] END_OF_CHUNK = "\n##\n".getBytes(Charsets.UTF_8);
+
 }
index de2d6d7e0c354ada3bcf1fb4f1b630b186c34e3c..fdcaa2a5b8c98616385231d5c6c8c0f7e39c0adc 100644 (file)
@@ -10,6 +10,8 @@ package org.opendaylight.controller.netconf.util.messages;
 
 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.NetconfSession;
 import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
 import org.opendaylight.controller.netconf.api.NetconfMessage;
@@ -38,13 +40,15 @@ public final class SendErrorExceptionUtil {
             final NetconfDocumentedException sendErrorException) {
         logger.trace("Sending error {}", sendErrorException.getMessage(), sendErrorException);
         final Document errorDocument = createDocument(sendErrorException);
-        session.sendMessage(new NetconfMessage(errorDocument));
+        ChannelFuture f = session.sendMessage(new NetconfMessage(errorDocument));
+        f.addListener(new SendErrorVerifyingListener(sendErrorException));
     }
 
     public static void sendErrorMessage(Channel channel, NetconfDocumentedException sendErrorException) {
         logger.trace("Sending error {}", sendErrorException.getMessage(), sendErrorException);
         final Document errorDocument = createDocument(sendErrorException);
-        channel.writeAndFlush(new NetconfMessage(errorDocument));
+        ChannelFuture f = channel.writeAndFlush(new NetconfMessage(errorDocument));
+        f.addListener(new SendErrorVerifyingListener(sendErrorException));
     }
 
     public static void sendErrorMessage(NetconfSession session, NetconfDocumentedException sendErrorException,
@@ -52,7 +56,8 @@ public final class SendErrorExceptionUtil {
         final Document errorDocument = createDocument(sendErrorException);
         logger.trace("Sending error {}", XmlUtil.toString(errorDocument));
         tryToCopyAttributes(incommingMessage.getDocument(), errorDocument, sendErrorException);
-        session.sendMessage(new NetconfMessage(errorDocument));
+        ChannelFuture f = session.sendMessage(new NetconfMessage(errorDocument));
+        f.addListener(new SendErrorVerifyingListener(sendErrorException));
     }
 
     private static void tryToCopyAttributes(final Document incommingDocument, final Document errorDocument,
@@ -112,7 +117,7 @@ public final class SendErrorExceptionUtil {
                 XPathConstants.NODE);
         errorSeverityNode.setTextContent(sendErrorException.getErrorSeverity().getTagValue());
 
-        if (sendErrorException.getErrorInfo() != null && sendErrorException.getErrorInfo().isEmpty() == false) {
+        if (sendErrorException.getErrorInfo() != null && !sendErrorException.getErrorInfo().isEmpty()) {
             /*
              * <error-info> <bad-attribute>message-id</bad-attribute>
              * <bad-element>rpc</bad-element> </error-info>
@@ -133,4 +138,20 @@ public final class SendErrorExceptionUtil {
         return errorDocument;
     }
 
+    /**
+     * Checks if netconf error was sent successfully.
+     */
+    private static final class SendErrorVerifyingListener implements ChannelFutureListener {
+        private final NetconfDocumentedException sendErrorException;
+
+        public SendErrorVerifyingListener(final NetconfDocumentedException sendErrorException) {
+            this.sendErrorException = sendErrorException;
+        }
+
+        @Override
+        public void operationComplete(final ChannelFuture channelFuture) throws Exception {
+            Preconditions.checkState(channelFuture.isSuccess(), "Unable to send exception {}", sendErrorException,
+                    channelFuture.cause());
+        }
+    }
 }
index 80eaa26de184ddc29993bd847d1c34b0e7becd09..f89df2ac7cc331908f64ed8d05b2dc826f4d7757 100644 (file)
@@ -9,12 +9,11 @@
 package org.opendaylight.controller.netconf.util.osgi;
 
 import com.google.common.base.Optional;
+import com.google.common.base.Strings;
+import java.net.InetSocketAddress;
 import org.osgi.framework.BundleContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-
-import java.net.InetSocketAddress;
-
 import static com.google.common.base.Preconditions.checkNotNull;
 
 public final class NetconfConfigUtil {
@@ -32,6 +31,8 @@ public final class NetconfConfigUtil {
     private static final String ADDRESS_SUFFIX_PROP = ".address";
     private static final String CLIENT_PROP = ".client";
     private static final String PRIVATE_KEY_PATH_PROP = ".pk.path";
+    private static final String SSH_DEFAULT_USER = ".default.user";
+    private static final String SSH_DEFAULT_PASSWORD = ".default.password";
 
     private static final String CONNECTION_TIMEOUT_MILLIS_PROP = "connectionTimeoutMillis";
     private static final long DEFAULT_TIMEOUT_MILLIS = 5000;
@@ -54,7 +55,7 @@ public final class NetconfConfigUtil {
 
         Optional<InetSocketAddress> inetSocketAddressOptional = extractSomeNetconfAddress(context, InfixProp.tcp, exceptionMessageIfNotFound, forClient);
 
-        if (inetSocketAddressOptional.isPresent() == false) {
+        if (!inetSocketAddressOptional.isPresent()) {
             throw new IllegalStateException("Netconf tcp address not found." + exceptionMessageIfNotFound);
         }
         InetSocketAddress inetSocketAddress = inetSocketAddressOptional.get();
@@ -72,6 +73,13 @@ public final class NetconfConfigUtil {
     public static String getPrivateKeyPath(BundleContext context){
         return getPropertyValue(context,PREFIX_PROP + InfixProp.ssh +PRIVATE_KEY_PATH_PROP);
     }
+    public static Optional<String> getSSHDefaultUser(BundleContext context){
+        return getOptionalPropertyValue(context,PREFIX_PROP + InfixProp.ssh +SSH_DEFAULT_USER);
+    }
+    public static Optional<String> getSSHDefaultPassword(BundleContext context){
+        return getOptionalPropertyValue(context,PREFIX_PROP + InfixProp.ssh +SSH_DEFAULT_PASSWORD);
+    }
+
     private static String getPropertyValue(BundleContext context, String propertyName){
         String propertyValue = context.getProperty(propertyName);
         if (propertyValue == null){
@@ -79,6 +87,13 @@ public final class NetconfConfigUtil {
         }
         return propertyValue;
     }
+    private static Optional<String> getOptionalPropertyValue(BundleContext context, String propertyName){
+        String propertyValue = context.getProperty(propertyName);
+        if (Strings.isNullOrEmpty(propertyValue)){
+            return Optional.absent();
+        }
+        return Optional.fromNullable(propertyValue);
+    }
     /**
      * @param context
      *            from which properties are being read.
index 17ea3740fca77cd6124daad71050de6383970dc5..66603fb6c2d60b90cf2e17c277e65420d3c0b8b1 100644 (file)
@@ -180,7 +180,7 @@ public final class XmlElement {
         final List<XmlElement> result = new ArrayList<>();
         for (int i = 0; i < childNodes.getLength(); i++) {
             Node item = childNodes.item(i);
-            if (item instanceof Element == false) {
+            if (!(item instanceof Element)) {
                 continue;
             }
             if (strat.accept((Element) item)) {
@@ -400,7 +400,7 @@ public final class XmlElement {
         } else {
             prefix = "";
         }
-        if (namespaces.containsKey(prefix) == false) {
+        if (!namespaces.containsKey(prefix)) {
             throw new IllegalArgumentException("Cannot find namespace for " + XmlUtil.toString(element) + ". Prefix from content is "
                     + prefix + ". Found namespaces " + namespaces);
         }
index 39a49544a576abe3bd65403c864aa1b4572fc898..708f17cadbc2a16dd639b53b386dd84e212d3d54 100644 (file)
@@ -46,7 +46,9 @@ public final class XmlNetconfConstants {
     // 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 URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_1 = "urn:ietf:params:xml:ns:netconf:base:1.1";
+    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";
index d8907424f804f6d93262a38ddf107364a392cca1..1f81117ca383922ff246c9e10af36b708f84b26a 100644 (file)
@@ -8,12 +8,12 @@
 
 package org.opendaylight.controller.netconf.util.xml;
 
-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 com.google.common.base.Charsets;
+import com.google.common.base.Optional;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.xml.sax.SAXException;
 
 import javax.xml.XMLConstants;
 import javax.xml.namespace.QName;
@@ -23,7 +23,6 @@ import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.transform.OutputKeys;
 import javax.xml.transform.Source;
 import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerException;
 import javax.xml.transform.TransformerFactory;
 import javax.xml.transform.TransformerFactoryConfigurationError;
 import javax.xml.transform.dom.DOMSource;
@@ -33,14 +32,12 @@ import javax.xml.validation.Schema;
 import javax.xml.validation.SchemaFactory;
 import javax.xml.xpath.XPathExpression;
 import javax.xml.xpath.XPathExpressionException;
-
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.xml.sax.SAXException;
-
-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;
 
 public final class XmlUtil {
 
@@ -81,7 +78,7 @@ public final class XmlUtil {
         try {
             dBuilder = BUILDERFACTORY.newDocumentBuilder();
         } catch (ParserConfigurationException e) {
-            throw new RuntimeException("Failed to parse XML document", e);
+            throw new IllegalStateException("Failed to parse XML document", e);
         }
         Document doc = dBuilder.parse(xmlContent);
 
@@ -96,10 +93,9 @@ public final class XmlUtil {
     public static Document newDocument() {
         try {
             DocumentBuilder builder = BUILDERFACTORY.newDocumentBuilder();
-            Document document = builder.newDocument();
-            return document;
+            return builder.newDocument();
         } catch (ParserConfigurationException e) {
-            throw new RuntimeException("Failed to create document", e);
+            throw new IllegalStateException("Failed to create document", e);
         }
     }
 
@@ -153,8 +149,8 @@ public final class XmlUtil {
             transformer.transform(source, result);
 
             return result.getWriter().toString();
-        } catch (IllegalArgumentException | TransformerFactoryConfigurationError | TransformerException e) {
-            throw new RuntimeException("Unable to serialize xml element " + xml, e);
+        } catch (Exception |  TransformerFactoryConfigurationError e) {
+            throw new IllegalStateException("Unable to serialize xml element " + xml, e);
         }
     }
 
index 07252b06f78dfb2a80a4c88d112f6b3f41fd5422..e95ab8095d08c8b3fcf80094fc958d0053b4d256 100644 (file)
@@ -115,6 +115,9 @@ public class SwitchManager implements ISwitchManager, IConfigurationContainerAwa
      * only subnet returned. As soon as a user-configured subnet is created this one will
      * vanish.
      */
+    private static final String DISABLE_DEFAULT_SUBNET_PROP = "switchmanager.disableDefaultSubnetGateway";
+    private static final String DISABLE_DEFAULT_SUBNET_PROP_VAL = System.getProperty(DISABLE_DEFAULT_SUBNET_PROP);
+    private static final boolean USE_DEFAULT_SUBNET_GW = !Boolean.valueOf(DISABLE_DEFAULT_SUBNET_PROP_VAL);
     protected static final SubnetConfig DEFAULT_SUBNETCONFIG;
     protected static final Subnet DEFAULT_SUBNET;
     protected static final String DEFAULT_SUBNET_NAME = "default (cannot be modifed)";
@@ -288,9 +291,9 @@ public class SwitchManager implements ISwitchManager, IConfigurationContainerAwa
     @Override
     public List<SubnetConfig> getSubnetsConfigList() {
         // if there are no subnets, return the default subnet
-        if(subnetsConfigList.size() == 0){
+        if (USE_DEFAULT_SUBNET_GW && subnetsConfigList.isEmpty()) {
             return Collections.singletonList(DEFAULT_SUBNETCONFIG);
-        }else{
+        } else {
             return new ArrayList<SubnetConfig>(subnetsConfigList.values());
         }
     }
@@ -298,9 +301,9 @@ public class SwitchManager implements ISwitchManager, IConfigurationContainerAwa
     @Override
     public SubnetConfig getSubnetConfig(String subnet) {
         // if there are no subnets, return the default subnet
-        if(subnetsConfigList.isEmpty() && subnet.equalsIgnoreCase(DEFAULT_SUBNET_NAME)){
+        if (USE_DEFAULT_SUBNET_GW && subnetsConfigList.isEmpty() && subnet.equalsIgnoreCase(DEFAULT_SUBNET_NAME)) {
             return DEFAULT_SUBNETCONFIG;
-        }else{
+        } else {
             return subnetsConfigList.get(subnet);
         }
     }