Merge "Simplify method isMutualExclusive in Subnet. Remove redundant 'if' statements."
authorMadhu Venugopal <mavenugo@gmail.com>
Mon, 23 Dec 2013 19:24:23 +0000 (19:24 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Mon, 23 Dec 2013 19:24:23 +0000 (19:24 +0000)
289 files changed:
opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/ConfigTransactionController.java
opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/LookupRegistry.java
opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/ServiceReferenceReadableRegistry.java
opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/ServiceReferenceWritableRegistry.java
opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/jmx/ObjectNameUtil.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/CloseableServiceReferenceReadableRegistry.java [new file with mode: 0644]
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/ConfigTransactionLookupRegistry.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/ServiceReferenceRegistryImpl.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/dependencyresolver/DependencyResolverImpl.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/dynamicmbean/AbstractDynamicWrapper.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/dynamicmbean/AttributeHolder.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/dynamicmbean/DynamicWritableWrapper.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/jmx/BaseJMXRegistrator.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/jmx/NestableJMXRegistrator.java [moved from opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/KeyStoreHandler.java with 62% similarity]
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/jmx/ServiceReference.java [new file with mode: 0644]
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/jmx/ServiceReferenceMXBean.java [new file with mode: 0644]
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/jmx/ServiceReferenceMXBeanImpl.java [new file with mode: 0644]
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/jmx/ServiceReferenceRegistrator.java [new file with mode: 0644]
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/jmx/TransactionModuleJMXRegistrator.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/ServiceReferenceRegistryImplTest.java [new file with mode: 0644]
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/util/ObjectNameUtilTest.java
opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/parallelapsp/TestingParallelAPSPModule.java
opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/parallelapsp/test/AbstractParallelAPSPTest.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/TestingScheduledThreadPoolConfigBeanMXBean.java
opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/scheduledthreadpool/TestingScheduledThreadPoolModule.java
opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/seviceinterface/TestingThreadPoolServiceInterface.java
opendaylight/config/config-util/src/main/java/org/opendaylight/controller/config/util/ConfigRegistryJMXClient.java
opendaylight/config/config-util/src/main/java/org/opendaylight/controller/config/util/ConfigTransactionJMXClient.java
opendaylight/config/config-util/src/test/java/org/opendaylight/controller/config/util/TestingConfigRegistry.java
opendaylight/config/config-util/src/test/java/org/opendaylight/controller/config/util/TestingConfigTransactionController.java
opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/TemplateFactory.java
opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/ModuleField.java
opendaylight/config/yang-jmx-generator-plugin/src/main/resources/freeMarker/module_abs_template_new.ftl
opendaylight/config/yang-jmx-generator-plugin/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/JMXGeneratorFileNamesValidationTest.java
opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/MbeParser.java
opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/YangParserWrapper.java [new file with mode: 0644]
opendaylight/config/yang-test/pom.xml
opendaylight/config/yang-test/src/test/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleTest.java [new file with mode: 0644]
opendaylight/distribution/opendaylight/pom.xml
opendaylight/distribution/opendaylight/src/main/resources/configuration/logback.xml
opendaylight/forwardingrulesmanager/implementation/src/main/java/org/opendaylight/controller/forwardingrulesmanager/internal/ForwardingRulesManager.java
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/ComponentActivator.xtend
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/DataPacketAdapter.xtend
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/FromSalConversionsUtils.java
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/InventoryAndReadAdapter.xtend
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/MDFlowMapping.xtend
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/MDSalNodeConnectorFactory.java [new file with mode: 0644]
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/MDSalNodeFactory.java [new file with mode: 0644]
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/NodeMapping.xtend
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/ToSalConversionsUtils.java
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/adsal/FlowStatisticsAdapter.java
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowTransaction.xtend
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupTransaction.xtend
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterTransaction.xtend
opendaylight/md-sal/model/model-flow-base/src/main/yang/group-types.yang
opendaylight/md-sal/model/model-flow-base/src/main/yang/meter-types.yang
opendaylight/md-sal/model/model-flow-base/src/main/yang/opendaylight-flow-types.yang
opendaylight/md-sal/model/model-flow-base/src/main/yang/port-types.yang
opendaylight/md-sal/model/model-flow-base/src/main/yang/queue-types.yang
opendaylight/md-sal/model/model-flow-service/src/main/yang/flow-service.yang
opendaylight/md-sal/model/model-flow-service/src/main/yang/group-service.yang
opendaylight/md-sal/model/model-flow-service/src/main/yang/meter-service.yang
opendaylight/md-sal/model/model-flow-service/src/main/yang/port-service.yang
opendaylight/md-sal/model/model-flow-statistics/src/main/yang/flow-statistics.yang
opendaylight/md-sal/model/model-flow-statistics/src/main/yang/group-statistics.yang
opendaylight/md-sal/model/model-flow-statistics/src/main/yang/meter-statistics.yang
opendaylight/md-sal/model/model-flow-statistics/src/main/yang/port-statistics.yang
opendaylight/md-sal/model/model-flow-statistics/src/main/yang/queue-statistics.yang [new file with mode: 0644]
opendaylight/md-sal/model/model-flow-statistics/src/main/yang/statistics-types.yang
opendaylight/md-sal/pom.xml
opendaylight/md-sal/remoterpc-routingtable/implementation/pom.xml [moved from opendaylight/md-sal/zeromq-routingtable/implementation/pom.xml with 98% similarity]
opendaylight/md-sal/remoterpc-routingtable/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/api/RouteChangeListener.java [moved from opendaylight/md-sal/zeromq-routingtable/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/api/RouteChangeListener.java with 100% similarity]
opendaylight/md-sal/remoterpc-routingtable/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/api/RoutingTable.java [moved from opendaylight/md-sal/zeromq-routingtable/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/api/RoutingTable.java with 100% similarity]
opendaylight/md-sal/remoterpc-routingtable/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/api/RoutingTableException.java [moved from opendaylight/md-sal/zeromq-routingtable/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/api/RoutingTableException.java with 100% similarity]
opendaylight/md-sal/remoterpc-routingtable/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/api/SystemException.java [moved from opendaylight/md-sal/zeromq-routingtable/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/api/SystemException.java with 100% similarity]
opendaylight/md-sal/remoterpc-routingtable/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/impl/Activator.java [moved from opendaylight/md-sal/zeromq-routingtable/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/impl/Activator.java with 100% similarity]
opendaylight/md-sal/remoterpc-routingtable/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/impl/RoutingTableImpl.java [moved from opendaylight/md-sal/zeromq-routingtable/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/impl/RoutingTableImpl.java with 95% similarity]
opendaylight/md-sal/remoterpc-routingtable/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/impl/RoutingTableImplTest.java [moved from opendaylight/md-sal/zeromq-routingtable/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/impl/RoutingTableImplTest.java with 100% similarity]
opendaylight/md-sal/remoterpc-routingtable/integrationtest/pom.xml [moved from opendaylight/md-sal/zeromq-routingtable/integrationtest/pom.xml with 98% similarity]
opendaylight/md-sal/remoterpc-routingtable/integrationtest/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/impl/ZeroMQRoutingTableTestIT.java [moved from opendaylight/md-sal/zeromq-routingtable/integrationtest/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/impl/ZeroMQRoutingTableTestIT.java with 99% similarity]
opendaylight/md-sal/remoterpc-routingtable/integrationtest/src/test/resources/logback.xml [moved from opendaylight/md-sal/zeromq-routingtable/integrationtest/src/test/resources/logback.xml with 100% similarity]
opendaylight/md-sal/remoterpc-routingtable/integrationtest/test-nb/pom.xml [new file with mode: 0644]
opendaylight/md-sal/remoterpc-routingtable/integrationtest/test-nb/src/main/java/org/opendaylight/controller/tests/zmqroutingtable/rest/RouteIdentifierImpl.java [new file with mode: 0644]
opendaylight/md-sal/remoterpc-routingtable/integrationtest/test-nb/src/main/java/org/opendaylight/controller/tests/zmqroutingtable/rest/Router.java [new file with mode: 0644]
opendaylight/md-sal/remoterpc-routingtable/integrationtest/test-nb/src/main/resources/WEB-INF/web.xml [new file with mode: 0644]
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/RpcAvailabilityListener.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/BindingBrokerImplModule.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/DataBrokerImplModule.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/RuntimeMappingModule.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/RuntimeCodeGenerator.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/RuntimeCodeHelper.xtend
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/RpcRouterCodegenInstance.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/RpcRouterCodegenInstance.xtend [deleted file]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/RpcRoutingTableImpl.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/RpcRoutingTableImpl.xtend [deleted file]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/RuntimeCodeGenerator.xtend
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/SingletonHolder.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/XtendHelper.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/impl/LazyGeneratedCodecRegistry.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/impl/RuntimeGeneratedMappingServiceImpl.xtend
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/impl/TransformerGenerator.xtend
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/BindingAwareBrokerImpl.xtend
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationBrokerImpl.xtend
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/OsgiConsumerContext.xtend
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/RpcProviderRegistryImpl.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentConnector.java [moved from opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentDataServiceConnector.java with 58% similarity]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentMappingService.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/spi/RoutingContext.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/spi/RpcContextIdentifier.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/spi/RpcRouter.java
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/AbstractDataServiceTest.java
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/RuntimeCodeGeneratorTest.java
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/MultipleAugmentationPuts.java
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/util/BindingTestContext.java
opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/FlagsSerializationTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/CrossBrokerRpcTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/MessageCapturingFlowService.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-it/src/main/java/org/opendaylight/controller/test/sal/binding/it/TestHelper.java
opendaylight/md-sal/sal-common-api/src/main/java/org/opendaylight/controller/md/sal/common/api/routing/RouteChangePublisher.java
opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/routing/RoutingUtils.java [new file with mode: 0644]
opendaylight/md-sal/sal-common-util/pom.xml
opendaylight/md-sal/sal-common-util/src/main/java/org/opendaylight/controller/sal/common/util/Rpcs.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/BrokerImpl.xtend
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/RpcRouterImpl.xtend
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/SchemaAwareDataStoreAdapter.java
opendaylight/md-sal/sal-remoterpc-connector/implementation/pom.xml
opendaylight/md-sal/sal-remoterpc-connector/integrationtest/test-nb/pom.xml
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonMapper.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 [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/RestconfProvider.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/XmlMapper.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/ControllerContext.xtend
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/IdentityValuesDTO.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestCodec.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.xtend
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/SimpleNodeWrapper.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonBasicDataTypesTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonBasicYangTypesTest.java [moved from opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ToJsonBasicYangTypesTest.java with 87% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonChoiceCaseTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonIdentityrefTest.java [moved from opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ToJsonIdentityrefTest.java with 61% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonLeafrefType.java [moved from opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ToJsonLeafrefType.java with 75% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonWithAugmentTest.java [moved from opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ToJsonWithAugmentTest.java with 66% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonToCnSnTest.java [moved from opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/FromJsonToCompositeNodeTest.java with 73% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ReadConfAndOperDataTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestconfImplTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/TestUtils.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ToJsonBasicDataTypesTest.java [deleted file]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ToJsonChoiceCaseTest.java [deleted file]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/XmlProvidersTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/structures/Lf.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/structures/LfLst.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/structures/LstItem.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/xml/to/cnsn/test/XmlToCnSnTest.java [moved from opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/FromXmlToCompositeNodeTest.java with 65% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/augmentation/augment-container.yang [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/augment-container.yang with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/augmentation/augment-leaf.yang [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/augment-leaf.yang with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/augmentation/augment-leaflist.yang [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/augment-leaflist.yang with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/augmentation/augment-list.yang [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/augment-list.yang with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/augmentation/xml/data.xml [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/xml/data.xml with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/augmentation/yang.yang [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/yang.yang with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/choice/choice.yang [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/choice/choice.yang with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/choice/xml/data_case_defined_without_case.xml [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/choice/xml/data_case_defined_without_case.xml with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/choice/xml/data_container.xml [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/choice/xml/data_container.xml with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/choice/xml/data_leaflist.xml [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/choice/xml/data_leaflist.xml with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/choice/xml/data_list.xml [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/choice/xml/data_list.xml with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/choice/xml/data_more_choices_same_level.xml [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/choice/xml/data_more_choices_same_level.xml with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/choice/xml/data_more_choices_same_level_various_paths_err.xml [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/choice/xml/data_more_choices_same_level_various_paths_err.xml with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/choice/xml/data_no_first_case.xml [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/choice/xml/data_no_first_case.xml with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/choice/xml/data_random_level.xml [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/choice/xml/data_random_level.xml with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/choice/xml/data_three_choices_same_level.xml [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/choice/xml/data_three_choices_same_level.xml with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/choice/xml/data_various_path_err.xml [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/choice/xml/data_various_path_err.xml with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/identityref/identity-module.yang [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/identityref/identity-module.yang with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/identityref/identityref-module.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/leafref/cont-augment-module.yang [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/leafref/cont-augment-module.yang with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/leafref/main-module.yang [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/leafref/main-module.yang with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/leafref/xml/data_absolut_ref_to_existing_leaf.xml [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/leafref/xml/data_absolut_ref_to_existing_leaf.xml with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/leafref/xml/data_from_leafref_to_leafref.xml [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/leafref/xml/data_from_leafref_to_leafref.xml with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/leafref/xml/data_ref_to_non_existing_leaf.xml [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/leafref/xml/data_ref_to_non_existing_leaf.xml with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/leafref/xml/data_ref_to_not_leaf.xml [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/leafref/xml/data_ref_to_not_leaf.xml with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/leafref/xml/data_relativ_ref_from_leaflist_to_existing_leaf.xml [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/leafref/xml/data_relativ_ref_from_leaflist_to_existing_leaf.xml with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/leafref/xml/data_relativ_ref_to_existing_leaf.xml [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/leafref/xml/data_relativ_ref_to_existing_leaf.xml with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/simple-data-types/simple-data-types.yang [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/simple-data-types/simple-data-types.yang with 90% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/simple-data-types/xml/data.xml [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/simple-data-types/xml/data.xml with 80% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/simple-yang-types/simple-yang-types.yang [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/simple-yang-types/simple-yang-types.yang with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/simple-yang-types/xml/awaited_output_data.json [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/simple-yang-types/xml/awaited_output_data.json with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/simple-yang-types/xml/awaited_output_empty_data.json [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/simple-yang-types/xml/awaited_output_empty_data.json with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/simple-yang-types/xml/data.xml [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/simple-yang-types/xml/data.xml with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/simple-yang-types/xml/empty_data.xml [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/simple-yang-types/xml/empty_data.xml with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/instance_identifier/aug-referenced-elements-module.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/instance_identifier/eferenced-elements-module.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/instance_identifier/rinstance-identifier-module.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/yang/basic-module.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/yang/referenced-module.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/array-with-null.json [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-composite-node/array-with-null.json with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/empty-data.json [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-composite-node/empty-data.json with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/empty-data1.json [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-composite-node/empty-data1.json with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/identityref/identity-module.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/identityref/identityref-module.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/identityref/json/data.json [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/multiple-items-in-list.json [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-composite-node/multiple-items-in-list.json with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/multiple-leaflist-items.json [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-composite-node/multiple-leaflist-items.json with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/simple-container-yang/simple-container.yang [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-composite-node/simple-container-yang/simple-container.yang with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/simple-container.json [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-composite-node/simple-container.json with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/simple-list-yang/simple-list1.yang [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-composite-node/simple-list-yang/simple-list1.yang with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/simple-list-yang/simple-list2.yang [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-composite-node/simple-list-yang/simple-list2.yang with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/simple-list.json [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-composite-node/simple-list.json with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/wrong-top-level1.json [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-composite-node/wrong-top-level1.json with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/wrong-top-level2.json [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-composite-node/wrong-top-level2.json with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/wrong-top-level3.json [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-composite-node/wrong-top-level3.json with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/data-container-yang/data-container.yang [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-composite-node/data-container-yang/data-container.yang with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/data-container.xml [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-composite-node/data-container.xml with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/data-list-yang/data-container.yang [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-composite-node/data-list-yang/data-container.yang with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/data-list-yang/data-list.yang [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-composite-node/data-list-yang/data-list.yang with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/data-list.xml [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-composite-node/data-list.xml with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/data-nmspc-in-attributes.xml [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/empty-data.xml [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-composite-node/empty-data.xml with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/identity-module.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/identityref-module.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/xml/data-default-nmspc-in-element.xml [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/xml/data-default-nmspc-in-parrent-element.xml [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/xml/data-nmspc-in-element.xml [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/xml/data-nmspc-in-parrent-element.xml [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/xml/data-no-nmspc-value-with-prefix.xml [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/xml/data-no-nmspc-value-without-prefix.xml [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/yang-augments/general-module.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/yang-augments/identity-module.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/yang-augments/identityref-module.yang [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/identityref/identityref-module.yang with 69% similarity]
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/MultipartMessageManager.java
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/NodeStatistics.java
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsManagerActivator.java
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsProvider.java
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsUpdateCommiter.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationServiceImpl.java
opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationServiceImplTest.java [new file with mode: 0644]
opendaylight/netconf/config-persister-impl/pom.xml
opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/ConfigPusher.java
opendaylight/netconf/ietf-netconf-monitoring-extension/pom.xml [new file with mode: 0644]
opendaylight/netconf/ietf-netconf-monitoring-extension/src/main/yang/ietf-netconf-monitoring-extension.yang [new file with mode: 0644]
opendaylight/netconf/netconf-api/pom.xml
opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/NetconfMessage.java
opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClientDispatcher.java
opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClientSessionNegotiatorFactory.java
opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfSshClientDispatcher.java
opendaylight/netconf/netconf-impl/pom.xml
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSession.java
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionNegotiator.java
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/util/AdditionalHeaderUtil.java [new file with mode: 0644]
opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/AdditionalHeaderParserTest.java
opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/ConcurrentClientsTest.java
opendaylight/netconf/netconf-it/pom.xml
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-monitoring/pom.xml
opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/xml/model/MonitoringSession.java
opendaylight/netconf/netconf-monitoring/src/test/java/org/opendaylight/controller/netconf/monitoring/xml/JaxBSerializerTest.java
opendaylight/netconf/netconf-ssh/pom.xml
opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/osgi/NetconfSSHActivator.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 [new file with mode: 0644]
opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/AuthProviderInterface.java [new file with mode: 0644]
opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/RSAKey.java [deleted file]
opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/threads/SocketThread.java
opendaylight/netconf/netconf-ssh/src/main/resources/RSA.pk [new file with mode: 0644]
opendaylight/netconf/netconf-ssh/src/test/java/org/opendaylight/controller/netconf/SSHServerTest.java [moved from opendaylight/netconf/netconf-ssh/src/test/java/org/opendaylight/controller/netconf/ssh/SSHServerTest.java with 53% similarity]
opendaylight/netconf/netconf-ssh/src/test/java/org/opendaylight/controller/netconf/StubUserManager.java [new file with mode: 0644]
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/messages/NetconfMessageAdditionalHeader.java [new file with mode: 0644]
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/messages/NetconfMessageFactory.java
opendaylight/netconf/pom.xml
opendaylight/northbound/commons/src/main/java/org/opendaylight/controller/northbound/commons/NorthboundApplication.java
opendaylight/northbound/subnets/src/main/resources/WEB-INF/web.xml
opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/TopologyServiceShim.java
opendaylight/switchmanager/api/src/main/java/org/opendaylight/controller/switchmanager/Subnet.java
opendaylight/switchmanager/api/src/test/java/org/opendaylight/controller/switchmanager/SubnetTest.java
opendaylight/switchmanager/implementation/src/main/java/org/opendaylight/controller/switchmanager/internal/SwitchManager.java
opendaylight/usermanager/api/src/main/java/org/opendaylight/controller/usermanager/UserConfig.java
opendaylight/usermanager/api/src/test/java/org/opendaylight/controller/usermanager/AuthorizationUserConfigTest.java
opendaylight/usermanager/implementation/pom.xml
opendaylight/web/flows/src/main/resources/js/page.js

index c257e55..2647513 100644 (file)
@@ -16,7 +16,7 @@ import javax.management.ObjectName;
 /**
  * Represents functionality provided by configuration transaction.
  */
-public interface ConfigTransactionController extends LookupRegistry, ServiceReferenceReadableRegistry, ServiceReferenceWritableRegistry {
+public interface ConfigTransactionController extends LookupRegistry, ServiceReferenceWritableRegistry {
 
     /**
      * Create new configuration bean.
index 772617e..376ecdb 100644 (file)
@@ -65,8 +65,9 @@ public interface LookupRegistry {
      */
     void checkConfigBeanExists(ObjectName objectName) throws InstanceNotFoundException;
 
+
     /**
-     * @return qnames of all ModuleFactory instances in the system
+     * @return qNames of all ModuleFactory instances in the system
      */
     Set<String> getAvailableModuleFactoryQNames();
 
index f84fcd4..d7e94e8 100644 (file)
@@ -16,24 +16,24 @@ public interface ServiceReferenceReadableRegistry {
 
     /**
      * Lookup object name by fully qualified service interface name and service reference name.
-     * @param serviceInterfaceName service interface name
+     * @param serviceInterfaceQName service interface name
      * @param refName service reference name supplied in
      * {@link org.opendaylight.controller.config.api.ConfigTransactionController#saveServiceReference(String, String, javax.management.ObjectName)}
      * @throws java.lang.IllegalArgumentException if module not found
      */
-    ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceName, String refName);
+    ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceQName, String refName);
 
     /**
      * Get mapping of services to reference names and module object names.
      */
-    Map<String /* serviceInterfaceName */, Map<String/* refName */, ObjectName>> getServiceMapping();
+    Map<String /* serviceInterfaceQName */, Map<String/* refName */, ObjectName>> getServiceMapping();
 
     /**
      * Get current mapping between reference names and module object names for given service interface name.
-     * @param serviceInterfaceName service interface name
+     * @param serviceInterfaceQName service interface name
      * @throws IllegalArgumentException if there is a mismatch between serviceInterfaceName and objectName
      */
-    Map<String /* refName */, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceName);
+    Map<String /* refName */, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceQName);
 
     /**
      * Find all available service interface names of a module.
@@ -50,4 +50,13 @@ public interface ServiceReferenceReadableRegistry {
      */
     String getServiceInterfaceName(String namespace, String localName);
 
+    /**
+     * @return ObjectName with type=Service that was created using
+     * {@link org.opendaylight.controller.config.api.ServiceReferenceWritableRegistry#saveServiceReference(String, String,
+     * javax.management.ObjectName)}
+     */
+    ObjectName getServiceReference(String serviceInterfaceQName, String refName) throws InstanceNotFoundException;
+
+    void checkServiceReferenceExists(ObjectName objectName) throws InstanceNotFoundException;
+
 }
index f3d6d16..fa2aa1f 100644 (file)
@@ -13,17 +13,18 @@ import javax.management.ObjectName;
 public interface ServiceReferenceWritableRegistry extends ServiceReferenceReadableRegistry {
     /**
      * Create or update reference name to objectName. Reference name is unique per service interface name.
+     * @return created or updated object name containing service name and reference name
      * @throws IllegalArgumentException if there is a mismatch between serviceInterfaceName and objectName
      * @throws InstanceNotFoundException if search did not find exactly one instance
      */
-    void saveServiceReference(String serviceInterfaceName, String refName, ObjectName objectName) throws InstanceNotFoundException;
+    ObjectName saveServiceReference(String serviceInterfaceName, String refName, ObjectName moduleON) throws InstanceNotFoundException;
 
     /**
      * Remove service reference.
      * @return true iif removed
      * @throws IllegalArgumentException if service interface name is not advertised by any module
      */
-    boolean removeServiceReference(String serviceInterfaceName, String refName);
+    void removeServiceReference(String serviceInterfaceName, String refName) throws InstanceNotFoundException;
 
     /**
      * Remove all service references.
index cc1d897..3baa103 100644 (file)
@@ -25,21 +25,23 @@ import java.util.Set;
  * is defined as {@link #ON_DOMAIN} and at least one key-value pair. The only
  * mandatory property is {@link #TYPE_KEY}. All transaction related mbeans have
  * {@link #TRANSACTION_NAME_KEY} property set.
- *
  */
 @ThreadSafe
 public class ObjectNameUtil {
 
     public static final String ON_DOMAIN = ConfigRegistryConstants.ON_DOMAIN;
     public static final String MODULE_FACTORY_NAME_KEY = "moduleFactoryName";
+    public static final String SERVICE_QNAME_KEY = "serviceQName";
     public static final String INSTANCE_NAME_KEY = "instanceName";
     public static final String TYPE_KEY = ConfigRegistryConstants.TYPE_KEY;
     public static final String TYPE_CONFIG_REGISTRY = ConfigRegistryConstants.TYPE_CONFIG_REGISTRY;
     public static final String TYPE_CONFIG_TRANSACTION = "ConfigTransaction";
     public static final String TYPE_MODULE = "Module";
+    public static final String TYPE_SERVICE_REFERENCE = "ServiceReference";
     public static final String TYPE_RUNTIME_BEAN = "RuntimeBean";
-
     public static final String TRANSACTION_NAME_KEY = "TransactionName";
+    public static final String REF_NAME_KEY = "RefName";
+    private static final String REPLACED_QUOTATION_MARK = "\\?";
 
     public static ObjectName createON(String on) {
         try {
@@ -57,10 +59,10 @@ public class ObjectNameUtil {
         return ConfigRegistryConstants.createON(name, key, value);
     }
 
-    public static ObjectName createON(String name, Map<String, String> attribs) {
+    public static ObjectName createON(String domain, Map<String, String> attribs) {
         Hashtable<String, String> table = new Hashtable<>(attribs);
         try {
-            return new ObjectName(name, table);
+            return new ObjectName(domain, table);
         } catch (Exception e) {
             throw new RuntimeException(e);
         }
@@ -76,21 +78,21 @@ public class ObjectNameUtil {
     }
 
     public static ObjectName createTransactionModuleON(String transactionName,
-            ModuleIdentifier moduleIdentifier) {
+                                                       ModuleIdentifier moduleIdentifier) {
         return createTransactionModuleON(transactionName,
                 moduleIdentifier.getFactoryName(),
                 moduleIdentifier.getInstanceName());
     }
 
     public static ObjectName createTransactionModuleON(String transactionName,
-            String moduleName, String instanceName) {
-        Map<String, String> onParams = createModuleON(moduleName, instanceName);
+                                                       String moduleName, String instanceName) {
+        Map<String, String> onParams = createModuleMap(moduleName, instanceName);
         onParams.put(TRANSACTION_NAME_KEY, transactionName);
         return createON(ON_DOMAIN, onParams);
     }
 
     public static ObjectName createTransactionModuleON(String transactionName,
-            ObjectName on) {
+                                                       ObjectName on) {
         return createTransactionModuleON(transactionName, getFactoryName(on),
                 getInstanceName(on));
     }
@@ -101,14 +103,73 @@ public class ObjectNameUtil {
                 moduleIdentifier.getInstanceName());
     }
 
+    public static ObjectName createReadOnlyServiceON(String serviceQName, String refName) {
+        Map<String, String> onParams = createServiceMap(serviceQName, refName);
+        return createON(ON_DOMAIN, onParams);
+    }
+
+    public static ObjectName createTransactionServiceON(String transactionName, String serviceQName, String refName) {
+        Map<String, String> onParams = createServiceON(transactionName, serviceQName, refName);
+        return createON(ON_DOMAIN, onParams);
+    }
+
+    public static String getServiceQName(ObjectName objectName) {
+        checkType(objectName, TYPE_SERVICE_REFERENCE);
+        String quoted = objectName.getKeyProperty(SERVICE_QNAME_KEY);
+        String result = unquoteAndUnescape(objectName, quoted);
+        return result;
+    }
+
+    // ObjectName supports quotation and ignores tokens like =, but fails to ignore ? sign.
+    // It must be replaced with another character that hopefully does not collide
+    // with actual value.
+    private static String unquoteAndUnescape(ObjectName objectName, String quoted) {
+        if (quoted == null) {
+            throw new IllegalArgumentException("Cannot find " + SERVICE_QNAME_KEY + " in " + objectName);
+        }
+        if (quoted.startsWith("\"") == false || quoted.endsWith("\"") == false) {
+            throw new IllegalArgumentException("Quotes not found in " + objectName);
+        }
+        String substring = quoted.substring(1);
+        substring = substring.substring(0, substring.length() - 1);
+        substring = substring.replace(REPLACED_QUOTATION_MARK, "?");
+        return substring;
+    }
+
+    private static String quoteAndEscapeValue(String serviceQName) {
+        return "\"" + serviceQName.replace("?", REPLACED_QUOTATION_MARK) + "\"";
+    }
+
+    public static String getReferenceName(ObjectName objectName) {
+        checkType(objectName, TYPE_SERVICE_REFERENCE);
+        return objectName.getKeyProperty(REF_NAME_KEY);
+    }
+
+    private static Map<String, String> createServiceON(String transactionName, String serviceQName,
+                                                       String refName) {
+        Map<String, String> result = new HashMap<>(createServiceMap(serviceQName, refName));
+        result.put(TRANSACTION_NAME_KEY, transactionName);
+        return result;
+    }
+
+    private static Map<String, String> createServiceMap(String serviceQName,
+                                                        String refName) {
+        Map<String, String> onParams = new HashMap<>();
+        onParams.put(TYPE_KEY, TYPE_SERVICE_REFERENCE);
+        onParams.put(SERVICE_QNAME_KEY, quoteAndEscapeValue(serviceQName));
+        onParams.put(REF_NAME_KEY, refName);
+        return onParams;
+    }
+
+
     public static ObjectName createReadOnlyModuleON(String moduleName,
-            String instanceName) {
-        Map<String, String> onParams = createModuleON(moduleName, instanceName);
+                                                    String instanceName) {
+        Map<String, String> onParams = createModuleMap(moduleName, instanceName);
         return createON(ON_DOMAIN, onParams);
     }
 
-    private static Map<String, String> createModuleON(String moduleName,
-            String instanceName) {
+    private static Map<String, String> createModuleMap(String moduleName,
+                                                       String instanceName) {
         Map<String, String> onParams = new HashMap<>();
         onParams.put(TYPE_KEY, TYPE_MODULE);
         onParams.put(MODULE_FACTORY_NAME_KEY, moduleName);
@@ -117,10 +178,12 @@ public class ObjectNameUtil {
     }
 
     public static String getFactoryName(ObjectName objectName) {
+        checkTypeOneOf(objectName, TYPE_MODULE, TYPE_RUNTIME_BEAN);
         return objectName.getKeyProperty(MODULE_FACTORY_NAME_KEY);
     }
 
     public static String getInstanceName(ObjectName objectName) {
+        checkTypeOneOf(objectName, TYPE_MODULE, TYPE_RUNTIME_BEAN);
         return objectName.getKeyProperty(INSTANCE_NAME_KEY);
     }
 
@@ -132,6 +195,7 @@ public class ObjectNameUtil {
      * Sanitize on: keep only mandatory attributes of module + metadata.
      */
     public static ObjectName withoutTransactionName(ObjectName inputON) {
+        checkTypeOneOf(inputON, TYPE_MODULE, TYPE_SERVICE_REFERENCE);
         if (getTransactionName(inputON) == null) {
             throw new IllegalArgumentException(
                     "Expected ObjectName with transaction:" + inputON);
@@ -140,14 +204,18 @@ public class ObjectNameUtil {
             throw new IllegalArgumentException("Expected different domain: "
                     + inputON);
         }
-        String moduleName = getFactoryName(inputON);
-        String instanceName = getInstanceName(inputON);
-
-
+        Map<String, String> outputProperties;
+        if (inputON.getKeyProperty(TYPE_KEY).equals(TYPE_MODULE)) {
+            String moduleName = getFactoryName(inputON);
+            String instanceName = getInstanceName(inputON);
+            outputProperties = new HashMap<>(createModuleMap(moduleName, instanceName));
+        } else {
+            String serviceQName = getServiceQName(inputON);
+            String refName = getReferenceName(inputON);
+            outputProperties = new HashMap<>(createServiceMap(serviceQName, refName));
+        }
         Map<String, String> allProperties = getAdditionalProperties(inputON);
-        Map<String, String> outputProperties = new HashMap<>(createModuleON(moduleName, instanceName));
-
-        for(Entry<String, String> entry: allProperties.entrySet()) {
+        for (Entry<String, String> entry : allProperties.entrySet()) {
             if (entry.getKey().startsWith("X-")) {
                 outputProperties.put(entry.getKey(), entry.getValue());
             }
@@ -155,6 +223,13 @@ public class ObjectNameUtil {
         return createON(ON_DOMAIN, outputProperties);
     }
 
+    public static ObjectName withTransactionName(ObjectName inputON, String transactionName) {
+        Map<String, String> additionalProperties = getAdditionalProperties(inputON);
+        additionalProperties.put(TRANSACTION_NAME_KEY, transactionName);
+        return createON(inputON.getDomain(), additionalProperties);
+
+    }
+
     private static void assertDoesNotContain(
             Map<String, String> additionalProperties, String key) {
         if (additionalProperties.containsKey(key)) {
@@ -165,7 +240,7 @@ public class ObjectNameUtil {
     }
 
     public static ObjectName createRuntimeBeanName(String moduleName,
-            String instanceName, Map<String, String> additionalProperties) {
+                                                   String instanceName, Map<String, String> additionalProperties) {
         // check that there is no overwriting of default attributes
         assertDoesNotContain(additionalProperties, MODULE_FACTORY_NAME_KEY);
         assertDoesNotContain(additionalProperties, INSTANCE_NAME_KEY);
@@ -217,8 +292,18 @@ public class ObjectNameUtil {
         }
     }
 
+    public static void checkTypeOneOf(ObjectName objectName, String ... types) {
+        for(String type: types) {
+            if (type.equals(objectName.getKeyProperty(TYPE_KEY))) {
+                return;
+            }
+        }
+        throw new IllegalArgumentException("Wrong type, expected one of " + Arrays.asList(types)
+                + ", got " + objectName);
+    }
+
     public static ObjectName createModulePattern(String moduleName,
-            String instanceName) {
+                                                 String instanceName) {
         if (moduleName == null)
             moduleName = "*";
         if (instanceName == null)
@@ -235,7 +320,7 @@ public class ObjectNameUtil {
     }
 
     public static ObjectName createModulePattern(String ifcName,
-            String instanceName, String transactionName) {
+                                                 String instanceName, String transactionName) {
         return ObjectNameUtil.createON(ObjectNameUtil.ON_DOMAIN
                 + ":type=Module," + ObjectNameUtil.MODULE_FACTORY_NAME_KEY
                 + "=" + ifcName + "," + ObjectNameUtil.INSTANCE_NAME_KEY + "="
@@ -244,7 +329,7 @@ public class ObjectNameUtil {
     }
 
     public static ObjectName createRuntimeBeanPattern(String moduleName,
-            String instanceName) {
+                                                      String instanceName) {
         return ObjectNameUtil.createON(ObjectNameUtil.ON_DOMAIN + ":"
                 + ObjectNameUtil.TYPE_KEY + "="
                 + ObjectNameUtil.TYPE_RUNTIME_BEAN + ","
@@ -255,7 +340,7 @@ public class ObjectNameUtil {
     }
 
     public static ModuleIdentifier fromON(ObjectName objectName,
-            String expectedType) {
+                                          String expectedType) {
         checkType(objectName, expectedType);
         String factoryName = getFactoryName(objectName);
         if (factoryName == null)
@@ -268,4 +353,7 @@ public class ObjectNameUtil {
         return new ModuleIdentifier(factoryName, instanceName);
     }
 
+    public static boolean isServiceReference(ObjectName objectName) {
+        return TYPE_SERVICE_REFERENCE.equals(objectName.getKeyProperty(TYPE_KEY));
+    }
 }
diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/CloseableServiceReferenceReadableRegistry.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/CloseableServiceReferenceReadableRegistry.java
new file mode 100644 (file)
index 0000000..8c32507
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * 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 org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry;
+
+public interface CloseableServiceReferenceReadableRegistry  extends AutoCloseable, ServiceReferenceReadableRegistry {
+
+
+    void close();
+
+}
index e3311c7..1923170 100644 (file)
@@ -10,7 +10,6 @@ package org.opendaylight.controller.config.manager.impl;
 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.ServiceReferenceReadableRegistry;
 import org.opendaylight.controller.config.api.ServiceReferenceWritableRegistry;
 import org.opendaylight.controller.config.api.ValidationException;
 import org.opendaylight.controller.config.api.jmx.CommitStatus;
@@ -104,7 +103,7 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
     private List<ModuleFactory> lastListOfFactories = Collections.emptyList();
 
     @GuardedBy("this") // switched in every 2ndPC
-    private ServiceReferenceReadableRegistry readableSRRegistry = ServiceReferenceRegistryImpl.createInitialSRLookupRegistry();
+    private CloseableServiceReferenceReadableRegistry  readableSRRegistry = ServiceReferenceRegistryImpl.createInitialSRLookupRegistry();
 
     // constructor
     public ConfigRegistryImpl(ModuleFactoriesResolver resolver,
@@ -298,8 +297,7 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
             OsgiRegistration osgiRegistration = null;
             if (entry.hasOldModule()) {
                 ModuleInternalInfo oldInternalInfo = entry.getOldInternalInfo();
-                DynamicReadableWrapper oldReadableConfigBean = oldInternalInfo
-                        .getReadableModule();
+                DynamicReadableWrapper oldReadableConfigBean = oldInternalInfo.getReadableModule();
                 currentConfig.remove(entry.getIdentifier());
 
                 // test if old instance == new instance
@@ -368,7 +366,9 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
         version = configTransactionController.getVersion();
 
         // switch readable Service Reference Registry
-        this.readableSRRegistry = ServiceReferenceRegistryImpl.createSRReadableRegistry(configTransactionController.getWritableRegistry(), this);
+        this.readableSRRegistry.close();
+        this.readableSRRegistry = ServiceReferenceRegistryImpl.createSRReadableRegistry(
+                configTransactionController.getWritableRegistry(), this, baseJMXRegistrator);
 
         return new CommitStatus(newInstances, reusedInstances,
                 recreatedInstances);
@@ -525,8 +525,8 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
 
     // service reference functionality:
     @Override
-    public synchronized ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceName, String refName) {
-        return readableSRRegistry.lookupConfigBeanByServiceInterfaceName(serviceInterfaceName, refName);
+    public synchronized ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceQName, String refName) {
+        return readableSRRegistry.lookupConfigBeanByServiceInterfaceName(serviceInterfaceQName, refName);
     }
 
     @Override
@@ -535,8 +535,8 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
     }
 
     @Override
-    public synchronized Map<String, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceName) {
-        return readableSRRegistry.lookupServiceReferencesByServiceInterfaceName(serviceInterfaceName);
+    public synchronized Map<String, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceQName) {
+        return readableSRRegistry.lookupServiceReferencesByServiceInterfaceName(serviceInterfaceQName);
     }
 
     @Override
@@ -549,11 +549,28 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
         return readableSRRegistry.getServiceInterfaceName(namespace, localName);
     }
 
+    @Override
+    public void checkServiceReferenceExists(ObjectName objectName) throws InstanceNotFoundException {
+        readableSRRegistry.checkServiceReferenceExists(objectName);
+    }
+
+    @Override
+    public ObjectName getServiceReference(String serviceInterfaceQName, String refName) throws InstanceNotFoundException {
+        return readableSRRegistry.getServiceReference(serviceInterfaceQName, refName);
+    }
+
     @Override
     public Set<String> getAvailableModuleFactoryQNames() {
         return ModuleQNameUtil.getQNames(resolver.getAllFactories());
     }
 
+    @Override
+    public String toString() {
+        return "ConfigRegistryImpl{" +
+                "versionCounter=" + versionCounter +
+                ", version=" + version +
+                '}';
+    }
 }
 
 /**
@@ -579,12 +596,12 @@ class ConfigHolder {
     }
 
     private void add(ModuleInternalInfo configInfo) {
-        ModuleInternalInfo oldValue = currentConfig.put(configInfo.getName(),
+        ModuleInternalInfo oldValue = currentConfig.put(configInfo.getIdentifier(),
                 configInfo);
         if (oldValue != null) {
             throw new IllegalStateException(
                     "Cannot overwrite module with same name:"
-                            + configInfo.getName() + ":" + configInfo);
+                            + configInfo.getIdentifier() + ":" + configInfo);
         }
     }
 
index 17ce078..e0d1a42 100644 (file)
@@ -95,7 +95,7 @@ class ConfigTransactionControllerImpl implements
         this.currentlyRegisteredFactories = currentlyRegisteredFactories;
         this.factoriesHolder = new HierarchicalConfigMBeanFactoriesHolder(currentlyRegisteredFactories);
         this.transactionStatus = new TransactionStatus();
-        this.dependencyResolverManager = new DependencyResolverManager(transactionName, transactionStatus);
+        this.dependencyResolverManager = new DependencyResolverManager(transactionName, transactionStatus, writableSRRegistry);
         this.transactionsMBeanServer = transactionsMBeanServer;
         this.configMBeanServer = configMBeanServer;
         this.blankTransaction = blankTransaction;
@@ -165,15 +165,14 @@ class ConfigTransactionControllerImpl implements
             throws InstanceAlreadyExistsException {
         transactionStatus.checkNotCommitStarted();
         transactionStatus.checkNotAborted();
-        ModuleIdentifier moduleIdentifier = oldConfigBeanInfo.getName();
+        ModuleIdentifier moduleIdentifier = oldConfigBeanInfo.getIdentifier();
         dependencyResolverManager.assertNotExists(moduleIdentifier);
 
         ModuleFactory moduleFactory = factoriesHolder
                 .findByModuleName(moduleIdentifier.getFactoryName());
 
         Module module;
-        DependencyResolver dependencyResolver = dependencyResolverManager
-                .getOrCreate(moduleIdentifier);
+        DependencyResolver dependencyResolver = dependencyResolverManager.getOrCreate(moduleIdentifier);
         try {
             BundleContext bc = getModuleFactoryBundleContext(moduleFactory.getImplementationName());
             module = moduleFactory.createModule(
@@ -412,7 +411,7 @@ class ConfigTransactionControllerImpl implements
         close();
     }
 
-    private void close() {
+    public void close() {
         //FIXME: should not close object that was retrieved in constructor, a wrapper object should do that perhaps
         txLookupRegistry.close();
     }
@@ -523,8 +522,8 @@ class ConfigTransactionControllerImpl implements
 
 
     @Override
-    public synchronized ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceName, String refName) {
-        return writableSRRegistry.lookupConfigBeanByServiceInterfaceName(serviceInterfaceName, refName);
+    public synchronized ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceQName, String refName) {
+        return writableSRRegistry.lookupConfigBeanByServiceInterfaceName(serviceInterfaceQName, refName);
     }
 
     @Override
@@ -533,8 +532,8 @@ class ConfigTransactionControllerImpl implements
     }
 
     @Override
-    public synchronized Map<String, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceName) {
-        return writableSRRegistry.lookupServiceReferencesByServiceInterfaceName(serviceInterfaceName);
+    public synchronized Map<String, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceQName) {
+        return writableSRRegistry.lookupServiceReferencesByServiceInterfaceName(serviceInterfaceQName);
     }
 
     @Override
@@ -548,13 +547,13 @@ class ConfigTransactionControllerImpl implements
     }
 
     @Override
-    public synchronized void saveServiceReference(String serviceInterfaceName, String refName, ObjectName objectName) throws InstanceNotFoundException {
-        writableSRRegistry.saveServiceReference(serviceInterfaceName, refName, objectName);
+    public synchronized ObjectName saveServiceReference(String serviceInterfaceName, String refName, ObjectName moduleON) throws InstanceNotFoundException {
+        return writableSRRegistry.saveServiceReference(serviceInterfaceName, refName, moduleON);
     }
 
     @Override
-    public synchronized boolean removeServiceReference(String serviceInterfaceName, String refName) {
-        return writableSRRegistry.removeServiceReference(serviceInterfaceName, refName);
+    public synchronized void removeServiceReference(String serviceInterfaceName, String refName) throws InstanceNotFoundException {
+        writableSRRegistry.removeServiceReference(serviceInterfaceName, refName);
     }
 
     @Override
@@ -581,4 +580,13 @@ class ConfigTransactionControllerImpl implements
         return txLookupRegistry.getAvailableModuleFactoryQNames();
     }
 
+    @Override
+    public void checkServiceReferenceExists(ObjectName objectName) throws InstanceNotFoundException {
+        writableSRRegistry.checkServiceReferenceExists(objectName);
+    }
+
+    @Override
+    public ObjectName getServiceReference(String serviceInterfaceQName, String refName) throws InstanceNotFoundException {
+        return writableSRRegistry.getServiceReference(serviceInterfaceQName, refName);
+    }
 }
index 12db6c8..a7d426e 100644 (file)
@@ -117,6 +117,13 @@ class ConfigTransactionLookupRegistry  implements LookupRegistry, Closeable {
         return ModuleQNameUtil.getQNames(allCurrentFactories);
     }
 
+
+    @Override
+    public String toString() {
+        return "ConfigTransactionLookupRegistry{" +
+                "transactionIdentifier=" + transactionIdentifier +
+                '}';
+    }
 }
 
 interface TransactionJMXRegistratorFactory {
index 14a706d..941aec1 100644 (file)
@@ -90,11 +90,6 @@ public class ModuleInternalInfo implements Comparable<ModuleInternalInfo>,
         return osgiRegistration;
     }
 
-    @Deprecated
-    public ModuleIdentifier getName() {
-        return name;
-    }
-
     /**
      * Get index representing dependency ordering within a transaction.
      */
@@ -111,7 +106,7 @@ public class ModuleInternalInfo implements Comparable<ModuleInternalInfo>,
     }
 
     public DestroyedModule toDestroyedModule() {
-        return new DestroyedModule(getName(),
+        return new DestroyedModule(getIdentifier(),
                 getReadableModule().getInstance(), getModuleJMXRegistrator(),
                 getOsgiRegistration(), getOrderingIdx());
     }
index 7fedcdf..0faa32b 100644 (file)
@@ -13,42 +13,52 @@ import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry;
 import org.opendaylight.controller.config.api.ServiceReferenceWritableRegistry;
 import org.opendaylight.controller.config.api.annotations.ServiceInterfaceAnnotation;
 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.ServiceReference;
+import org.opendaylight.controller.config.manager.impl.jmx.ServiceReferenceMXBeanImpl;
+import org.opendaylight.controller.config.manager.impl.jmx.ServiceReferenceRegistrator;
+import org.opendaylight.controller.config.manager.impl.jmx.ServiceReferenceRegistrator.ServiceReferenceJMXRegistration;
+import org.opendaylight.controller.config.manager.impl.jmx.ServiceReferenceRegistrator.ServiceReferenceTransactionRegistratorFactory;
+import org.opendaylight.controller.config.manager.impl.jmx.ServiceReferenceRegistrator.ServiceReferenceTransactionRegistratorFactoryImpl;
 import org.opendaylight.controller.config.manager.impl.util.InterfacesHelper;
 import org.opendaylight.controller.config.spi.ModuleFactory;
 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.Iterator;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
 
-public class ServiceReferenceRegistryImpl implements ServiceReferenceReadableRegistry, ServiceReferenceWritableRegistry {
+public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceReadableRegistry, ServiceReferenceWritableRegistry {
     private static final Logger logger = LoggerFactory.getLogger(ServiceReferenceRegistryImpl.class);
 
     private final Map<String, ModuleFactory> factories;
     private final Map<String, Set<String>> factoryNamesToQNames;
     // validator of incoming ObjectNames - throws InstanceNotFoundException if not found either in registry or transaction
     private final LookupRegistry lookupRegistry;
+    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;
     // all Service Interface qNames for sanity checking
     private final Set<String /* qName */> allQNames;
 
     // actual reference database
-    private final Map<String /* qName */, Map<String /* refName */, ModuleIdentifier>> refNames;
+    private final Map<ServiceReference, ModuleIdentifier> refNames = new HashMap<>();
+    private final boolean writable;
+    private final Map<ServiceReference, Entry<ServiceReferenceMXBeanImpl, ServiceReferenceJMXRegistration>> mBeans = new HashMap<>();
 
     /**
      * Static constructor for config registry. Since only transaction can write to this registry, it will
      * return blank state.
      */
-    public static ServiceReferenceReadableRegistry createInitialSRLookupRegistry() {
+    public static CloseableServiceReferenceReadableRegistry createInitialSRLookupRegistry() {
         // since this is initial state, just throw exception:
         LookupRegistry lookupRegistry = new LookupRegistry() {
             @Override
@@ -73,36 +83,99 @@ public class ServiceReferenceRegistryImpl implements ServiceReferenceReadableReg
 
             @Override
             public void checkConfigBeanExists(ObjectName objectName) throws InstanceNotFoundException {
-                throw new InstanceNotFoundException("Cannot find " + objectName);
+                throw new InstanceNotFoundException("Cannot find " + objectName + " - Tried to use mocking registry");
             }
 
             @Override
             public Set<String> getAvailableModuleFactoryQNames() {
                 throw new UnsupportedOperationException();
             }
+
+            @Override
+            public String toString() {
+                return "initial";
+            }
+        };
+        ServiceReferenceTransactionRegistratorFactory serviceReferenceRegistratorFactory = new ServiceReferenceTransactionRegistratorFactory(){
+            @Override
+            public ServiceReferenceRegistrator create() {
+                return new ServiceReferenceRegistrator() {
+                    @Override
+                    public String getNullableTransactionName() {
+                        throw new UnsupportedOperationException();
+                    }
+
+                    @Override
+                    public ServiceReferenceJMXRegistration registerMBean(ServiceReferenceMXBeanImpl object, ObjectName on) throws InstanceAlreadyExistsException {
+                        throw new UnsupportedOperationException();
+                    }
+
+                    @Override
+                    public void close() {
+
+                    }
+                };
+            }
         };
         return new ServiceReferenceRegistryImpl(Collections.<String, ModuleFactory>emptyMap(), lookupRegistry,
-                Collections.<String /* qName */, Map<String /* refName */, ModuleIdentifier>>emptyMap());
+                serviceReferenceRegistratorFactory, false);
     }
 
     /**
      * Static constructor for transaction controller. Take current state as seen by config registry, allow writing new data.
      */
     public static ServiceReferenceWritableRegistry createSRWritableRegistry(ServiceReferenceReadableRegistry oldReadableRegistry,
-            LookupRegistry lookupRegistry, Map<String, Map.Entry<ModuleFactory, BundleContext>> currentlyRegisteredFactories) {
+                                                    ConfigTransactionLookupRegistry txLookupRegistry,
+                                                    Map<String, Map.Entry<ModuleFactory, BundleContext>> currentlyRegisteredFactories) {
 
+        if (txLookupRegistry == null) {
+            throw new IllegalArgumentException("txLookupRegistry is null");
+        }
         ServiceReferenceRegistryImpl old = (ServiceReferenceRegistryImpl) oldReadableRegistry;
         Map<String, ModuleFactory> factories = extractFactoriesMap(currentlyRegisteredFactories);
-        return new ServiceReferenceRegistryImpl(factories, lookupRegistry, Collections.unmodifiableMap(old.refNames));
+        ServiceReferenceTransactionRegistratorFactory serviceReferenceRegistratorFactory = new ServiceReferenceTransactionRegistratorFactoryImpl(
+                txLookupRegistry.getTxModuleJMXRegistrator(), txLookupRegistry.getTxModuleJMXRegistrator().getTransactionName());
+        ServiceReferenceRegistryImpl newRegistry = new ServiceReferenceRegistryImpl(factories, txLookupRegistry,
+                serviceReferenceRegistratorFactory, true);
+        copy(old, newRegistry, txLookupRegistry.getTransactionIdentifier().getName());
+        return newRegistry;
     }
 
     /**
      * Copy back state to config registry after commit.
      */
-    public static ServiceReferenceReadableRegistry createSRReadableRegistry(ServiceReferenceWritableRegistry oldWritableRegistry, LookupRegistry lookupRegistry) {
+    public static CloseableServiceReferenceReadableRegistry createSRReadableRegistry(ServiceReferenceWritableRegistry oldWritableRegistry,
+                                                                            LookupRegistry lookupRegistry, BaseJMXRegistrator baseJMXRegistrator) {
         ServiceReferenceRegistryImpl old = (ServiceReferenceRegistryImpl) oldWritableRegistry;
+
         // even if factories do change, nothing in the mapping can change between transactions
-        return new ServiceReferenceRegistryImpl(old.factories, lookupRegistry, Collections.unmodifiableMap(old.refNames));
+        ServiceReferenceTransactionRegistratorFactory serviceReferenceRegistratorFactory = new ServiceReferenceTransactionRegistratorFactoryImpl(baseJMXRegistrator);
+        ServiceReferenceRegistryImpl newRegistry = new ServiceReferenceRegistryImpl(old.factories, lookupRegistry,
+                serviceReferenceRegistratorFactory, false);
+        copy(old, newRegistry, null);
+        return newRegistry;
+    }
+
+    /**
+     * Fill refNames and mBeans maps from old instance
+     */
+    private static void copy(ServiceReferenceRegistryImpl old, ServiceReferenceRegistryImpl newRegistry, String nullableDstTransactionName) {
+        for (Entry<ServiceReference, Entry<ServiceReferenceMXBeanImpl, ServiceReferenceJMXRegistration>> refNameEntry : old.mBeans.entrySet()) {
+            ObjectName currentImplementation;
+            ObjectName currentImplementationSrc = refNameEntry.getValue().getKey().getCurrentImplementation();
+            if (nullableDstTransactionName != null) {
+                currentImplementation = ObjectNameUtil.withTransactionName(currentImplementationSrc, nullableDstTransactionName);
+            } else {
+                currentImplementation = ObjectNameUtil.withoutTransactionName(currentImplementationSrc);
+            }
+            try {
+                boolean skipChecks = true;
+                newRegistry.saveServiceReference(refNameEntry.getKey(), currentImplementation, skipChecks);
+            } catch (InstanceNotFoundException e) {
+                logger.error("Cannot save service reference({}, {})", refNameEntry.getKey(), currentImplementation);
+                throw new IllegalStateException("Possible code error", e);
+            }
+        }
     }
 
     private static Map<String, ModuleFactory> extractFactoriesMap(Map<String, Map.Entry<ModuleFactory, BundleContext>> currentlyRegisteredFactories) {
@@ -114,9 +187,14 @@ public class ServiceReferenceRegistryImpl implements ServiceReferenceReadableReg
     }
 
     private ServiceReferenceRegistryImpl(Map<String, ModuleFactory> factories, LookupRegistry lookupRegistry,
-                                         Map<String /* qName */, Map<String /* refName */, ModuleIdentifier>> refNamesToCopy) {
+                                         ServiceReferenceTransactionRegistratorFactory serviceReferenceRegistratorFactory,
+                                         boolean writable) {
         this.factories = factories;
+        this.writable = writable;
         this.lookupRegistry = lookupRegistry;
+
+        this.serviceReferenceRegistrator = serviceReferenceRegistratorFactory.create();
+
         Map<String, Set<String /* QName */>> factoryNamesToQNames = new HashMap<>();
         Set<ServiceInterfaceAnnotation> allAnnotations = new HashSet<>();
         Set<String /* qName */> allQNames = new HashSet<>();
@@ -154,22 +232,12 @@ public class ServiceReferenceRegistryImpl implements ServiceReferenceReadableReg
         }
         this.namespacesToAnnotations = Collections.unmodifiableMap(namespacesToAnnotations);
         // copy refNames
-        Map<String /* qName */, Map<String /* refName */, ModuleIdentifier>> deepCopy = new HashMap<>();
-        for (Entry<String, Map<String, ModuleIdentifier>> outerROEntry: refNamesToCopy.entrySet()) {
-            Map<String /* refName */, ModuleIdentifier> innerWritableMap = new HashMap<>();
-            deepCopy.put(outerROEntry.getKey(), innerWritableMap);
-            for (Entry<String, ModuleIdentifier> innerROEntry:  outerROEntry.getValue().entrySet()) {
-                innerWritableMap.put(innerROEntry.getKey(), innerROEntry.getValue());
-            }
-        }
-        this.refNames = deepCopy;
         logger.trace("factoryNamesToQNames:{}", this.factoryNamesToQNames);
-        logger.trace("refNames:{}", refNames);
     }
 
 
     @Override
-    public Set<String> lookupServiceInterfaceNames(ObjectName objectName) throws InstanceNotFoundException {
+    public synchronized Set<String> lookupServiceInterfaceNames(ObjectName objectName) throws InstanceNotFoundException {
         lookupRegistry.checkConfigBeanExists(objectName);
 
         String factoryName = ObjectNameUtil.getFactoryName(objectName);
@@ -183,7 +251,7 @@ public class ServiceReferenceRegistryImpl implements ServiceReferenceReadableReg
     }
 
     @Override
-    public String getServiceInterfaceName(String namespace, String localName) {
+    public synchronized String getServiceInterfaceName(String namespace, String localName) {
         Map<String /* localName */, ServiceInterfaceAnnotation> ofNamespace = namespacesToAnnotations.get(namespace);
         if (ofNamespace == null) {
             logger.error("Cannot find namespace {} in {}", namespace, namespacesToAnnotations);
@@ -197,23 +265,19 @@ public class ServiceReferenceRegistryImpl implements ServiceReferenceReadableReg
         return sia.value();
     }
 
-
-
     // reading:
 
     @Override
-    public Map<String /* serviceInterfaceName */, Map<String/* refName */, ObjectName>> getServiceMapping() {
+    public synchronized Map<String /* serviceInterfaceName */, Map<String/* refName */, ObjectName>> getServiceMapping() {
         Map<String /* serviceInterfaceName */, Map<String/* refName */, ObjectName>> result = new HashMap<>();
-        for (Entry<String /* qName */, Map<String, ModuleIdentifier>> outerEntry: refNames.entrySet()) {
-            String qName = outerEntry.getKey();
-            Map<String /* refName */, ObjectName> innerMap = new HashMap<>();
-            result.put(qName, innerMap);
-            for (Entry<String /* refName */, ModuleIdentifier> innerEntry: outerEntry.getValue().entrySet()) {
-                ModuleIdentifier moduleIdentifier = innerEntry.getValue();
-                ObjectName on;
-                on = getObjectName(moduleIdentifier);
-                innerMap.put(innerEntry.getKey(), on);
+        for (Entry<ServiceReference, ModuleIdentifier> entry: refNames.entrySet()) {
+            String qName = entry.getKey().getServiceInterfaceName();
+            Map<String /* refName */, ObjectName> innerMap = result.get(qName);
+            if (innerMap == null) {
+                innerMap = new HashMap<>();
+                result.put(qName, innerMap);
             }
+            innerMap.put(entry.getKey().getRefName(), getObjectName(entry.getValue()));
         }
         return result;
     }
@@ -230,116 +294,227 @@ public class ServiceReferenceRegistryImpl implements ServiceReferenceReadableReg
     }
 
     @Override
-    public ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceName, String refName) {
-        Map<String, ModuleIdentifier> innerMap = refNames.get(serviceInterfaceName);
-        if (innerMap == null) {
-            logger.error("Cannot find qname {} in {}", serviceInterfaceName, refName);
-            throw new IllegalArgumentException("Cannot find " + serviceInterfaceName);
-        }
-        ModuleIdentifier moduleIdentifier = innerMap.get(refName);
+    public synchronized ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceQName, String refName) {
+        ServiceReference serviceReference = new ServiceReference(serviceInterfaceQName, refName);
+        ModuleIdentifier moduleIdentifier = refNames.get(serviceReference);
         if (moduleIdentifier == null) {
-            logger.error("Cannot find refName {} in {}, using qname {}", refName, innerMap, serviceInterfaceName);
-            throw new IllegalArgumentException("Cannot find module based on service reference " + refName);
+            logger.error("Cannot find qname {} and refName {} in {}", serviceInterfaceQName, refName, refName);
+            throw new IllegalArgumentException("Cannot find " + serviceReference);
         }
         return getObjectName(moduleIdentifier);
     }
 
     @Override
-    public  Map<String /* refName */, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceName) {
-        Map<String, ModuleIdentifier> innerMap = refNames.get(serviceInterfaceName);
+    public synchronized Map<String /* refName */, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceQName) {
+        Map<String, Map<String, ObjectName>> serviceMapping = getServiceMapping();
+        Map<String, ObjectName> innerMap = serviceMapping.get(serviceInterfaceQName);
         if (innerMap == null) {
-            logger.error("Cannot find qname {} in {}", serviceInterfaceName, refNames);
-            throw new IllegalArgumentException("Cannot find " + serviceInterfaceName);
+            logger.error("Cannot find qname {} in {}", serviceInterfaceQName, refNames);
+            throw new IllegalArgumentException("Cannot find " + serviceInterfaceQName);
         }
-        Map<String /* refName */, ObjectName> result = new HashMap<>();
-        for (Entry<String/* refName */, ModuleIdentifier> entry: innerMap.entrySet()) {
-            ObjectName on = getObjectName(entry.getValue());
-            result.put(entry.getKey(), on);
+        return innerMap;
+    }
+
+    @Override
+    public synchronized ObjectName getServiceReference(String serviceInterfaceQName, String refName) throws InstanceNotFoundException {
+        ServiceReference serviceReference = new ServiceReference(serviceInterfaceQName, refName);
+        if (mBeans.containsKey(serviceReference) == false) {
+            throw new InstanceNotFoundException("Cannot find " + serviceReference);
+        }
+        return getServiceON(serviceReference);
+    }
+
+    @Override
+    public synchronized void checkServiceReferenceExists(ObjectName objectName) throws InstanceNotFoundException {
+        String actualTransactionName = ObjectNameUtil.getTransactionName(objectName);
+        String expectedTransactionName = serviceReferenceRegistrator.getNullableTransactionName();
+        if (writable & actualTransactionName == null || (writable && actualTransactionName.equals(expectedTransactionName) == false)) {
+            throw new IllegalArgumentException("Mismatched transaction name in " + objectName);
+        }
+        String serviceQName = ObjectNameUtil.getServiceQName(objectName);
+        String referenceName = ObjectNameUtil.getReferenceName(objectName);
+        ServiceReference serviceReference = new ServiceReference(serviceQName, referenceName);
+        if (refNames.containsKey(serviceReference) == false) {
+            logger.warn("Cannot find {} in {}", serviceReference, refNames);
+            throw new InstanceNotFoundException("Service reference not found:" + objectName);
         }
-        return result;
     }
 
     // writing:
 
+    private void assertWritable() {
+        if (writable == false) {
+            throw new IllegalStateException("Cannot write to readable registry");
+        }
+    }
+
     @Override
-    public void saveServiceReference(String serviceInterfaceName, String refName, ObjectName objectName)  throws InstanceNotFoundException {
+    public synchronized ObjectName saveServiceReference(String serviceInterfaceName, String refName, ObjectName moduleON)  throws InstanceNotFoundException {
+        assertWritable();
+        ServiceReference serviceReference = new ServiceReference(serviceInterfaceName, refName);
+        return saveServiceReference(serviceReference, moduleON);
+    }
+
+    private synchronized ObjectName saveServiceReference(ServiceReference serviceReference, ObjectName moduleON)
+            throws InstanceNotFoundException{
+        return saveServiceReference(serviceReference, moduleON, false);
+    }
+
+    private synchronized ObjectName saveServiceReference(ServiceReference serviceReference, ObjectName moduleON,
+                                                         boolean skipChecks) throws InstanceNotFoundException {
+
         // make sure it is found
-        lookupRegistry.checkConfigBeanExists(objectName);
-        String factoryName = ObjectNameUtil.getFactoryName(objectName);
+        if (skipChecks == false) {
+            lookupRegistry.checkConfigBeanExists(moduleON);
+        }
+        String factoryName = ObjectNameUtil.getFactoryName(moduleON);
+        String instanceName = ObjectNameUtil.getInstanceName(moduleON);
+        ModuleIdentifier moduleIdentifier = new ModuleIdentifier(factoryName, instanceName);
+
         // check that service interface name exist
-        Set<String> serviceInterfaceQNames = factoryNamesToQNames.get(factoryName);
+        Set<String> serviceInterfaceQNames = factoryNamesToQNames.get(moduleIdentifier.getFactoryName());
         if (serviceInterfaceQNames == null) {
-            logger.error("Possible error in code: cannot find factoryName {} in {}, object name {}", factoryName, factoryNamesToQNames, objectName);
-            throw new IllegalStateException("Possible error in code: cannot find annotations of existing factory " + factoryName);
+            logger.error("Possible error in code: cannot find factoryName {} in {}, {}", moduleIdentifier.getFactoryName(),
+                    factoryNamesToQNames, moduleIdentifier);
+            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(serviceInterfaceName) == false) {
-            logger.error("Cannot find qname {} with factory name {}, found {}", serviceInterfaceName, factoryName, serviceInterfaceQNames);
-            throw new IllegalArgumentException("Cannot find service interface " + serviceInterfaceName + " within factory " + factoryName );
+        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());
         }
-        String instanceName = ObjectNameUtil.getInstanceName(objectName);
-        ModuleIdentifier moduleIdentifier = new ModuleIdentifier(factoryName, instanceName);
-        Map<String /* refName */, ModuleIdentifier> ofQName = refNames.get(serviceInterfaceName);
-        // might be null
-        if (ofQName == null) {
-            ofQName = new HashMap<>();
-            refNames.put(serviceInterfaceName, ofQName);
+
+
+        // create service reference object name, put to mBeans
+        ObjectName result = getServiceON(serviceReference);
+        Entry<ServiceReferenceMXBeanImpl, ServiceReferenceJMXRegistration> mxBeanEntry = mBeans.get(serviceReference);
+        if (mxBeanEntry == null) {
+            // create dummy mx bean
+            ServiceReferenceMXBeanImpl dummyMXBean = new ServiceReferenceMXBeanImpl(moduleON);
+            ServiceReferenceJMXRegistration dummyMXBeanRegistration;
+            try {
+                dummyMXBeanRegistration = serviceReferenceRegistrator.registerMBean(dummyMXBean, result);
+            } catch (InstanceAlreadyExistsException e) {
+                throw new IllegalStateException("Possible error in code. Cannot register " + result, e);
+            }
+            mBeans.put(serviceReference, createMXBeanEntry(dummyMXBean, dummyMXBeanRegistration));
+        } else {
+            // update
+            mxBeanEntry.getKey().setCurrentImplementation(moduleON);
+        }
+        // save to refNames
+        refNames.put(serviceReference, moduleIdentifier);
+        return result;
+    }
+
+    private Entry<ServiceReferenceMXBeanImpl, ServiceReferenceJMXRegistration> createMXBeanEntry(
+            final ServiceReferenceMXBeanImpl mxBean, final ServiceReferenceJMXRegistration registration) {
+        return new Entry<ServiceReferenceMXBeanImpl, ServiceReferenceJMXRegistration>() {
+            @Override
+            public ServiceReferenceMXBeanImpl getKey() {
+                return mxBean;
+            }
+
+            @Override
+            public ServiceReferenceJMXRegistration getValue() {
+                return registration;
+            }
+
+            @Override
+            public ServiceReferenceJMXRegistration setValue(ServiceReferenceJMXRegistration value) {
+                throw new UnsupportedOperationException();
+            }
+        };
+    }
+
+    private ObjectName getServiceON(ServiceReference serviceReference) {
+        if (writable) {
+            return ObjectNameUtil.createTransactionServiceON(serviceReferenceRegistrator.getNullableTransactionName(),
+                    serviceReference.getServiceInterfaceName(), serviceReference.getRefName());
+        } else {
+            return ObjectNameUtil.createReadOnlyServiceON(serviceReference.getServiceInterfaceName(), serviceReference.getRefName());
         }
-        ofQName.put(refName, moduleIdentifier);
     }
 
     @Override
-    public boolean removeServiceReference(String serviceInterfaceName, String refName) {
-        // is the qname known?
-        if (allQNames.contains(serviceInterfaceName) == false) {
-            logger.error("Cannot find qname {} in {}", serviceInterfaceName, allQNames);
-            throw new IllegalArgumentException("Cannot find service interface " + serviceInterfaceName);
+    public synchronized void removeServiceReference(String serviceInterfaceName, String refName) throws InstanceNotFoundException{
+        ServiceReference serviceReference = new ServiceReference(serviceInterfaceName, refName);
+        removeServiceReference(serviceReference);
+    }
+
+    private synchronized void removeServiceReference(ServiceReference serviceReference) throws InstanceNotFoundException {
+        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());
+        }
+        ModuleIdentifier removed = refNames.remove(serviceReference);
+        if (removed == null){
+            throw new InstanceNotFoundException("Cannot find " + serviceReference.getServiceInterfaceName());
         }
-        Map<String, ModuleIdentifier> ofQName = refNames.get(serviceInterfaceName);
-        if (ofQName == null) {
-            return false;
+        Entry<ServiceReferenceMXBeanImpl, ServiceReferenceJMXRegistration> entry = mBeans.remove(serviceReference);
+        if (entry == null) {
+            throw new IllegalStateException("Possible code error: cannot remove from mBeans: " + serviceReference);
         }
-        return ofQName.remove(refName) != null;
+        entry.getValue().close();
     }
 
     @Override
-    public void removeAllServiceReferences() {
-        refNames.clear();
+    public synchronized void removeAllServiceReferences() {
+        assertWritable();
+        for (ServiceReference serviceReference: mBeans.keySet()) {
+            try {
+                removeServiceReference(serviceReference);
+            } catch (InstanceNotFoundException e) {
+                throw new IllegalStateException("Possible error in code", e);
+            }
+        }
     }
 
     @Override
-    public boolean removeServiceReferences(ObjectName objectName) throws InstanceNotFoundException {
-        lookupRegistry.checkConfigBeanExists(objectName);
-        String factoryName = ObjectNameUtil.getFactoryName(objectName);
+    public synchronized boolean removeServiceReferences(ObjectName moduleObjectName) throws InstanceNotFoundException {
+        assertWritable();
+        Set<ServiceReference> serviceReferencesLinkingTo = findServiceReferencesLinkingTo(moduleObjectName);
+        for (ServiceReference sr : serviceReferencesLinkingTo) {
+            removeServiceReference(sr);
+        }
+        return serviceReferencesLinkingTo.isEmpty() == false;
+    }
+
+    private synchronized Set<ServiceReference> findServiceReferencesLinkingTo(ObjectName moduleObjectName)  throws InstanceNotFoundException {
+        lookupRegistry.checkConfigBeanExists(moduleObjectName);
+        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, objectName);
+            logger.error("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(objectName);
+        String instanceName = ObjectNameUtil.getInstanceName(moduleObjectName);
         ModuleIdentifier moduleIdentifier = new ModuleIdentifier(factoryName, instanceName);
-        boolean found = false;
-        for(String qName: serviceInterfaceQNames){
-            Map<String, ModuleIdentifier> ofQName = refNames.get(qName);
-            if (ofQName != null) {
-                for(Iterator<Entry<String, ModuleIdentifier>> it = ofQName.entrySet ().iterator(); it.hasNext();){
-                    Entry<String, ModuleIdentifier> next = it.next();
-                    if (next.getValue().equals(moduleIdentifier)) {
-                        found = true;
-                        it.remove();
-                    }
-                }
+        Set<ServiceReference> result = new HashSet<>();
+        for (Entry<ServiceReference, ModuleIdentifier> entry : refNames.entrySet()) {
+            if (entry.getValue().equals(moduleIdentifier)) {
+                result.add(entry.getKey());
             }
         }
-        return found;
+        return result;
     }
 
+
     @Override
     public String toString() {
         return "ServiceReferenceRegistryImpl{" +
+                "lookupRegistry=" + lookupRegistry +
                 "refNames=" + refNames +
                 ", factoryNamesToQNames=" + factoryNamesToQNames +
                 '}';
     }
+
+    @Override
+    public void close() {
+        serviceReferenceRegistrator.close();
+    }
 }
index 760fe50..925a57b 100644 (file)
@@ -11,6 +11,7 @@ import org.opendaylight.controller.config.api.DependencyResolver;
 import org.opendaylight.controller.config.api.JmxAttribute;
 import org.opendaylight.controller.config.api.JmxAttributeValidationException;
 import org.opendaylight.controller.config.api.ModuleIdentifier;
+import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry;
 import org.opendaylight.controller.config.api.annotations.AbstractServiceInterface;
 import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
 import org.opendaylight.controller.config.manager.impl.TransactionStatus;
@@ -37,12 +38,16 @@ final class DependencyResolverImpl implements DependencyResolver,
     private final TransactionStatus transactionStatus;
     @GuardedBy("this")
     private final Set<ModuleIdentifier> dependencies = new HashSet<>();
+    private final ServiceReferenceReadableRegistry readableRegistry;
 
     DependencyResolverImpl(ModuleIdentifier currentModule,
-            TransactionStatus transactionStatus, ModulesHolder modulesHolder) {
+            TransactionStatus transactionStatus, ModulesHolder modulesHolder,
+            ServiceReferenceReadableRegistry readableRegistry) {
+
         this.name = currentModule;
         this.transactionStatus = transactionStatus;
         this.modulesHolder = modulesHolder;
+        this.readableRegistry = readableRegistry;
     }
 
     /**
@@ -52,7 +57,7 @@ final class DependencyResolverImpl implements DependencyResolver,
     @Override
     public void validateDependency(
             Class<? extends AbstractServiceInterface> expectedServiceInterface,
-            ObjectName dependentModuleReadOnlyON, JmxAttribute jmxAttribute) {
+            ObjectName dependentReadOnlyON, JmxAttribute jmxAttribute) {
 
         transactionStatus.checkNotCommitted();
         if (expectedServiceInterface == null) {
@@ -62,22 +67,26 @@ final class DependencyResolverImpl implements DependencyResolver,
         if (jmxAttribute == null)
             throw new NullPointerException("Parameter 'jmxAttribute' is null");
 
-        JmxAttributeValidationException.checkNotNull(dependentModuleReadOnlyON,
+        JmxAttributeValidationException.checkNotNull(dependentReadOnlyON,
                 "is null, " + "expected dependency implementing "
                         + expectedServiceInterface, jmxAttribute);
 
+
+
         // check that objectName belongs to this transaction - this should be
         // stripped
         // in DynamicWritableWrapper
         boolean hasTransaction = ObjectNameUtil
-                .getTransactionName(dependentModuleReadOnlyON) != null;
+                .getTransactionName(dependentReadOnlyON) != null;
         JmxAttributeValidationException.checkCondition(
                 hasTransaction == false,
                 format("ObjectName should not contain "
                         + "transaction name. %s set to %s. ", jmxAttribute,
-                        dependentModuleReadOnlyON), jmxAttribute);
+                        dependentReadOnlyON), jmxAttribute);
+
+        dependentReadOnlyON = translateServiceRefIfPossible(dependentReadOnlyON);
 
-        ModuleIdentifier moduleIdentifier = ObjectNameUtil.fromON(dependentModuleReadOnlyON, ObjectNameUtil
+        ModuleIdentifier moduleIdentifier = ObjectNameUtil.fromON(dependentReadOnlyON, ObjectNameUtil
                 .TYPE_MODULE);
 
         ModuleFactory foundFactory = modulesHolder.findModuleFactory(moduleIdentifier, jmxAttribute);
@@ -90,7 +99,7 @@ final class DependencyResolverImpl implements DependencyResolver,
                             + "Module name is %s : %s, expected service interface %s, dependent module ON %s , "
                             + "attribute %s",
                     foundFactory.getImplementationName(), foundFactory,
-                    expectedServiceInterface, dependentModuleReadOnlyON,
+                    expectedServiceInterface, dependentReadOnlyON,
                     jmxAttribute);
             throw new JmxAttributeValidationException(message, jmxAttribute);
         }
@@ -99,24 +108,35 @@ final class DependencyResolverImpl implements DependencyResolver,
         }
     }
 
+    // transalate from serviceref to module ON
+    private ObjectName translateServiceRefIfPossible(ObjectName dependentReadOnlyON) {
+        if (ObjectNameUtil.isServiceReference(dependentReadOnlyON)) {
+            String serviceQName = ObjectNameUtil.getServiceQName(dependentReadOnlyON);
+            String refName = ObjectNameUtil.getReferenceName(dependentReadOnlyON);
+            dependentReadOnlyON = ObjectNameUtil.withoutTransactionName( // strip again of transaction name
+                    readableRegistry.lookupConfigBeanByServiceInterfaceName(serviceQName, refName));
+        }
+        return dependentReadOnlyON;
+    }
+
     /**
      * {@inheritDoc}
      */
     //TODO: check for cycles
     @Override
-    public <T> T resolveInstance(Class<T> expectedType, ObjectName dependentON,
+    public <T> T resolveInstance(Class<T> expectedType, ObjectName dependentReadOnlyON,
             JmxAttribute jmxAttribute) {
-        if (expectedType == null || dependentON == null || jmxAttribute == null) {
+        if (expectedType == null || dependentReadOnlyON == null || jmxAttribute == null) {
             throw new IllegalArgumentException(format(
                     "Null parameters not allowed, got {} {} {}", expectedType,
-                    dependentON, jmxAttribute));
+                    dependentReadOnlyON, jmxAttribute));
         }
-
+        dependentReadOnlyON = translateServiceRefIfPossible(dependentReadOnlyON);
         transactionStatus.checkCommitStarted();
         transactionStatus.checkNotCommitted();
 
         ModuleIdentifier dependentModuleIdentifier = ObjectNameUtil.fromON(
-                dependentON, ObjectNameUtil.TYPE_MODULE);
+                dependentReadOnlyON, ObjectNameUtil.TYPE_MODULE);
         Module module = modulesHolder.findModule(dependentModuleIdentifier,
                 jmxAttribute);
         synchronized (this) {
index 645aab3..afd865c 100644 (file)
@@ -11,6 +11,7 @@ import org.opendaylight.controller.config.api.DependencyResolver;
 import org.opendaylight.controller.config.api.DependencyResolverFactory;
 import org.opendaylight.controller.config.api.JmxAttribute;
 import org.opendaylight.controller.config.api.ModuleIdentifier;
+import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry;
 import org.opendaylight.controller.config.manager.impl.CommitInfo;
 import org.opendaylight.controller.config.manager.impl.ModuleInternalTransactionalInfo;
 import org.opendaylight.controller.config.manager.impl.TransactionStatus;
@@ -35,11 +36,13 @@ public class DependencyResolverManager implements TransactionHolder, DependencyR
     private final Map<ModuleIdentifier, DependencyResolverImpl> moduleIdentifiersToDependencyResolverMap = new HashMap<>();
     private final ModulesHolder modulesHolder;
     private final TransactionStatus transactionStatus;
+    private final ServiceReferenceReadableRegistry readableRegistry;
 
     public DependencyResolverManager(String transactionName,
-            TransactionStatus transactionStatus) {
+            TransactionStatus transactionStatus, ServiceReferenceReadableRegistry readableRegistry) {
         this.modulesHolder = new ModulesHolder(transactionName);
         this.transactionStatus = transactionStatus;
+        this.readableRegistry = readableRegistry;
     }
 
     @Override
@@ -48,14 +51,11 @@ public class DependencyResolverManager implements TransactionHolder, DependencyR
     }
 
     public synchronized DependencyResolverImpl getOrCreate(ModuleIdentifier name) {
-        DependencyResolverImpl dependencyResolver = moduleIdentifiersToDependencyResolverMap
-                .get(name);
+        DependencyResolverImpl dependencyResolver = moduleIdentifiersToDependencyResolverMap.get(name);
         if (dependencyResolver == null) {
             transactionStatus.checkNotCommitted();
-            dependencyResolver = new DependencyResolverImpl(name,
-                    transactionStatus, modulesHolder);
-            moduleIdentifiersToDependencyResolverMap.put(name,
-                    dependencyResolver);
+            dependencyResolver = new DependencyResolverImpl(name, transactionStatus, modulesHolder, readableRegistry);
+            moduleIdentifiersToDependencyResolverMap.put(name, dependencyResolver);
         }
         return dependencyResolver;
     }
index ba2c108..6f0d1b2 100644 (file)
@@ -7,16 +7,14 @@
  */
 package org.opendaylight.controller.config.manager.impl.dynamicmbean;
 
-import static java.lang.String.format;
-
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import org.opendaylight.controller.config.api.ModuleIdentifier;
+import org.opendaylight.controller.config.api.annotations.Description;
+import org.opendaylight.controller.config.api.annotations.RequireInterface;
+import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
+import org.opendaylight.controller.config.manager.impl.util.InterfacesHelper;
+import org.opendaylight.controller.config.spi.Module;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import javax.management.Attribute;
 import javax.management.AttributeList;
@@ -40,15 +38,17 @@ import javax.management.Notification;
 import javax.management.NotificationListener;
 import javax.management.ObjectName;
 import javax.management.ReflectionException;
+import java.lang.reflect.Array;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
-import org.opendaylight.controller.config.api.ModuleIdentifier;
-import org.opendaylight.controller.config.api.annotations.Description;
-import org.opendaylight.controller.config.api.annotations.RequireInterface;
-import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
-import org.opendaylight.controller.config.manager.impl.util.InterfacesHelper;
-import org.opendaylight.controller.config.spi.Module;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import static java.lang.String.format;
 
 /**
  * Contains common code for readable/rw dynamic mbean wrappers. Routes all
@@ -246,6 +246,7 @@ abstract class AbstractDynamicWrapper implements DynamicMBeanModuleWrapper {
         } catch (InstanceNotFoundException e) {
             new MBeanException(e);
         }
+
         if (obj instanceof ObjectName) {
             AttributeHolder attributeHolder = attributeHolderMap
                     .get(attributeName);
@@ -254,8 +255,42 @@ abstract class AbstractDynamicWrapper implements DynamicMBeanModuleWrapper {
             }
             return obj;
         }
+
+
+        if(isDependencyListAttr(attributeName, obj)) {
+            obj = fixDependencyListAttribute(obj);
+        }
+
         return obj;
+    }
+
+    private Object fixDependencyListAttribute(Object attribute) {
+        if(attribute.getClass().isArray() == false)
+            throw new IllegalArgumentException("Unexpected attribute type, should be an array, but was " + attribute.getClass());
+
+        for (int i = 0; i < Array.getLength(attribute); i++) {
+
+            Object on = Array.get(attribute, i);
+            if(on instanceof ObjectName == false)
+                throw new IllegalArgumentException("Unexpected attribute type, should be an ObjectName, but was " + on.getClass());
+            on = fixObjectName((ObjectName) on);
+
+            Array.set(attribute, i, on);
+        }
+
+        return attribute;
+    }
+
+    private boolean isDependencyListAttr(String attributeName, Object attribute) {
+        if (attributeHolderMap.containsKey(attributeName) == false)
+            return false;
+
+        AttributeHolder attributeHolder = attributeHolderMap.get(attributeName);
 
+        boolean isDepList = true;
+        isDepList &= attributeHolder.getRequireInterfaceOrNull() != null;
+        isDepList &= attribute instanceof ObjectName[];
+        return isDepList;
     }
 
     protected ObjectName fixObjectName(ObjectName on) {
index 109ab10..9dd6a22 100644 (file)
@@ -7,18 +7,17 @@
  */
 package org.opendaylight.controller.config.manager.impl.dynamicmbean;
 
-import java.lang.reflect.Method;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
+import org.opendaylight.controller.config.api.annotations.Description;
+import org.opendaylight.controller.config.api.annotations.RequireInterface;
 
 import javax.annotation.Nullable;
 import javax.annotation.concurrent.Immutable;
 import javax.management.MBeanAttributeInfo;
 import javax.management.ObjectName;
-
-import org.opendaylight.controller.config.api.annotations.Description;
-import org.opendaylight.controller.config.api.annotations.RequireInterface;
+import java.lang.reflect.Method;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
 
 @Immutable
 class AttributeHolder {
@@ -32,6 +31,14 @@ class AttributeHolder {
     private final RequireInterface requireInterfaceAnnotation;
     private final String attributeType;
 
+    public static final Set<Class<?>> PERMITTED_PARAMETER_TYPES_FOR_DEPENDENCY_SETTER = new HashSet<>();
+
+    static {
+        PERMITTED_PARAMETER_TYPES_FOR_DEPENDENCY_SETTER.add(ObjectName.class);
+        PERMITTED_PARAMETER_TYPES_FOR_DEPENDENCY_SETTER.add(ObjectName[].class);
+        PERMITTED_PARAMETER_TYPES_FOR_DEPENDENCY_SETTER.add(List.class);
+    }
+
     public AttributeHolder(String name, Object object, String returnType,
             boolean writable,
             @Nullable RequireInterface requireInterfaceAnnotation,
@@ -114,12 +121,12 @@ class AttributeHolder {
     static RequireInterface findRequireInterfaceAnnotation(final Method setter,
             Set<Class<?>> inspectedInterfaces) {
 
-        // only allow setX(ObjectName y) or setX(ObjectName[] y) to continue
-        if (setter.getParameterTypes().length != 1
-                || (setter.getParameterTypes()[0].equals(ObjectName.class) == false && setter
-                        .getParameterTypes()[0].equals(ObjectName[].class) == false)) {
+        // only allow setX(ObjectName y) or setX(ObjectName[] y) or setX(List<ObjectName> y) to continue
+
+        if (setter.getParameterTypes().length > 1)
+            return null;
+        if(PERMITTED_PARAMETER_TYPES_FOR_DEPENDENCY_SETTER.contains(setter.getParameterTypes()[0]) == false)
             return null;
-        }
 
         List<RequireInterface> foundRequireInterfaces = AnnotationsHelper
                 .findMethodAnnotationInSuperClassesAndIfcs(setter, RequireInterface.class, inspectedInterfaces);
index a1cd6b0..2ab04e5 100644 (file)
@@ -7,7 +7,13 @@
  */
 package org.opendaylight.controller.config.manager.impl.dynamicmbean;
 
-import java.lang.reflect.Method;
+import org.opendaylight.controller.config.api.ModuleIdentifier;
+import org.opendaylight.controller.config.api.ValidationException;
+import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
+import org.opendaylight.controller.config.manager.impl.TransactionIdentifier;
+import org.opendaylight.controller.config.spi.Module;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import javax.annotation.concurrent.ThreadSafe;
 import javax.management.Attribute;
@@ -20,14 +26,7 @@ import javax.management.MBeanOperationInfo;
 import javax.management.MBeanServer;
 import javax.management.ObjectName;
 import javax.management.ReflectionException;
-
-import org.opendaylight.controller.config.api.ModuleIdentifier;
-import org.opendaylight.controller.config.api.ValidationException;
-import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
-import org.opendaylight.controller.config.manager.impl.TransactionIdentifier;
-import org.opendaylight.controller.config.spi.Module;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import java.lang.reflect.Method;
 
 /**
  * Wraps {@link org.opendaylight.controller.config.spi.Module} instance in a
@@ -92,16 +91,11 @@ public class DynamicWritableWrapper extends AbstractDynamicWrapper {
 
         try {
             if (attribute.getValue() instanceof ObjectName) {
-                AttributeHolder attributeHolder = attributeHolderMap
-                        .get(attribute.getName());
-                if (attributeHolder.getRequireInterfaceOrNull() != null) {
-                    attribute = new Attribute(attribute.getName(),
-                            fixObjectName((ObjectName) attribute.getValue()));
-                } else {
-                    attribute = new Attribute(attribute.getName(),
-                            attribute.getValue());
-                }
+                attribute = fixDependencyAttribute(attribute);
+            } else if(attribute.getValue() instanceof ObjectName[]) {
+                attribute = fixDependencyListAttribute(attribute);
             }
+
             internalServer.setAttribute(objectNameInternal, attribute);
         } catch (InstanceNotFoundException e) {
             throw new MBeanException(e);
@@ -109,6 +103,39 @@ public class DynamicWritableWrapper extends AbstractDynamicWrapper {
 
     }
 
+    private Attribute fixDependencyListAttribute(Attribute attribute) {
+        AttributeHolder attributeHolder = attributeHolderMap
+                .get(attribute.getName());
+        if (attributeHolder.getRequireInterfaceOrNull() != null) {
+            attribute = new Attribute(attribute.getName(),
+                    fixObjectNames((ObjectName[]) attribute.getValue()));
+        }
+        return attribute;
+    }
+
+    private Attribute fixDependencyAttribute(Attribute attribute) {
+        AttributeHolder attributeHolder = attributeHolderMap
+                .get(attribute.getName());
+        if (attributeHolder.getRequireInterfaceOrNull() != null) {
+            attribute = new Attribute(attribute.getName(),
+                    fixObjectName((ObjectName) attribute.getValue()));
+        } else {
+            attribute = new Attribute(attribute.getName(),
+                    attribute.getValue());
+        }
+        return attribute;
+    }
+
+    private ObjectName[] fixObjectNames(ObjectName[] dependencies) {
+        int i = 0;
+
+        for (ObjectName dependencyOn : dependencies) {
+            dependencies[i++] = fixObjectName(dependencyOn);
+        }
+
+        return dependencies;
+    }
+
     @Override
     public AttributeList setAttributes(AttributeList attributes) {
         AttributeList result = new AttributeList();
index 09bc1f8..d09fc75 100644 (file)
@@ -14,7 +14,7 @@ import javax.management.ObjectName;
 import javax.management.QueryExp;
 import java.util.Set;
 
-public class BaseJMXRegistrator implements AutoCloseable {
+public class BaseJMXRegistrator implements AutoCloseable, NestableJMXRegistrator {
 
     private final InternalJMXRegistrator internalJMXRegistrator;
 
@@ -50,6 +50,11 @@ public class BaseJMXRegistrator implements AutoCloseable {
         return internalJMXRegistrator.getRegisteredObjectNames();
     }
 
+    @Override
+    public InternalJMXRegistrator createChild() {
+        return internalJMXRegistrator.createChild();
+    }
+
     @Override
     public void close() {
         internalJMXRegistrator.close();
@@ -5,10 +5,9 @@
  * terms of the Eclipse 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.ssh.authentication;
+package org.opendaylight.controller.config.manager.impl.jmx;
 
-import ch.ethz.ssh2.signature.RSAPrivateKey;
+public interface NestableJMXRegistrator {
 
-public interface KeyStoreHandler {
-    public RSAPrivateKey getPrivateKey();
+    InternalJMXRegistrator createChild();
 }
diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/jmx/ServiceReference.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/jmx/ServiceReference.java
new file mode 100644 (file)
index 0000000..849f752
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * 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.jmx;
+
+public class ServiceReference {
+    private final String serviceInterfaceName, refName;
+
+    public ServiceReference(String serviceInterfaceName, String refName) {
+        this.serviceInterfaceName = serviceInterfaceName;
+        this.refName = refName;
+    }
+
+    public String getServiceInterfaceName() {
+        return serviceInterfaceName;
+    }
+
+    public String getRefName() {
+        return refName;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        ServiceReference that = (ServiceReference) o;
+
+        if (!refName.equals(that.refName)) return false;
+        if (!serviceInterfaceName.equals(that.serviceInterfaceName)) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = serviceInterfaceName.hashCode();
+        result = 31 * result + refName.hashCode();
+        return result;
+    }
+}
diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/jmx/ServiceReferenceMXBean.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/jmx/ServiceReferenceMXBean.java
new file mode 100644 (file)
index 0000000..759541d
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * 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.jmx;
+
+import javax.management.ObjectName;
+
+public interface ServiceReferenceMXBean {
+
+    ObjectName getCurrentImplementation();
+
+}
diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/jmx/ServiceReferenceMXBeanImpl.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/jmx/ServiceReferenceMXBeanImpl.java
new file mode 100644 (file)
index 0000000..dedeeed
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * 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.jmx;
+
+import javax.management.ObjectName;
+
+public class ServiceReferenceMXBeanImpl implements ServiceReferenceMXBean {
+    private ObjectName currentImplementation;
+
+    public ServiceReferenceMXBeanImpl(ObjectName currentImplementation) {
+        this.currentImplementation = currentImplementation;
+    }
+
+    @Override
+    public ObjectName getCurrentImplementation() {
+        return currentImplementation;
+    }
+
+    public void setCurrentImplementation(ObjectName currentImplementation) {
+        this.currentImplementation = currentImplementation;
+    }
+}
diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/jmx/ServiceReferenceRegistrator.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/jmx/ServiceReferenceRegistrator.java
new file mode 100644 (file)
index 0000000..160ee18
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * 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.jmx;
+
+import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
+import org.opendaylight.controller.config.manager.impl.jmx.InternalJMXRegistrator.InternalJMXRegistration;
+
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.ObjectName;
+
+public interface ServiceReferenceRegistrator extends AutoCloseable {
+
+    public String getNullableTransactionName();
+
+    ServiceReferenceJMXRegistration registerMBean(ServiceReferenceMXBeanImpl object,
+                                                          ObjectName on) throws InstanceAlreadyExistsException;
+
+    @Override
+    void close();
+
+    public static class ServiceReferenceJMXRegistration implements AutoCloseable {
+        private final InternalJMXRegistration registration;
+
+        ServiceReferenceJMXRegistration(InternalJMXRegistration registration) {
+            this.registration = registration;
+        }
+
+        @Override
+        public void close() {
+            registration.close();
+        }
+    }
+
+    public static interface ServiceReferenceTransactionRegistratorFactory {
+        public ServiceReferenceRegistrator create();
+    }
+
+    public static class ServiceReferenceRegistratorImpl implements ServiceReferenceRegistrator {
+        private final InternalJMXRegistrator currentJMXRegistrator;
+        private final String nullableTransactionName;
+
+        public ServiceReferenceRegistratorImpl(NestableJMXRegistrator parentRegistrator, String nullableTransactionName){
+            currentJMXRegistrator = parentRegistrator.createChild();
+            this.nullableTransactionName = nullableTransactionName;
+        }
+
+        public String getNullableTransactionName() {
+            return nullableTransactionName;
+        }
+
+
+        public ServiceReferenceJMXRegistration registerMBean(ServiceReferenceMXBeanImpl object,
+                                                             ObjectName on) throws InstanceAlreadyExistsException {
+            String actualTransactionName = ObjectNameUtil.getTransactionName(on);
+            boolean broken = false;
+            broken |= (nullableTransactionName == null) != (actualTransactionName == null);
+            broken |= (nullableTransactionName != null) && nullableTransactionName.equals(actualTransactionName) == false;
+            if (broken) {
+                throw new IllegalArgumentException("Transaction name mismatch between expected "
+                        + nullableTransactionName + ", got " + actualTransactionName + " in " + on);
+            }
+            if (ObjectNameUtil.isServiceReference(on) == false) {
+                throw new IllegalArgumentException("Invalid type of " + on);
+            }
+            return new ServiceReferenceJMXRegistration(currentJMXRegistrator.registerMBean(object, on));
+        }
+
+
+        @Override
+        public void close() {
+            currentJMXRegistrator.close();
+        }
+        public static interface ServiceReferenceTransactionRegistratorFactory {
+            public ServiceReferenceRegistrator create();
+        }
+    }
+
+
+    public static class ServiceReferenceTransactionRegistratorFactoryImpl implements ServiceReferenceTransactionRegistratorFactory {
+        private final NestableJMXRegistrator parentRegistrator;
+        private final String nullableTransactionName;
+
+        public ServiceReferenceTransactionRegistratorFactoryImpl(TransactionModuleJMXRegistrator parentRegistrator,
+                                                             String nullableTransactionName) {
+            this.parentRegistrator = parentRegistrator;
+            this.nullableTransactionName = nullableTransactionName;
+        }
+
+        public ServiceReferenceTransactionRegistratorFactoryImpl(BaseJMXRegistrator baseJMXRegistrator) {
+            this.parentRegistrator = baseJMXRegistrator;
+            this.nullableTransactionName = null;
+        }
+
+        public ServiceReferenceRegistrator create() {
+            return new ServiceReferenceRegistratorImpl(parentRegistrator, nullableTransactionName);
+        }
+    }
+}
index 546adb0..238fd24 100644 (file)
@@ -17,14 +17,14 @@ import javax.management.QueryExp;
 import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
 import org.opendaylight.controller.config.manager.impl.jmx.InternalJMXRegistrator.InternalJMXRegistration;
 
-public class TransactionModuleJMXRegistrator implements Closeable {
-    private final InternalJMXRegistrator childJMXRegistrator;
+public class TransactionModuleJMXRegistrator implements Closeable, NestableJMXRegistrator {
+    private final InternalJMXRegistrator currentJMXRegistrator;
     private final String transactionName;
 
     public TransactionModuleJMXRegistrator(
             InternalJMXRegistrator internalJMXRegistrator,
             String transactionName) {
-        this.childJMXRegistrator = internalJMXRegistrator.createChild();
+        this.currentJMXRegistrator = internalJMXRegistrator.createChild();
         this.transactionName = transactionName;
     }
 
@@ -44,21 +44,29 @@ public class TransactionModuleJMXRegistrator implements Closeable {
 
     public TransactionModuleJMXRegistration registerMBean(Object object,
             ObjectName on) throws InstanceAlreadyExistsException {
-        if (!transactionName.equals(ObjectNameUtil.getTransactionName(on)))
-            throw new IllegalArgumentException(
-                    "Transaction name mismatch between expected "
+        if (transactionName.equals(ObjectNameUtil.getTransactionName(on)) == false) {
+            throw new IllegalArgumentException("Transaction name mismatch between expected "
                             + transactionName + " " + "and " + on);
-        ObjectNameUtil.checkType(on, ObjectNameUtil.TYPE_MODULE);
+        }
+        ObjectNameUtil.checkTypeOneOf(on, ObjectNameUtil.TYPE_MODULE);
         return new TransactionModuleJMXRegistration(
-                childJMXRegistrator.registerMBean(object, on));
+                currentJMXRegistrator.registerMBean(object, on));
     }
 
     public Set<ObjectName> queryNames(ObjectName name, QueryExp query) {
-        return childJMXRegistrator.queryNames(name, query);
+        return currentJMXRegistrator.queryNames(name, query);
     }
 
     @Override
     public void close() {
-        childJMXRegistrator.close();
+        currentJMXRegistrator.close();
+    }
+
+    public String getTransactionName() {
+        return transactionName;
+    }
+
+    public InternalJMXRegistrator createChild() {
+        return currentJMXRegistrator.createChild();
     }
 }
index a7e3fa6..81b0921 100644 (file)
@@ -7,13 +7,20 @@
  */
 package org.opendaylight.controller.config.manager.impl;
 
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Maps;
+import junit.framework.Assert;
 import org.junit.After;
 import org.mockito.Matchers;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
 import org.opendaylight.controller.config.api.jmx.CommitStatus;
 import org.opendaylight.controller.config.manager.impl.factoriesresolver.ModuleFactoriesResolver;
 import org.opendaylight.controller.config.manager.impl.jmx.BaseJMXRegistrator;
 import org.opendaylight.controller.config.manager.impl.jmx.ConfigRegistryJMXRegistrator;
 import org.opendaylight.controller.config.manager.impl.jmx.InternalJMXRegistrator;
+import org.opendaylight.controller.config.manager.testingservices.scheduledthreadpool.TestingScheduledThreadPoolImpl;
+import org.opendaylight.controller.config.manager.testingservices.threadpool.TestingFixedThreadPool;
 import org.opendaylight.controller.config.spi.Module;
 import org.opendaylight.controller.config.util.ConfigRegistryJMXClient;
 import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
@@ -24,14 +31,20 @@ import javax.management.InstanceAlreadyExistsException;
 import javax.management.MBeanServer;
 import javax.management.ObjectName;
 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.util.Dictionary;
+import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import static org.junit.Assert.assertEquals;
 import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 
 /**
@@ -53,6 +66,10 @@ public abstract class AbstractConfigTest extends
     protected BundleContext mockedContext = mock(BundleContext.class);
     protected ServiceRegistration<?> mockedServiceRegistration;
 
+    protected  Map<Class, BundleContextServiceRegistrationHandler> getBundleContextServiceRegistrationHandlers() {
+        return Maps.newHashMap();
+    }
+
     // this method should be called in @Before
     protected void initConfigTransactionManagerImpl(
             ModuleFactoriesResolver resolver) {
@@ -61,17 +78,14 @@ public abstract class AbstractConfigTest extends
 
         configRegistryJMXRegistrator = new ConfigRegistryJMXRegistrator(
                 platformMBeanServer);
-        this.mockedServiceRegistration = mock(ServiceRegistration.class);
-        doNothing().when(mockedServiceRegistration).unregister();
-        doReturn(mockedServiceRegistration).when(mockedContext).registerService(
-                Matchers.any(String[].class), any(Closeable.class),
-                any(Dictionary.class));
+        initBundleContext();
 
         internalJmxRegistrator = new InternalJMXRegistrator(platformMBeanServer);
         baseJmxRegistrator = new BaseJMXRegistrator(internalJmxRegistrator);
 
         configRegistry = new ConfigRegistryImpl(resolver,
                 platformMBeanServer, baseJmxRegistrator);
+
         try {
             configRegistryJMXRegistrator.registerToJMX(configRegistry);
         } catch (InstanceAlreadyExistsException e) {
@@ -80,10 +94,41 @@ public abstract class AbstractConfigTest extends
         configRegistryClient = new ConfigRegistryJMXClient(platformMBeanServer);
     }
 
+    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;
+    }
+
     @After
     public final void cleanUpConfigTransactionManagerImpl() {
         configRegistryJMXRegistrator.close();
         configRegistry.close();
+        TestingFixedThreadPool.cleanUp();
+        TestingScheduledThreadPoolImpl.cleanUp();
     }
 
     /**
@@ -111,10 +156,10 @@ public abstract class AbstractConfigTest extends
 
     protected void assertStatus(CommitStatus status, int expectedNewInstances,
             int expectedRecreatedInstances, int expectedReusedInstances) {
-        assertEquals(expectedNewInstances, status.getNewInstances().size());
-        assertEquals(expectedRecreatedInstances, status.getRecreatedInstances()
+        assertEquals("New instances mismatch in " + status, expectedNewInstances, status.getNewInstances().size());
+        assertEquals("Recreated instances mismatch in " + status, expectedRecreatedInstances, status.getRecreatedInstances()
                 .size());
-        assertEquals(expectedReusedInstances, status.getReusedInstances()
+        assertEquals("Reused instances mismatch in " + status, expectedReusedInstances, status.getReusedInstances()
                 .size());
     }
 
@@ -150,4 +195,35 @@ public abstract class AbstractConfigTest extends
             Class<? extends Module> configBeanClass, String implementationName) {
         return new ClassBasedModuleFactory(implementationName, configBeanClass);
     }
+
+
+    public static interface BundleContextServiceRegistrationHandler {
+
+       void handleServiceRegistration(Object serviceInstance);
+
+    }
+
+    private class RegisterServiceAnswer implements Answer {
+        @Override
+        public Object answer(InvocationOnMock invocation) throws Throwable {
+            Object[] args = invocation.getArguments();
+
+            Preconditions.checkArgument(args.length == 3);
+
+            Preconditions.checkArgument(args[0] instanceof Class);
+            Class<?> serviceType = (Class<?>) args[0];
+            Object serviceInstance = args[1];
+
+            BundleContextServiceRegistrationHandler serviceRegistrationHandler = getBundleContextServiceRegistrationHandlers()
+                    .get(serviceType);
+
+            Preconditions.checkArgument(serviceType.isAssignableFrom(serviceInstance.getClass()));
+
+            if (serviceRegistrationHandler != null) {
+                serviceRegistrationHandler.handleServiceRegistration(serviceType.cast(serviceInstance));
+            }
+
+            return mockedServiceRegistration;
+        }
+    }
 }
diff --git a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/ServiceReferenceRegistryImplTest.java b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/ServiceReferenceRegistryImplTest.java
new file mode 100644 (file)
index 0000000..6d0b340
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * 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 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.factoriesresolver.HardcodedModuleFactoriesResolver;
+import org.opendaylight.controller.config.manager.impl.jmx.ServiceReferenceMXBean;
+import org.opendaylight.controller.config.manager.testingservices.parallelapsp.TestingParallelAPSPModuleFactory;
+import org.opendaylight.controller.config.manager.testingservices.parallelapsp.test.AbstractParallelAPSPTest;
+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.util.ConfigTransactionJMXClient;
+
+import javax.management.Attribute;
+import javax.management.AttributeNotFoundException;
+import javax.management.InstanceNotFoundException;
+import javax.management.JMX;
+import javax.management.MBeanException;
+import javax.management.ObjectName;
+import javax.management.ReflectionException;
+
+import java.util.Map;
+import java.util.Set;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.opendaylight.controller.config.api.jmx.ObjectNameUtil.withoutTransactionName;
+
+public class ServiceReferenceRegistryImplTest extends AbstractParallelAPSPTest {
+
+
+    @Before
+    public void setUp() {
+        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(
+                new TestingFixedThreadPoolModuleFactory(),
+                new TestingParallelAPSPModuleFactory(),
+                new TestingScheduledThreadPoolModuleFactory()));
+    }
+
+    @Override
+    protected String getThreadPoolImplementationName() {
+        return TestingFixedThreadPoolModuleFactory.NAME;
+    }
+
+    @Test
+    public void test() throws Exception {
+        ConfigTransactionJMXClient transaction1 = configRegistryClient.createTransaction();
+        // create fixed1
+        int fixedNrOfThreads = 20, scheduledNrOfThreads = 30;
+
+        ObjectName fixedTPTransactionON = transaction1.createModule(getThreadPoolImplementationName(), fixed1);
+        platformMBeanServer.setAttribute(fixedTPTransactionON, new Attribute("ThreadCount", fixedNrOfThreads));
+
+        ObjectName scheduledTPTransactionON = transaction1.createModule(
+                TestingScheduledThreadPoolModuleFactory.NAME, "scheduled1");
+        platformMBeanServer.setAttribute(scheduledTPTransactionON, new Attribute("ThreadCount",
+                scheduledNrOfThreads));
+
+        String refName = "ref";
+        ObjectName serviceReference = transaction1.saveServiceReference(TestingThreadPoolServiceInterface.QNAME, refName,
+                fixedTPTransactionON);
+        // 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);
+
+        // switch reference to scheduled
+        ConfigTransactionJMXClient transaction2 = configRegistryClient.createTransaction();
+        transaction2.saveServiceReference(TestingThreadPoolServiceInterface.QNAME, refName,
+                ObjectNameUtil.withTransactionName(scheduledTPTransactionON, transaction2.getTransactionName()));
+        transaction2.commit();
+        // check scheduled is used
+        checkApspThreadCount(scheduledNrOfThreads);
+        // check that dummy MXBean points to scheduled
+        assertEquals(withoutTransactionName(scheduledTPTransactionON), serviceReferenceMXBean.getCurrentImplementation());
+
+        // empty transaction
+        configRegistryClient.createTransaction().commit();
+
+        // get service mapping
+        Map<String,Map<String,ObjectName>> serviceMapping = configRegistryClient.getServiceMapping();
+        Map<String,Map<String,ObjectName>> expectedMapping = ImmutableMap.of(TestingThreadPoolServiceInterface.QNAME,
+                (Map<String, ObjectName>)ImmutableMap.of(refName, withoutTransactionName(scheduledTPTransactionON)));
+        assertEquals(expectedMapping, serviceMapping);
+
+        // destroy all
+        ConfigTransactionJMXClient transaction4 = configRegistryClient.createTransaction();
+        Set<ObjectName> objectNames = transaction4.lookupConfigBeans();
+        for(ObjectName on: objectNames) {
+            transaction4.destroyModule(on);
+        }
+        transaction4.commit();
+
+        serviceMapping = configRegistryClient.getServiceMapping();
+        assertTrue(serviceMapping.isEmpty());
+    }
+
+    private void checkApspThreadCount(int fixedNrOfThreads) throws MBeanException, AttributeNotFoundException,
+            InstanceNotFoundException, ReflectionException {
+        ObjectName apspON = ObjectNameUtil.createReadOnlyModuleON(TestingParallelAPSPModuleFactory.NAME, apsp1);
+        assertEquals(fixedNrOfThreads, platformMBeanServer.getAttribute(apspON, "MaxNumberOfThreads"));
+    }
+}
index 65b0105..31e70bd 100644 (file)
@@ -20,6 +20,7 @@ import org.junit.Before;
 import org.junit.Test;
 import org.opendaylight.controller.config.api.JmxAttribute;
 import org.opendaylight.controller.config.api.ModuleIdentifier;
+import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry;
 import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
 import org.opendaylight.controller.config.manager.impl.ModuleInternalTransactionalInfo;
 import org.opendaylight.controller.config.manager.impl.TransactionStatus;
@@ -40,7 +41,8 @@ public class DependencyResolverManagerTest {
     @Before
     public void setUp() {
         transactionStatus = mock(TransactionStatus.class);
-        tested = new DependencyResolverManager("txName", transactionStatus);
+        ServiceReferenceReadableRegistry mockedRegistry = mock(ServiceReferenceReadableRegistry.class);
+        tested = new DependencyResolverManager("txName", transactionStatus, mockedRegistry);
         doNothing().when(transactionStatus).checkCommitStarted();
         doNothing().when(transactionStatus).checkNotCommitted();
     }
index 0338039..fe32289 100644 (file)
@@ -7,16 +7,19 @@
  */
 package org.opendaylight.controller.config.manager.impl.util;
 
-import java.util.Set;
-
-import javax.management.ObjectName;
-
+import com.google.common.base.Throwables;
+import com.google.common.collect.Sets;
 import org.junit.After;
 import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
 import org.opendaylight.controller.config.manager.impl.AbstractLockedPlatformMBeanServerTest;
 
-import com.google.common.base.Throwables;
-import com.google.common.collect.Sets;
+import javax.management.ObjectName;
+import java.util.Set;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 
 public class ObjectNameUtilTest extends AbstractLockedPlatformMBeanServerTest {
     private Set<ObjectName> unregisterONs;
@@ -37,7 +40,26 @@ public class ObjectNameUtilTest extends AbstractLockedPlatformMBeanServerTest {
             }
         }
         if (lastException != null) {
-            Throwables.propagate(lastException);
+            throw Throwables.propagate(lastException);
         }
     }
+
+    @Test
+    public void testQuotation() throws Exception {
+        String serviceQName = "(namespace?revision=r)qname";
+        String refName = "refName";
+        String transaction = "transaction";
+        ObjectName serviceReferenceON = ObjectNameUtil.createTransactionServiceON(transaction, serviceQName, refName);
+        assertFalse(serviceReferenceON.isPattern());
+        assertEquals(serviceQName, ObjectNameUtil.getServiceQName(serviceReferenceON));
+        assertEquals(refName, ObjectNameUtil.getReferenceName(serviceReferenceON));
+        assertEquals(transaction, ObjectNameUtil.getTransactionName(serviceReferenceON));
+
+        serviceReferenceON = ObjectNameUtil.createReadOnlyServiceON(serviceQName, refName);
+        assertFalse(serviceReferenceON.isPattern());
+        assertEquals(serviceQName, ObjectNameUtil.getServiceQName(serviceReferenceON));
+        assertEquals(refName, ObjectNameUtil.getReferenceName(serviceReferenceON));
+        assertEquals(null, ObjectNameUtil.getTransactionName(serviceReferenceON));
+
+    }
 }
index 3c55f4d..f4ba5ef 100644 (file)
@@ -114,8 +114,7 @@ public class TestingParallelAPSPModule implements Module,
 
             if (oldInstance != null) {
                 // changing thread pool is not supported
-                boolean reuse = threadPoolInstance.equals(oldInstance
-                        .getThreadPool());
+                boolean reuse = threadPoolInstance == oldInstance.getThreadPool();
                 if (reuse) {
                     logger.debug("Reusing old instance");
                     instance = oldInstance;
index 3d9d524..f979a45 100644 (file)
@@ -16,11 +16,11 @@ import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
 import javax.management.InstanceAlreadyExistsException;
 import javax.management.ObjectName;
 
-abstract class AbstractParallelAPSPTest extends AbstractConfigTest {
+public abstract class AbstractParallelAPSPTest extends AbstractConfigTest {
     protected final String fixed1 = "fixed1";
     protected final String apsp1 = "apsp-parallel";
 
-    abstract String getThreadPoolImplementationName();
+    protected abstract String getThreadPoolImplementationName();
 
     protected ObjectName createParallelAPSP(
             ConfigTransactionJMXClient transaction, ObjectName threadPoolON)
@@ -36,6 +36,7 @@ abstract class AbstractParallelAPSPTest extends AbstractConfigTest {
 
     protected ObjectName createFixed1(ConfigTransactionJMXClient transaction,
             int numberOfThreads) throws InstanceAlreadyExistsException {
+
         ObjectName name = transaction.createModule(
                 getThreadPoolImplementationName(), fixed1);
 
index 77d1f8b..2b9760c 100644 (file)
@@ -36,7 +36,7 @@ public class TestingScheduledThreadPoolModule implements Module,
     @Nullable
     private final TestingScheduledThreadPoolImpl oldInstance;
 
-    private final int threadCount = 10;
+    private int threadCount = 10;
     private TestingScheduledThreadPoolImpl instance;
     private RootRuntimeBeanRegistrator runtimeBeanRegistrator;
     private boolean recreate;
@@ -68,6 +68,11 @@ public class TestingScheduledThreadPoolModule implements Module,
         return threadCount;
     }
 
+    @Override
+    public void setThreadCount(int threadCount) {
+        this.threadCount = threadCount;
+    }
+
     @Override
     public Closeable getInstance() {
         assertNotNull(runtimeBeanRegistrator);
index 91a4cff..0a886e5 100644 (file)
@@ -11,8 +11,9 @@ import org.opendaylight.controller.config.api.annotations.AbstractServiceInterfa
 import org.opendaylight.controller.config.api.annotations.ServiceInterfaceAnnotation;
 import org.opendaylight.controller.config.manager.testingservices.threadpool.TestingThreadPoolIfc;
 
-@ServiceInterfaceAnnotation(value = "testing-threadpool", osgiRegistrationType = TestingThreadPoolIfc.class,
-    namespace = "ns", revision = "foo", localName = "bar")
+@ServiceInterfaceAnnotation(value = TestingThreadPoolServiceInterface.QNAME, osgiRegistrationType = TestingThreadPoolIfc.class,
+    namespace = "ns", revision = "foo", localName = "testing-threadpool")
 public interface TestingThreadPoolServiceInterface extends
         AbstractServiceInterface {
+    public static final String QNAME = "(ns?revision=foo)testing-threadpool";
 }
index 8badb75..549ff9f 100644 (file)
@@ -148,8 +148,8 @@ public class ConfigRegistryJMXClient implements ConfigRegistryClient {
     }
 
     @Override
-    public ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceName, String refName) {
-        return configRegistryMXBeanProxy.lookupConfigBeanByServiceInterfaceName(serviceInterfaceName, refName);
+    public ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceQName, String refName) {
+        return configRegistryMXBeanProxy.lookupConfigBeanByServiceInterfaceName(serviceInterfaceQName, refName);
     }
 
     @Override
@@ -158,8 +158,8 @@ public class ConfigRegistryJMXClient implements ConfigRegistryClient {
     }
 
     @Override
-    public Map<String, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceName) {
-        return configRegistryMXBeanProxy.lookupServiceReferencesByServiceInterfaceName(serviceInterfaceName);
+    public Map<String, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceQName) {
+        return configRegistryMXBeanProxy.lookupServiceReferencesByServiceInterfaceName(serviceInterfaceQName);
     }
 
     @Override
@@ -201,4 +201,15 @@ public class ConfigRegistryJMXClient implements ConfigRegistryClient {
     public Set<String> getAvailableModuleFactoryQNames() {
         return configRegistryMXBeanProxy.getAvailableModuleFactoryQNames();
     }
+
+    @Override
+    public ObjectName getServiceReference(String serviceInterfaceQName, String refName) throws InstanceNotFoundException {
+        return configRegistryMXBeanProxy.getServiceReference(serviceInterfaceQName, refName);
+    }
+
+    @Override
+    public void checkServiceReferenceExists(ObjectName objectName) throws InstanceNotFoundException {
+        configRegistryMXBeanProxy.checkServiceReferenceExists(objectName);
+    }
+
 }
index 0db1e5b..e683d91 100644 (file)
@@ -164,13 +164,13 @@ public class ConfigTransactionJMXClient implements ConfigTransactionClient {
     }
 
     @Override
-    public void saveServiceReference(String serviceInterfaceName, String refName, ObjectName objectName) throws InstanceNotFoundException {
-        configTransactionControllerMXBeanProxy.saveServiceReference(serviceInterfaceName,refName,objectName);
+    public ObjectName saveServiceReference(String serviceInterfaceName, String refName, ObjectName moduleON) throws InstanceNotFoundException {
+        return configTransactionControllerMXBeanProxy.saveServiceReference(serviceInterfaceName,refName, moduleON);
     }
 
     @Override
-    public boolean removeServiceReference(String serviceInterfaceName, String refName) {
-        return configTransactionControllerMXBeanProxy.removeServiceReference(serviceInterfaceName, refName);
+    public void removeServiceReference(String serviceInterfaceName, String refName) throws InstanceNotFoundException{
+        configTransactionControllerMXBeanProxy.removeServiceReference(serviceInterfaceName, refName);
     }
 
     @Override
@@ -179,8 +179,8 @@ public class ConfigTransactionJMXClient implements ConfigTransactionClient {
     }
 
     @Override
-    public ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceName, String refName) {
-        return configTransactionControllerMXBeanProxy.lookupConfigBeanByServiceInterfaceName(serviceInterfaceName, refName);
+    public ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceQName, String refName) {
+        return configTransactionControllerMXBeanProxy.lookupConfigBeanByServiceInterfaceName(serviceInterfaceQName, refName);
     }
 
     @Override
@@ -189,8 +189,8 @@ public class ConfigTransactionJMXClient implements ConfigTransactionClient {
     }
 
     @Override
-    public Map<String, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceName) {
-        return configTransactionControllerMXBeanProxy.lookupServiceReferencesByServiceInterfaceName(serviceInterfaceName);
+    public Map<String, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceQName) {
+        return configTransactionControllerMXBeanProxy.lookupServiceReferencesByServiceInterfaceName(serviceInterfaceQName);
     }
 
     @Override
@@ -208,6 +208,16 @@ public class ConfigTransactionJMXClient implements ConfigTransactionClient {
         return configTransactionControllerMXBeanProxy.removeServiceReferences(objectName);
     }
 
+    @Override
+    public ObjectName getServiceReference(String serviceInterfaceQName, String refName) throws InstanceNotFoundException {
+        return configTransactionControllerMXBeanProxy.getServiceReference(serviceInterfaceQName, refName);
+    }
+
+    @Override
+    public void checkServiceReferenceExists(ObjectName objectName) throws InstanceNotFoundException {
+        configTransactionControllerMXBeanProxy.checkServiceReferenceExists(objectName);
+    }
+
     @Override
     public void validateBean(ObjectName configBeanON)
             throws ValidationException {
index 6534171..e0d4c85 100644 (file)
@@ -150,7 +150,7 @@ public class TestingConfigRegistry implements ConfigRegistryMXBean {
     }
 
     @Override
-    public ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceName, String refName) {
+    public ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceQName, String refName) {
         throw new UnsupportedOperationException();
     }
 
@@ -160,7 +160,7 @@ public class TestingConfigRegistry implements ConfigRegistryMXBean {
     }
 
     @Override
-    public Map<String, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceName) {
+    public Map<String, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceQName) {
         throw new UnsupportedOperationException();
     }
 
@@ -178,4 +178,14 @@ public class TestingConfigRegistry implements ConfigRegistryMXBean {
     public Set<String> getAvailableModuleFactoryQNames() {
         throw new UnsupportedOperationException();
     }
+
+    @Override
+    public ObjectName getServiceReference(String serviceInterfaceQName, String refName) throws InstanceNotFoundException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void checkServiceReferenceExists(ObjectName objectName) throws InstanceNotFoundException {
+        throw new UnsupportedOperationException();
+    }
 }
index 44eb73a..4d16f51 100644 (file)
@@ -117,12 +117,12 @@ public class TestingConfigTransactionController implements
     }
 
     @Override
-    public void saveServiceReference(String serviceInterfaceName, String refName, ObjectName objectName) throws InstanceNotFoundException {
+    public ObjectName saveServiceReference(String serviceInterfaceName, String refName, ObjectName moduleON) throws InstanceNotFoundException {
         throw new UnsupportedOperationException();
     }
 
     @Override
-    public boolean removeServiceReference(String serviceInterfaceName, String refName) {
+    public void removeServiceReference(String serviceInterfaceName, String refName) {
         throw new UnsupportedOperationException();
     }
 
@@ -132,7 +132,7 @@ public class TestingConfigTransactionController implements
     }
 
     @Override
-    public ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceName, String refName) {
+    public ObjectName lookupConfigBeanByServiceInterfaceName(String serviceInterfaceQName, String refName) {
         throw new UnsupportedOperationException();
     }
 
@@ -142,7 +142,7 @@ public class TestingConfigTransactionController implements
     }
 
     @Override
-    public Map<String, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceName) {
+    public Map<String, ObjectName> lookupServiceReferencesByServiceInterfaceName(String serviceInterfaceQName) {
         throw new UnsupportedOperationException();
     }
 
@@ -165,4 +165,14 @@ public class TestingConfigTransactionController implements
     public Set<String> getAvailableModuleFactoryQNames() {
         throw new UnsupportedOperationException();
     }
+
+    @Override
+    public ObjectName getServiceReference(String serviceInterfaceQName, String refName) throws InstanceNotFoundException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void checkServiceReferenceExists(ObjectName objectName) throws InstanceNotFoundException {
+        throw new UnsupportedOperationException();
+    }
 }
index 28e0256..49a20bd 100644 (file)
@@ -26,6 +26,7 @@ import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIf
 import org.opendaylight.controller.config.yangjmxgenerator.attribute.Dependency;
 import org.opendaylight.controller.config.yangjmxgenerator.attribute.JavaAttribute;
 import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListAttribute;
+import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListDependenciesAttribute;
 import org.opendaylight.controller.config.yangjmxgenerator.attribute.TOAttribute;
 import org.opendaylight.controller.config.yangjmxgenerator.attribute.TypedAttribute;
 import org.opendaylight.controller.config.yangjmxgenerator.attribute.VoidAttribute;
@@ -623,6 +624,7 @@ public class TemplateFactory {
                 }
 
                 boolean isDependency = false;
+                boolean isListOfDependencies = false;
                 Dependency dependency = null;
                 Annotation overrideAnnotation = new Annotation("Override",
                         Collections.<Parameter> emptyList());
@@ -635,12 +637,15 @@ public class TemplateFactory {
                             .getDependency();
                     annotations.add(Annotation
                             .createRequireIfcAnnotation(dependency.getSie()));
+                    if (attributeIfc instanceof ListDependenciesAttribute) {
+                        isListOfDependencies = true;
+                    }
                 }
 
                 String varName = BindingGeneratorUtil
                         .parseToValidParamName(attrEntry.getKey());
                 moduleFields.add(new ModuleField(type, varName, attributeIfc
-                        .getUpperCaseCammelCase(), nullableDefaultWrapped, isDependency, dependency));
+                        .getUpperCaseCammelCase(), nullableDefaultWrapped, isDependency, dependency, isListOfDependencies));
 
                 String getterName = "get"
                         + attributeIfc.getUpperCaseCammelCase();
@@ -657,10 +662,16 @@ public class TemplateFactory {
                             .createDescriptionAnnotation(attributeIfc.getNullableDescription()));
                 }
 
+                String setterBody = "this." + varName + " = " + varName + ";";
+                if (isListOfDependencies) {
+                    String nullCheck = String.format("if (%s == null) throw new IllegalArgumentException(\"Null not supported\");%n",
+                            varName);
+                    setterBody = nullCheck + setterBody;
+                }
                 MethodDefinition setter = new MethodDefinition("void",
                         setterName,
                         Lists.newArrayList(new Field(type, varName)),
-                        annotations, "this." + varName + " = " + varName + ";");
+                        annotations, setterBody);
                 setter.setJavadoc(attributeIfc.getNullableDescription());
 
                 methods.add(getter);
index 5624e16..aff7af2 100644 (file)
@@ -17,12 +17,12 @@ import java.util.List;
 public class ModuleField extends Field {
 
     private final String nullableDefault, attributeName;
-    private final boolean dependent;
+    private final boolean dependent, isListOfDependencies;
     private final Dependency dependency;
 
-    public ModuleField(List<String> modifiers, String type, String name,
+    private ModuleField(List<String> modifiers, String type, String name,
             String attributeName, String nullableDefault, boolean isDependency,
-            Dependency dependency) {
+            Dependency dependency, boolean isListOfDependencies) {
         super(modifiers, type, name);
         this.dependent = isDependency;
         this.dependency = dependency;
@@ -32,12 +32,13 @@ public class ModuleField extends Field {
             nullableDefault = "new " + ArrayList.class.getName() + generics + "()";
         }
         this.nullableDefault = nullableDefault;
+        this.isListOfDependencies = isListOfDependencies;
     }
 
     public ModuleField(String type, String name, String attributeName,
-            String nullableDefault, boolean isDependency, Dependency dependency) {
+            String nullableDefault, boolean isDependency, Dependency dependency, boolean isListOfDependencies) {
         this(Collections.<String> emptyList(), type, name, attributeName,
-                nullableDefault, isDependency, dependency);
+                nullableDefault, isDependency, dependency, isListOfDependencies);
     }
 
     public Dependency getDependency() {
@@ -52,6 +53,10 @@ public class ModuleField extends Field {
         return dependent;
     }
 
+    public boolean isListOfDependencies() {
+        return isListOfDependencies;
+    }
+
     public String getAttributeName() {
         return attributeName;
     }
index f7197d1..7192ac6 100644 (file)
@@ -149,13 +149,19 @@ package ${packageName};
             throw new IllegalArgumentException("Parameter 'other' is null");
         }
         <#list moduleFields as field>
-        <#if field.dependent==true>
-        if (${field.name}Dependency == null) {
-            if (other.${field.name}Dependency != null)
-                return false;
-        } else if (!${field.name}Dependency.equals(other.${field.name}Dependency)) {
+        <#if field.dependent==true && field.listOfDependencies == false>
+        if (${field.name}Dependency != other.${field.name}Dependency) { // reference to dependency must be same
+            return false;
+        }
+        <#elseif field.listOfDependencies>
+        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.name} == null) {
             if (other.${field.name} != null) {
index b49b17e..e33f1cd 100644 (file)
@@ -42,7 +42,7 @@ public class JMXGeneratorFileNamesValidationTest extends JMXGeneratorTest {
         } catch (RuntimeException e) {
             final Throwable cause = e.getCause();
             assertNotNull(cause);
-            assertTrue(cause instanceof IllegalStateException);
+            assertTrue(cause.toString() + " is unexpected", cause instanceof IllegalStateException);
             assertThat(cause.getMessage(),
                     containsString("Name conflict in generated files"));
             assertThat(cause.getMessage(), containsString("DtoA.java"));
index 211da6b..2be6c81 100644 (file)
@@ -9,7 +9,6 @@ package org.opendaylight.controller.config.yang.store.impl;
 
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
 import org.apache.commons.io.IOUtils;
 import org.opendaylight.controller.config.yang.store.api.YangStoreException;
 import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
@@ -22,13 +21,10 @@ import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
 
-import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
-import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 
@@ -37,26 +33,11 @@ public class MbeParser {
     public YangStoreSnapshotImpl parseYangFiles(
             Collection<? extends InputStream> allInput)
             throws YangStoreException {
-        YangParserImpl parser = new YangParserImpl();
+        YangParserImpl parser = YangParserWrapper.getYangParserInstance();
 
-        List<InputStream> bufferedInputStreams = new ArrayList<>();
-        for (InputStream is : allInput) {
-            String content;
-            try {
-                content = IOUtils.toString(is);
-            } catch (IOException e) {
-                throw new YangStoreException("Can not get yang as String from "
-                        + is, e);
-            }
-            InputStream buf = new ByteArrayInputStream(content.getBytes());
-            bufferedInputStreams.add(buf);
-        }
-
-        Map<InputStream, Module> allYangModules = parser
-                .parseYangModelsFromStreamsMapped(bufferedInputStreams);
+        Map<InputStream, Module> allYangModules = YangParserWrapper.parseYangFiles(parser, allInput);
 
-        SchemaContext resolveSchemaContext = parser.resolveSchemaContext(Sets
-                .newHashSet(allYangModules.values()));
+        SchemaContext resolveSchemaContext = YangParserWrapper.getSchemaContextFromModules(parser, allYangModules);
 
         // JMX generator
 
@@ -115,7 +96,7 @@ public class MbeParser {
 
     public Map<Module, String> parseYangFilesToString(
             Collection<? extends InputStream> allYangs) {
-        YangParserImpl parser = new YangParserImpl();
+        YangParserImpl parser = YangParserWrapper.getYangParserInstance();
 
         Map<InputStream, Module> allYangModules = parser
                 .parseYangModelsFromStreamsMapped(Lists.newArrayList(allYangs));
diff --git a/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/YangParserWrapper.java b/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/YangParserWrapper.java
new file mode 100644 (file)
index 0000000..7c42818
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * 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.store.impl;
+
+import com.google.common.collect.Sets;
+import org.apache.commons.io.IOUtils;
+import org.opendaylight.controller.config.yang.store.api.YangStoreException;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.parser.api.YangModelParser;
+import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+public class YangParserWrapper {
+
+    /**
+     * throw IllegalStateException if it is unable to parse yang files
+     */
+    public static SchemaContext parseYangFiles(Collection<? extends InputStream> yangFilesAsInputStreams) {
+        YangParserImpl parser = getYangParserInstance();
+        Map<InputStream, Module> mappedYangModules = null;
+        try {
+            mappedYangModules = parseYangFiles(parser, yangFilesAsInputStreams);
+        } catch (YangStoreException e) {
+            throw new IllegalStateException("Unable to parse yang files", e);
+        }
+        return getSchemaContextFromModules(parser, mappedYangModules);
+    }
+
+    static YangParserImpl getYangParserInstance() {
+        return new YangParserImpl();
+    }
+
+    static SchemaContext getSchemaContextFromModules(YangModelParser parser, Map<InputStream, Module> allYangModules) {
+        return parser.resolveSchemaContext(Sets
+                .newHashSet(allYangModules.values()));
+    }
+
+    static Map<InputStream, Module> parseYangFiles(YangModelParser parser, Collection<? extends InputStream> allInput) throws YangStoreException {
+        List<InputStream> bufferedInputStreams = new ArrayList<>();
+        for (InputStream is : allInput) {
+            String content;
+            try {
+                content = IOUtils.toString(is);
+            } catch (IOException e) {
+                throw new YangStoreException("Can not get yang as String from "
+                        + is, e);
+            }
+            InputStream buf = new ByteArrayInputStream(content.getBytes());
+            bufferedInputStreams.add(buf);
+        }
+
+        return parser
+                .parseYangModelsFromStreamsMapped(bufferedInputStreams);
+    }
+}
index 149348d..b1f7013 100644 (file)
             <artifactId>slf4j-api</artifactId>
         </dependency>
         <dependency>
-         <groupId>org.opendaylight.yangtools.model</groupId>
-         <artifactId>ietf-inet-types</artifactId>
+            <groupId>org.opendaylight.yangtools.model</groupId>
+            <artifactId>ietf-inet-types</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.bgpcep</groupId>
+            <artifactId>mockito-configuration</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>config-manager</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>config-manager</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>config-util</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
         </dependency>
     </dependencies>
 
diff --git a/opendaylight/config/yang-test/src/test/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleTest.java b/opendaylight/config/yang-test/src/test/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleTest.java
new file mode 100644 (file)
index 0000000..50e1d4b
--- /dev/null
@@ -0,0 +1,89 @@
+package org.opendaylight.controller.config.yang.test.impl;
+
+import com.google.common.collect.Lists;
+import junit.framework.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.controller.config.api.ConflictingVersionException;
+import org.opendaylight.controller.config.api.ValidationException;
+import org.opendaylight.controller.config.api.jmx.CommitStatus;
+import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
+import org.opendaylight.controller.config.manager.impl.AbstractConfigTest;
+import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
+import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
+
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.ObjectName;
+import java.util.ArrayList;
+import java.util.List;
+
+public class NetconfTestImplModuleTest  extends AbstractConfigTest {
+
+    public static final String TESTING_DEP_PREFIX = "testing-dep";
+    private NetconfTestImplModuleFactory factory;
+    private final String instanceName = "n1";
+
+    @Before
+    public void setUp() {
+
+        factory = new NetconfTestImplModuleFactory();
+        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory,
+                new DepTestImplModuleFactory()));
+    }
+
+    @Test
+    public void testDependencyList() throws InstanceAlreadyExistsException, ValidationException,
+            ConflictingVersionException {
+        ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
+
+        ObjectName on = createInstance(transaction, instanceName, 4);
+        transaction.validateConfig();
+        CommitStatus status = transaction.commit();
+
+        assertBeanCount(1, factory.getImplementationName());
+        assertBeanCount(4 + 1, DepTestImplModuleFactory.NAME);
+        assertStatus(status, 1 + 4 + 1, 0, 0);
+
+        transaction = configRegistryClient.createTransaction();
+
+        NetconfTestImplModuleMXBean proxy = transaction.newMXBeanProxy(ObjectNameUtil.withoutTransactionName(on),
+                NetconfTestImplModuleMXBean.class);
+        proxy.getComplexList();
+        List<ObjectName> testingDeps = proxy.getTestingDeps();
+        ObjectName testingDep = proxy.getTestingDep();
+
+        Assert.assertEquals(TESTING_DEP_PREFIX, ObjectNameUtil.getInstanceName(testingDep));
+        assertTestingDeps(testingDeps, 4);
+
+        transaction.abortConfig();
+    }
+
+    private void assertTestingDeps(List<ObjectName> testingDeps, int i) {
+        Assert.assertEquals(i, testingDeps.size());
+
+        int c = 1;
+        for (ObjectName testingDep : testingDeps) {
+            Assert.assertEquals(TESTING_DEP_PREFIX + Integer.toString(c++), ObjectNameUtil.getInstanceName(testingDep));
+        }
+    }
+
+
+    private ObjectName createInstance(ConfigTransactionJMXClient transaction, String instanceName, int depsCount)
+            throws InstanceAlreadyExistsException {
+        ObjectName nameCreated = transaction.createModule(factory.getImplementationName(), instanceName);
+        NetconfTestImplModuleMXBean mxBean = transaction.newMXBeanProxy(nameCreated, NetconfTestImplModuleMXBean.class);
+
+        ObjectName dep = transaction.createModule(DepTestImplModuleFactory.NAME, TESTING_DEP_PREFIX);
+        mxBean.setTestingDep(dep);
+
+        ArrayList<ObjectName> testingDeps = Lists.newArrayList();
+        for (int i = 0; i < depsCount; i++) {
+            dep = transaction.createModule(DepTestImplModuleFactory.NAME, TESTING_DEP_PREFIX + Integer.toString(i + 1));
+            testingDeps.add(dep);
+        }
+        mxBean.setTestingDeps(testingDeps);
+
+        return nameCreated;
+    }
+
+}
index e519a04..b0f7ad8 100644 (file)
           <artifactId>ietf-netconf-monitoring</artifactId>
           <version>${netconf.version}</version>
         </dependency>
+        <dependency>
+          <groupId>${project.groupId}</groupId>
+          <artifactId>ietf-netconf-monitoring-extension</artifactId>
+          <version>${netconf.version}</version>
+        </dependency>
         <dependency>
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>config-persister-impl</artifactId>
         <dependency>
               <groupId>org.opendaylight.controller</groupId>
               <artifactId>
-                  zeromq-routingtable.implementation
+                  remoterpc-routingtable.implementation
               </artifactId>
               <version>0.4.1-SNAPSHOT</version>
         </dependency>
index 2815422..84d1c91 100644 (file)
@@ -61,7 +61,7 @@
   <logger name="org.opendaylight.controller.sal.implementation" level="INFO"/>
   <logger name="org.opendaylight.controller.sal.implementation.internal.Inventory" level="INFO"/>
   <logger name="org.opendaylight.controller.sal.implementation.internal.Topology" level="INFO"/>
-     <!-- zeromq router and zeromq routing table -->
+     <!-- remoterpc router and remoterpc routing table -->
   <logger name="org.opendaylight.controller.sal.connector.remoterpc" level="INFO" />
   <!-- Functional Modules -->
   <logger name="org.opendaylight.controller.arphandler" level="INFO"/>
index 45fb11a..3d6a029 100644 (file)
@@ -2930,8 +2930,16 @@ public class ForwardingRulesManager implements
         }
         if (target != null) {
             // Update Configuration database
-            target.toggleInstallation();
-            target.setStatus(StatusCode.SUCCESS.toString());
+            if (target.getHardTimeout() != null || target.getIdleTimeout() != null) {
+                /*
+                 * No need for checking if actual values: these strings were
+                 * validated at configuration creation. Also, after a switch
+                 * down scenario, no use to reinstall a timed flow. Mark it as
+                 * "do not install". User can manually toggle it.
+                 */
+                target.toggleInstallation();
+            }
+            target.setStatus(StatusCode.GONE.toString());
             staticFlows.put(key, target);
         }
 
index b460edf..95acbcd 100644 (file)
@@ -8,7 +8,6 @@ import static org.opendaylight.controller.sal.compatibility.NodeMapping.*
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey
 import org.apache.felix.dm.Component
 import java.util.Arrays
-import org.opendaylight.yangtools.yang.binding.NotificationListener
 import java.util.Dictionary
 import java.util.Hashtable
 import org.opendaylight.controller.sal.utils.GlobalConstants
@@ -30,6 +29,9 @@ import org.opendaylight.controller.sal.inventory.IPluginOutInventoryService
 import org.opendaylight.controller.sal.discovery.IDiscoveryService
 import org.opendaylight.controller.sal.topology.IPluginOutTopologyService
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.FlowTopologyDiscoveryService
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.OpendaylightFlowTableStatisticsService
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsService
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService
 
 class ComponentActivator extends ComponentActivatorAbstractBase implements BindingAwareConsumer {
 
@@ -44,9 +46,16 @@ class ComponentActivator extends ComponentActivatorAbstractBase implements Bindi
     @Property
     DataPacketAdapter dataPacket = new DataPacketAdapter;
 
+    @Property
+    org.opendaylight.controller.sal.utils.INodeFactory nodeFactory = new MDSalNodeFactory
+
+    @Property
+    org.opendaylight.controller.sal.utils.INodeConnectorFactory nodeConnectorFactory = new MDSalNodeConnectorFactory
+
+
     override protected init() {
-        Node.NodeIDType.registerIDType(MD_SAL_TYPE, NodeKey);
-        NodeConnector.NodeConnectorIDType.registerIDType(MD_SAL_TYPE, NodeConnectorKey, MD_SAL_TYPE);
+        Node.NodeIDType.registerIDType(MD_SAL_TYPE, String);
+        NodeConnector.NodeConnectorIDType.registerIDType(MD_SAL_TYPE, String, MD_SAL_TYPE);
     }
 
     override start(BundleContext context) {
@@ -71,25 +80,38 @@ class ComponentActivator extends ComponentActivatorAbstractBase implements Bindi
         // Inventory Service
         inventory.dataService = session.getSALService(DataBrokerService);
         inventory.flowStatisticsService = session.getRpcService(OpendaylightFlowStatisticsService);
+        inventory.flowTableStatisticsService = session.getRpcService(OpendaylightFlowTableStatisticsService);
+        inventory.nodeConnectorStatisticsService = session.getRpcService(OpendaylightPortStatisticsService);
         inventory.topologyDiscovery = session.getRpcService(FlowTopologyDiscoveryService);
+               inventory.dataProviderService = session.getSALService(DataProviderService)
 
         subscribe.registerNotificationListener(dataPacket)
 
     }
 
     override protected getGlobalImplementations() {
-        return Arrays.asList(this, flow, inventory, dataPacket)
+        return Arrays.asList(this, flow, inventory, dataPacket, nodeFactory, nodeConnectorFactory)
     }
 
     override protected configureGlobalInstance(Component c, Object imp) {
         configure(imp, c);
     }
 
+    private def dispatch configure(MDSalNodeFactory imp, Component it) {
+        setInterface(org.opendaylight.controller.sal.utils.INodeFactory.name, properties);
+    }
+
+    private def dispatch configure(MDSalNodeConnectorFactory imp, Component it) {
+        setInterface(org.opendaylight.controller.sal.utils.INodeConnectorFactory.name, properties);
+    }
+
     private def dispatch configure(ComponentActivator imp, Component it) {
         add(
             createServiceDependency().setService(BindingAwareBroker) //
             .setCallbacks("setBroker", "setBroker") //
             .setRequired(true))
+
+
     }
 
     private def dispatch configure(DataPacketAdapter imp, Component it) {
@@ -114,7 +136,7 @@ class ComponentActivator extends ComponentActivatorAbstractBase implements Bindi
         add(
             createServiceDependency() //
             .setService(IPluginOutReadService) //
-            .setCallbacks("setReadPublisher", "setReadPublisher") //
+            .setCallbacks("setReadPublisher", "unsetReadPublisher") //
             .setRequired(false))
         add(
             createServiceDependency() //
@@ -137,6 +159,7 @@ class ComponentActivator extends ComponentActivatorAbstractBase implements Bindi
     private def Dictionary<String, Object> properties() {
         val props = new Hashtable<String, Object>();
         props.put(GlobalConstants.PROTOCOLPLUGINTYPE.toString, MD_SAL_TYPE)
+        props.put("protocolName", MD_SAL_TYPE);
         return props;
     }
 }
index ce6af64..f1c19b1 100644 (file)
@@ -15,8 +15,9 @@ class DataPacketAdapter implements PacketProcessingListener {
         dataPacketPublisher.receiveDataPacket(inPacket);
     }
 
-    public static def RawPacket toRawPacket(PacketReceived received) {
+    public static def RawPacket toRawPacket(PacketReceived received) {        
         val ret = new RawPacket(received.payload);
+        ret.setIncomingNodeConnector(NodeMapping.toADNodeConnector(received.ingress))
         return ret;
     }
 
index ad6009c..4e6e49e 100644 (file)
@@ -1,5 +1,9 @@
 package org.opendaylight.controller.sal.compatibility;
 
+import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.CRUDP;
+import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.ETHERNET_ARP;
+import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.TCP;
+import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.UDP;
 import static org.opendaylight.controller.sal.match.MatchType.DL_DST;
 import static org.opendaylight.controller.sal.match.MatchType.DL_SRC;
 import static org.opendaylight.controller.sal.match.MatchType.DL_TYPE;
@@ -8,11 +12,6 @@ import java.net.Inet4Address;
 import java.net.Inet6Address;
 import java.net.InetAddress;
 
-
-import org.opendaylight.controller.sal.core.NodeConnector;
-
-
-
 import org.opendaylight.controller.sal.match.Match;
 import org.opendaylight.controller.sal.match.MatchField;
 import org.opendaylight.controller.sal.match.MatchType;
@@ -22,14 +21,11 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Prefix;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetNodeConnectorStatisticsInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetNodeConnectorStatisticsInputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.Address;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv4Builder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv6Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanPcp;
@@ -53,9 +49,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatchBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.UdpMatchBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.vlan.match.fields.VlanIdBuilder;
+
 import com.google.common.net.InetAddresses;
-import static org.opendaylight.controller.sal.compatibility.NodeMapping.*;
-import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.*;
 
 public class FromSalConversionsUtils {
 
@@ -63,19 +58,7 @@ public class FromSalConversionsUtils {
 
     }
 
-    public static GetNodeConnectorStatisticsInput nodeConnectorStatistics(
-            NodeConnector connector) {
-        GetNodeConnectorStatisticsInputBuilder target = new GetNodeConnectorStatisticsInputBuilder();
-
-        NodeRef nodeRef = toNodeRef(connector.getNode());
-        target.setNode(nodeRef);
-
-        NodeConnectorRef nodeConnectorRef = toNodeConnectorRef(connector);
-        target.setNodeConnector(nodeConnectorRef);
-
-        return target.build();
-    }
-
+    @SuppressWarnings("unused")
     private static Address addressFromAction(InetAddress inetAddress) {
         String strInetAddresss = InetAddresses.toAddrString(inetAddress);
         if (inetAddress instanceof Inet4Address) {
@@ -196,7 +179,7 @@ public class FromSalConversionsUtils {
         MatchField vlan = sourceMatch.getField(MatchType.DL_VLAN);
         if (vlan != null && vlan.getValue() != null) {
             VlanIdBuilder vlanIDBuilder = new VlanIdBuilder();
-            vlanIDBuilder.setVlanId(new VlanId((int) (NetUtils
+            vlanIDBuilder.setVlanId(new VlanId((NetUtils
                     .getUnsignedShort((short) vlan.getValue()))));
             vlanMatchBuild.setVlanId(vlanIDBuilder.build());
         }
@@ -270,7 +253,7 @@ public class FromSalConversionsUtils {
 
         InetAddress inetDestAddress = null;
         MatchField netDest = sourceMatch.getField(MatchType.NW_DST);
-        if (netSource != null && netSource.getValue() != null) {
+        if (netDest != null && netDest.getValue() != null) {
             inetDestAddress = (InetAddress) (netDest.getValue());
         }
 
@@ -371,5 +354,76 @@ public class FromSalConversionsUtils {
                 .setIpv6Destination(new Ipv6Prefix(inetDstAddressString));
         return layer6MatchBuild.build();
     }
+    
+    public static boolean flowEquals(Flow statsFlow, Flow storedFlow) {
+        if (statsFlow.getClass() != storedFlow.getClass()) {
+            return false;
+        }
+        if (statsFlow.getBufferId()== null) {
+            if (storedFlow.getBufferId() != null) {
+                return false;
+            }
+        } else if(!statsFlow.getBufferId().equals(storedFlow.getBufferId())) {
+            return false;
+        }
+        if (statsFlow.getContainerName()== null) {
+            if (storedFlow.getContainerName()!= null) {
+                return false;
+            }
+        } else if(!statsFlow.getContainerName().equals(storedFlow.getContainerName())) {
+            return false;
+        }
+        if (statsFlow.getCookie()== null) {
+            if (storedFlow.getCookie()!= null) {
+                return false;
+            }
+        } else if(!statsFlow.getCookie().equals(storedFlow.getCookie())) {
+            return false;
+        }
+        if (statsFlow.getMatch()== null) {
+            if (storedFlow.getMatch() != null) {
+                return false;
+            }
+        } else if(!statsFlow.getMatch().equals(storedFlow.getMatch())) {
+            return false;
+        }
+        if (statsFlow.getCookie()== null) {
+            if (storedFlow.getCookie()!= null) {
+                return false;
+            }
+        } else if(!statsFlow.getCookie().equals(storedFlow.getCookie())) {
+            return false;
+        }
+        if (statsFlow.getHardTimeout() == null) {
+            if (storedFlow.getHardTimeout() != null) {
+                return false;
+            }
+        } else if(!statsFlow.getHardTimeout().equals(storedFlow.getHardTimeout() )) {
+            return false;
+        }
+        if (statsFlow.getIdleTimeout()== null) {
+            if (storedFlow.getIdleTimeout() != null) {
+                return false;
+            }
+        } else if(!statsFlow.getIdleTimeout().equals(storedFlow.getIdleTimeout())) {
+            return false;
+        }
+        if (statsFlow.getPriority() == null) {
+            if (storedFlow.getPriority() != null) {
+                return false;
+            }
+        } else if(!statsFlow.getPriority().equals(storedFlow.getPriority())) {
+            return false;
+        }
+        if (statsFlow.getTableId() == null) {
+            if (storedFlow.getTableId() != null) {
+                return false;
+            }
+        } else if(!statsFlow.getTableId().equals(storedFlow.getTableId())) {
+            return false;
+        }
+        return true;
+    }
+
 
 }
index 8ac6f1b..31ae745 100644 (file)
@@ -9,7 +9,6 @@ import org.opendaylight.controller.sal.binding.api.data.DataBrokerService
 
 import static extension org.opendaylight.controller.sal.common.util.Arguments.*
 import static extension org.opendaylight.controller.sal.compatibility.NodeMapping.*
-import static org.opendaylight.controller.sal.compatibility.MDFlowMapping.*
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef
@@ -19,9 +18,7 @@ import org.opendaylight.controller.sal.reader.NodeConnectorStatistics
 import org.opendaylight.controller.sal.reader.FlowOnNode
 import org.opendaylight.controller.sal.reader.NodeDescription
 import org.slf4j.LoggerFactory
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowStatisticsInputBuilder
 import java.util.ArrayList
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllNodeConnectorStatisticsInputBuilder
 import org.opendaylight.controller.sal.inventory.IPluginInInventoryService
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.OpendaylightInventoryListener
 import org.opendaylight.controller.sal.inventory.IPluginOutInventoryService
@@ -45,17 +42,64 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkUtilizationNormal
 import org.opendaylight.controller.sal.topology.TopoEdgeUpdate
 import org.opendaylight.controller.sal.discovery.IDiscoveryService
-
-class InventoryAndReadAdapter implements IPluginInTopologyService, IPluginInReadService, IPluginInInventoryService, OpendaylightInventoryListener, FlowTopologyDiscoveryListener {
+import org.opendaylight.controller.sal.reader.IPluginOutReadService
+import java.util.List
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsListener
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.OpendaylightFlowTableStatisticsListener
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsListener
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.AggregateFlowStatisticsUpdate
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowsStatisticsUpdate
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsUpdate
+import org.opendaylight.controller.sal.reader.NodeTableStatistics
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapList
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowsStatisticsFromAllFlowTablesInputBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsService
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetAllNodeConnectorsStatisticsInputBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.OpendaylightFlowTableStatisticsService
+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.TableKey
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsData
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.FlowCapableNodeConnectorStatisticsData
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.FlowCapableNodeConnectorStatistics
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsData
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.GetFlowTablesStatisticsInputBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetNodeConnectorStatisticsInputBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.NodeConnectorStatisticsUpdate
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsFromFlowTableInputBuilder
+
+class InventoryAndReadAdapter implements IPluginInTopologyService,
+                                                                                        IPluginInReadService,
+                                                                                        IPluginInInventoryService,
+                                                                                        OpendaylightInventoryListener,
+                                                                                        FlowTopologyDiscoveryListener,
+                                                                                        OpendaylightFlowStatisticsListener,
+                                                                                        OpendaylightFlowTableStatisticsListener,
+                                                                                        OpendaylightPortStatisticsListener {
 
     private static val LOG = LoggerFactory.getLogger(InventoryAndReadAdapter);
 
+       private static val OPENFLOWV10_TABLE_ID = new Integer(0).shortValue;
     @Property
     DataBrokerService dataService;
 
+    @Property
+    DataProviderService dataProviderService;
+
     @Property
     OpendaylightFlowStatisticsService flowStatisticsService;
 
+    @Property
+    OpendaylightPortStatisticsService nodeConnectorStatisticsService;
+    
+    @Property
+    OpendaylightFlowTableStatisticsService flowTableStatisticsService;
+
     @Property
     IPluginOutInventoryService inventoryPublisher;
 
@@ -67,6 +111,22 @@ class InventoryAndReadAdapter implements IPluginInTopologyService, IPluginInRead
 
     @Property
     FlowTopologyDiscoveryService topologyDiscovery;
+    
+    @Property
+    List<IPluginOutReadService> statisticsPublisher = new ArrayList<IPluginOutReadService>();
+       
+    def setReadPublisher(IPluginOutReadService listener) {
+       statisticsPublisher.add(listener);
+    }
+    
+    def unsetReadPublisher (IPluginOutReadService listener) {
+       if( listener != null)
+               statisticsPublisher.remove(listener);
+    }
+
+    protected def startChange() {
+        return dataProviderService.beginTransaction;
+    }
 
     override getTransmitRate(NodeConnector connector) {
         val nodeConnector = readFlowCapableNodeConnector(connector.toNodeConnectorRef);
@@ -74,82 +134,206 @@ class InventoryAndReadAdapter implements IPluginInTopologyService, IPluginInRead
     }
 
     override readAllFlow(Node node, boolean cached) {
-        val input = new GetAllFlowStatisticsInputBuilder;
-        input.setNode(node.toNodeRef);
-        val result = flowStatisticsService.getAllFlowStatistics(input.build)
 
-        val statistics = result.get.result;
         val output = new ArrayList<FlowOnNode>();
-        for (stat : statistics.flowStatistics) {
-            // FIXME: Create FlowOnNode
-        }
+               val tableRef = InstanceIdentifier.builder(Nodes)
+                                                                               .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(node))
+                                                       .augmentation(FlowCapableNode).child(Table, new TableKey(OPENFLOWV10_TABLE_ID)).toInstance();
+               
+               val it = this.startChange();
+               
+               val table= it.readConfigurationData(tableRef) as Table;
+               
+               if(table != null){
+                       LOG.info("Number of flows installed in table 0 of node {} : {}",node,table.flow.size);
+                       
+                       for(flow : table.flow){
+                               
+                               val adsalFlow = ToSalConversionsUtils.toFlow(flow);
+                               val statsFromDataStore = flow.getAugmentation(FlowStatisticsData) as FlowStatisticsData;
+                               
+                               if(statsFromDataStore != null){
+                                       val it = new FlowOnNode(adsalFlow);
+                                       byteCount =  statsFromDataStore.flowStatistics.byteCount.value.longValue;
+                                       packetCount = statsFromDataStore.flowStatistics.packetCount.value.longValue;
+                                       durationSeconds = statsFromDataStore.flowStatistics.duration.second.value.intValue;
+                                       durationNanoseconds = statsFromDataStore.flowStatistics.duration.nanosecond.value.intValue;
+                                       
+                                       output.add(it);
+                               }
+                       }
+               }
+        
+        //TODO (main): Shell we send request to the switch? It will make async request to the switch.
+        // Once plugin receive response, it will let adaptor know through onFlowStatisticsUpdate()
+        // If we assume that md-sal statistics manager will always be running, then its not required
+        // But if not, then sending request will collect the latest data for adaptor atleast.
+        val input = new GetAllFlowsStatisticsFromAllFlowTablesInputBuilder;
+        input.setNode(node.toNodeRef);
+        flowStatisticsService.getAllFlowsStatisticsFromAllFlowTables(input.build)
+        
         return output;
     }
 
     override readAllNodeConnector(Node node, boolean cached) {
-        val input = new GetAllNodeConnectorStatisticsInputBuilder();
+       
+       val ret = new ArrayList<NodeConnectorStatistics>();
+               val nodeRef = InstanceIdentifier.builder(Nodes)
+                                                                       .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(node))
+                                                                       .toInstance();
+               
+               val provider = this.startChange();
+               
+               val dsNode= provider.readConfigurationData(nodeRef) as org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+               
+               if(dsNode != null){
+                       
+                       for (dsNodeConnector : dsNode.nodeConnector){
+                               val nodeConnectorRef = InstanceIdentifier.builder(Nodes)
+                                                                       .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(node))
+                                                                       .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector, dsNodeConnector.key)
+                                                                       .toInstance();
+                               
+                               val nodeConnectorFromDS = provider.readConfigurationData(nodeConnectorRef) as org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
+                               
+                               if(nodeConnectorFromDS != null){
+                                       val nodeConnectorStatsFromDs = nodeConnectorFromDS.getAugmentation(FlowCapableNodeConnectorStatisticsData) as FlowCapableNodeConnectorStatistics;
+                                       
+                                       ret.add(toNodeConnectorStatistics(nodeConnectorStatsFromDs.flowCapableNodeConnectorStatistics,dsNode.id,dsNodeConnector.id));
+                               }
+                       }
+               }
+
+               //TODO: Refer TODO (main)
+        val input = new GetAllNodeConnectorsStatisticsInputBuilder();
         input.setNode(node.toNodeRef);
-        val result = flowStatisticsService.getAllNodeConnectorStatistics(input.build());
-        val statistics = result.get.result.nodeConnectorStatistics;
-        val ret = new ArrayList<NodeConnectorStatistics>();
-        for (stat : statistics) {
-            ret.add(stat.toNodeConnectorStatistics())
-        }
+        nodeConnectorStatisticsService.getAllNodeConnectorsStatistics(input.build());
         return ret;
     }
 
     override readAllNodeTable(Node node, boolean cached) {
-        throw new UnsupportedOperationException("TODO: auto-generated method stub")
+       val ret = new ArrayList<NodeTableStatistics>();
+       
+               val dsFlowCapableNode= readFlowCapableNode(node.toNodeRef)
+               
+               if(dsFlowCapableNode != null){
+                       
+                       for (table : dsFlowCapableNode.table){
+                               
+                               val tableStats = table.getAugmentation(FlowTableStatisticsData) as FlowTableStatisticsData;
+                               
+                               if(tableStats != null){
+                                       ret.add(toNodeTableStatistics(tableStats.flowTableStatistics,table.id,node));
+                               }
+                       }
+               }
+
+               //TODO: Refer TODO (main)
+        val input = new GetFlowTablesStatisticsInputBuilder();
+        input.setNode(node.toNodeRef);
+        flowTableStatisticsService.getFlowTablesStatistics(input.build);
+        return ret;
     }
 
     override readDescription(Node node, boolean cached) {
-        val capableNode = readFlowCapableNode(node.toNodeRef)
-
-        val it = new NodeDescription()
-        manufacturer = capableNode.manufacturer
-        serialNumber = capableNode.serialNumber
-        software = capableNode.software
-        description = capableNode.description
-
-        return it;
-    }
-
-    override readFlow(Node node, Flow flow, boolean cached) {
-        val input = flowStatisticsInput(node, flow);
-        val output = flowStatisticsService.getFlowStatistics(input);
-
-        try {
-            val statistics = output.get().getResult();
-            if (statistics != null) {
-                val it = new FlowOnNode(flow);
-                byteCount = statistics.byteCount.value.longValue
-                durationNanoseconds = statistics.duration.getNanosecond().getValue().intValue();
-                durationSeconds = statistics.duration.getSecond().getValue().intValue();
-                packetCount = statistics.getPacketCount().getValue().longValue();
-                return it;
-            }
-        } catch (Exception e) {
-            LOG.error("Read flow not processed", e);
-        }
-        return null;
+        return toNodeDescription(node.toNodeRef);
+       }
+
+    override readFlow(Node node, Flow targetFlow, boolean cached) {
+               var FlowOnNode ret= null;
+               
+               val tableRef = InstanceIdentifier.builder(Nodes)
+                                                                               .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(node))
+                                                       .augmentation(FlowCapableNode).child(Table, new TableKey(OPENFLOWV10_TABLE_ID)).toInstance();
+               
+               val it = this.startChange();
+               
+               val table= it.readConfigurationData(tableRef) as Table;
+               
+               if(table != null){
+                       LOG.info("Number of flows installed in table 0 of node {} : {}",node,table.flow.size);
+                       
+                       for(mdsalFlow : table.flow){
+                               if(FromSalConversionsUtils.flowEquals(mdsalFlow, MDFlowMapping.toMDSalflow(targetFlow))){
+                                       val statsFromDataStore = mdsalFlow.getAugmentation(FlowStatisticsData) as FlowStatisticsData;
+                                       
+                                       if(statsFromDataStore != null){
+                                               LOG.debug("Found matching flow in the data store flow table ");
+                                               val it = new FlowOnNode(targetFlow);
+                                               byteCount =  statsFromDataStore.flowStatistics.byteCount.value.longValue;
+                                               packetCount = statsFromDataStore.flowStatistics.packetCount.value.longValue;
+                                               durationSeconds = statsFromDataStore.flowStatistics.duration.second.value.intValue;
+                                               durationNanoseconds = statsFromDataStore.flowStatistics.duration.nanosecond.value.intValue;
+                                               
+                                               ret = it;
+                                       }
+                               }                       
+                       }
+               }
+        
+        //TODO: Refer TODO (main)
+        val input = new GetFlowStatisticsFromFlowTableInputBuilder;
+        input.setNode(node.toNodeRef);
+        input.fieldsFrom(MDFlowMapping.toMDSalflow(targetFlow));
+        flowStatisticsService.getFlowStatisticsFromFlowTable(input.build)
+        
+        return ret;
+       
     }
 
     override readNodeConnector(NodeConnector connector, boolean cached) {
+       var NodeConnectorStatistics  nodeConnectorStatistics = null;
+       
+               val nodeConnectorRef = InstanceIdentifier.builder(Nodes)
+                                                                       .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(connector.node))
+                                                                       .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector, InventoryMapping.toNodeConnectorKey(connector))
+                                                                       .toInstance();
+               val provider = this.startChange();
+                               
+               val nodeConnectorFromDS = provider.readConfigurationData(nodeConnectorRef) as org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
+                               
+               if(nodeConnectorFromDS != null){
+                       val nodeConnectorStatsFromDs = nodeConnectorFromDS.getAugmentation(FlowCapableNodeConnectorStatisticsData) as FlowCapableNodeConnectorStatistics;
+                       if(nodeConnectorStatsFromDs != null) {
+                               nodeConnectorStatistics = toNodeConnectorStatistics(nodeConnectorStatsFromDs.flowCapableNodeConnectorStatistics,
+                                                                                                                                               InventoryMapping.toNodeKey(connector.node).id,
+                                                                                                                                               InventoryMapping.toNodeConnectorKey(connector).id);
+                       }
+               }
+
+               //TODO: Refer TODO (main)
+        val input = new GetNodeConnectorStatisticsInputBuilder();
+        input.setNode(connector.node.toNodeRef);
+        input.setNodeConnectorId(InventoryMapping.toNodeConnectorKey(connector).id);
+        nodeConnectorStatisticsService.getNodeConnectorStatistics(input.build());
+        return nodeConnectorStatistics;
+    }
 
-        val getNodeConnectorStatisticsInput = FromSalConversionsUtils.nodeConnectorStatistics(connector);
-        val future = flowStatisticsService.getNodeConnectorStatistics(getNodeConnectorStatisticsInput);
-        try {
-            val rpcResult = future.get();
-            val output = rpcResult.getResult();
-
-            if (output != null) {
-                return output.toNodeConnectorStatistics;
-            }
-        } catch (Exception e) {
-            LOG.error("Read node connector not processed", e);
-        }
-
-        return null;
+    override readNodeTable(NodeTable nodeTable, boolean cached) {
+       var NodeTableStatistics nodeStats = null
+       
+       val tableRef = InstanceIdentifier.builder(Nodes)
+                                                                               .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(nodeTable.node))
+                                                       .augmentation(FlowCapableNode).child(Table, new TableKey(nodeTable.ID as Short)).toInstance();
+               
+               val it = this.startChange();
+               
+               val table= it.readConfigurationData(tableRef) as Table;
+               
+               if(table != null){
+                       val tableStats = table.getAugmentation(FlowTableStatisticsData) as FlowTableStatisticsData;
+                               
+                       if(tableStats != null){
+                               nodeStats =  toNodeTableStatistics(tableStats.flowTableStatistics,table.id,nodeTable.node);
+                       }
+               }
+
+               //TODO: Refer TODO (main)
+        val input = new GetFlowTablesStatisticsInputBuilder();
+        input.setNode(nodeTable.node.toNodeRef);
+        flowTableStatisticsService.getFlowTablesStatistics(input.build);
+        
+        return nodeStats;
     }
 
     override onNodeConnectorRemoved(NodeConnectorRemoved update) {
@@ -157,17 +341,45 @@ class InventoryAndReadAdapter implements IPluginInTopologyService, IPluginInRead
     }
 
     override onNodeRemoved(NodeRemoved notification) {
-        // NOOP
+        val properties = Collections.<org.opendaylight.controller.sal.core.Property>emptySet();
+
+        inventoryPublisher.updateNode(notification.nodeRef.toADNode, UpdateType.REMOVED, properties);
     }
 
     override onNodeConnectorUpdated(NodeConnectorUpdated update) {
-        val properties = Collections.<org.opendaylight.controller.sal.core.Property>emptySet();
-        inventoryPublisher.updateNodeConnector(update.nodeConnectorRef.toADNodeConnector, UpdateType.CHANGED, properties);
+        val properties = new java.util.HashSet<org.opendaylight.controller.sal.core.Property>();
+
+
+        val org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject> identifier = update.nodeConnectorRef.value as org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject>;
+        var updateType = UpdateType.CHANGED;
+        if ( this._dataService.readOperationalData(identifier) == null ){
+            updateType = UpdateType.ADDED;
+        }
+
+        var nodeConnector = update.nodeConnectorRef.toADNodeConnector
+
+
+        properties.add(new org.opendaylight.controller.sal.core.Name(nodeConnector.ID.toString()));
+
+        inventoryPublisher.updateNodeConnector(nodeConnector , updateType , properties);
     }
 
     override onNodeUpdated(NodeUpdated notification) {
         val properties = Collections.<org.opendaylight.controller.sal.core.Property>emptySet();
-        inventoryPublisher.updateNode(notification.nodeRef.toADNode, UpdateType.CHANGED, properties);
+        val org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject> identifier = notification.nodeRef.value  as org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject>;
+
+        var updateType = UpdateType.CHANGED;
+        if ( this._dataService.readOperationalData(identifier) == null ){
+            updateType = UpdateType.ADDED;
+        }
+        inventoryPublisher.updateNode(notification.nodeRef.toADNode, updateType, properties);
+        
+               //Notify the listeners of IPluginOutReadService
+        
+        for (statsPublisher : statisticsPublisher){
+                       val nodeRef = InstanceIdentifier.builder(Nodes).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(notification.id)).toInstance;
+                       statsPublisher.descriptionStatisticsUpdated(nodeRef.toADNode,toNodeDescription(notification.nodeRef));
+               }
     }
 
     override getNodeProps() {
@@ -182,10 +394,6 @@ class InventoryAndReadAdapter implements IPluginInTopologyService, IPluginInRead
         return null;
     }
 
-    override readNodeTable(NodeTable table, boolean cached) {
-        throw new UnsupportedOperationException("TODO: auto-generated method stub")
-    }
-
     private def FlowCapableNode readFlowCapableNode(NodeRef ref) {
         val dataObject = dataService.readOperationalData(ref.value as InstanceIdentifier<? extends DataObject>);
         val node = dataObject.checkInstanceOf(
@@ -200,26 +408,61 @@ class InventoryAndReadAdapter implements IPluginInTopologyService, IPluginInRead
         return node.getAugmentation(FlowCapableNodeConnector);
     }
 
-    private static def toNodeConnectorStatistics(
-        org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.NodeConnectorStatistics output) {
-        val it = new NodeConnectorStatistics
-
-        collisionCount = output.getCollisionCount().longValue();
-        receiveCRCErrorCount = output.getReceiveCrcError().longValue();
-        receiveFrameErrorCount = output.getReceiveFrameError().longValue();
-        receiveOverRunErrorCount = output.getReceiveOverRunError().longValue();
+    private def toNodeConnectorStatistics(
+        org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.NodeConnectorStatistics nodeConnectorStatistics, NodeId nodeId, NodeConnectorId nodeConnectorId) {
+               
+                       val it = new NodeConnectorStatistics();
+                       
+                       receivePacketCount = nodeConnectorStatistics.packets.received.longValue;
+                       transmitPacketCount = nodeConnectorStatistics.packets.transmitted.longValue;
+                       
+                       receiveByteCount = nodeConnectorStatistics.bytes.received.longValue;
+                       transmitByteCount = nodeConnectorStatistics.bytes.transmitted.longValue;
+                       
+                       receiveDropCount = nodeConnectorStatistics.receiveDrops.longValue;
+                       transmitDropCount = nodeConnectorStatistics.transmitDrops.longValue;
+                       
+                       receiveErrorCount = nodeConnectorStatistics.receiveErrors.longValue;
+                       transmitErrorCount = nodeConnectorStatistics.transmitErrors.longValue;
+                       
+                       receiveFrameErrorCount = nodeConnectorStatistics.receiveFrameError.longValue;
+                       receiveOverRunErrorCount = nodeConnectorStatistics.receiveOverRunError.longValue;
+                       receiveCRCErrorCount = nodeConnectorStatistics.receiveCrcError.longValue;
+                       collisionCount = nodeConnectorStatistics.collisionCount.longValue;
+                       
+                       val nodeConnectorRef = InstanceIdentifier.builder(Nodes)
+                                                               .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(nodeId))
+                                                               .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector,new NodeConnectorKey(nodeConnectorId)).toInstance;
+                       
+                       nodeConnector = NodeMapping.toADNodeConnector(new NodeConnectorRef(nodeConnectorRef));
+                       
+                       return it;
+    }
 
-        receiveDropCount = output.getReceiveDrops().longValue();
-        receiveErrorCount = output.getReceiveErrors().longValue();
-        receivePacketCount = output.getPackets().getReceived().longValue();
-        receiveByteCount = output.getBytes().getReceived().longValue();
+       private def toNodeTableStatistics(
+               org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.statistics.FlowTableStatistics tableStats,
+               Short tableId,Node node){
+               var it = new NodeTableStatistics();
+               
+               activeCount = tableStats.activeFlows.value.intValue;
+               lookupCount = tableStats.packetsLookedUp.value.intValue;
+               matchedCount = tableStats.packetsMatched.value.intValue;
+               name = tableId.toString;
+               nodeTable = new NodeTable(NodeMapping.MD_SAL_TYPE,tableId,node);
+               return it;
+       }
+       
+       private def toNodeDescription(NodeRef nodeRef){
+               val capableNode = readFlowCapableNode(nodeRef);
 
-        transmitDropCount = output.getTransmitDrops().longValue();
-        transmitErrorCount = output.getTransmitErrors().longValue();
-        transmitPacketCount = output.getPackets().getTransmitted().longValue();
-        transmitByteCount = output.getBytes().getTransmitted().longValue();
+        val it = new NodeDescription()
+        manufacturer = capableNode.manufacturer
+        serialNumber = capableNode.serialNumber
+        software = capableNode.software
+        description = capableNode.description
+        
         return it;
-    }
+       }
 
     override sollicitRefresh() {
         topologyDiscovery.solicitRefresh
@@ -248,5 +491,78 @@ class InventoryAndReadAdapter implements IPluginInTopologyService, IPluginInRead
     def Edge toADEdge(Link link) {
         new Edge(link.source.toADNodeConnector,link.destination.toADNodeConnector)
     }
-
+       
+       /*
+        * OpendaylightFlowStatisticsListener interface implementation
+        */
+       override onAggregateFlowStatisticsUpdate(AggregateFlowStatisticsUpdate notification) {
+               throw new UnsupportedOperationException("TODO: auto-generated method stub")
+       }
+       
+       override onFlowsStatisticsUpdate(FlowsStatisticsUpdate notification) {
+               
+               val adsalFlowsStatistics = new ArrayList<FlowOnNode>();
+               
+               for(flowStats : notification.flowAndStatisticsMapList){
+                       if(flowStats.tableId == 0)
+                               adsalFlowsStatistics.add(toFlowOnNode(flowStats));
+               }
+               
+               for (statsPublisher : statisticsPublisher){
+                       val nodeRef = InstanceIdentifier.builder(Nodes).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(notification.id)).toInstance;
+                       statsPublisher.nodeFlowStatisticsUpdated(nodeRef.toADNode,adsalFlowsStatistics);
+               }
+               
+       }
+       /*
+        * OpendaylightFlowTableStatisticsListener interface implementation
+        */     
+       override onFlowTableStatisticsUpdate(FlowTableStatisticsUpdate notification) {
+               var adsalFlowTableStatistics = new ArrayList<NodeTableStatistics>();
+               
+               for(stats : notification.flowTableAndStatisticsMap){
+                       if (stats.tableId.value == 0){
+                               val it = new NodeTableStatistics();
+                               activeCount = stats.activeFlows.value.intValue;
+                               lookupCount = stats.packetsLookedUp.value.longValue;
+                               matchedCount = stats.packetsMatched.value.longValue;
+                               
+                               adsalFlowTableStatistics.add(it);
+                       }
+           &