Merge "Exception for URI /restconf/operations/module_name:rpc ended with slash"
authorTony Tkacik <ttkacik@cisco.com>
Thu, 27 Feb 2014 16:06:03 +0000 (16:06 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Thu, 27 Feb 2014 16:06:03 +0000 (16:06 +0000)
203 files changed:
opendaylight/commons/opendaylight/pom.xml
opendaylight/commons/protocol-framework/src/main/java/org/opendaylight/protocol/framework/AbstractProtocolSession.java
opendaylight/commons/protocol-framework/src/main/java/org/opendaylight/protocol/framework/AbstractSessionNegotiator.java
opendaylight/config/config-api/pom.xml
opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/ConflictingVersionException.java
opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/IdentityAttributeRef.java
opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/JmxAttribute.java
opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/ModuleIdentifier.java
opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/ValidationException.java
opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/jmx/CommitStatus.java
opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/jmx/ObjectNameUtil.java
opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/jmx/constants/ConfigRegistryConstants.java
opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/spi/Module.java
opendaylight/config/config-manager/pom.xml
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/CommitInfo.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigRegistryImpl.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionControllerImpl.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionControllerInternal.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/DeadlockMonitor.java [new file with mode: 0644]
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/TransactionIdentifier.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/TransactionStatus.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/dependencyresolver/DestroyedModule.java [moved from opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/DestroyedModule.java with 94% similarity]
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/dependencyresolver/ModuleInternalTransactionalInfo.java [moved from opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ModuleInternalTransactionalInfo.java with 72% similarity]
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/dependencyresolver/ModulesHolder.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/dependencyresolver/TransactionHolder.java [deleted file]
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/AnnotationsHelper.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/factoriesresolver/HierarchicalConfigMBeanFactoriesHolder.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/jmx/InternalJMXRegistrator.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/jmx/ServiceReference.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/jmx/TransactionJMXRegistrator.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/BlankTransactionServiceTracker.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/BundleContextBackedModuleFactoriesResolver.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/ConfigManagerActivator.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/mapping/ModuleInfoBundleTracker.java
opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/dependencyresolver/DependencyResolverManagerTest.java
opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/parallelapsp/TestingParallelAPSPModule.java
opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/threadpool/test/SimpleConfigurationTest.java
opendaylight/config/config-module-archetype/pom.xml
opendaylight/config/config-persister-api/pom.xml
opendaylight/config/config-persister-directory-adapter/pom.xml
opendaylight/config/config-persister-directory-autodetect-adapter/pom.xml
opendaylight/config/config-persister-directory-xml-adapter/pom.xml
opendaylight/config/config-persister-file-adapter/pom.xml
opendaylight/config/config-persister-file-xml-adapter/pom.xml
opendaylight/config/config-plugin-parent/pom.xml
opendaylight/config/config-util/pom.xml
opendaylight/config/config-util/src/main/java/org/opendaylight/controller/config/util/ConfigTransactionJMXClient.java
opendaylight/config/logback-config/pom.xml
opendaylight/config/logback-config/src/test/java/org/opendaylight/controller/config/yang/logback/config/LogbackModuleWithInitialConfigurationTest.java
opendaylight/config/logback-config/src/test/java/org/opendaylight/controller/config/yang/logback/config/LogbackWithXmlConfigModuleTest.java
opendaylight/config/netty-config-api/pom.xml
opendaylight/config/netty-event-executor-config/pom.xml
opendaylight/config/netty-event-executor-config/src/main/java/org/opendaylight/controller/config/yang/netty/eventexecutor/AutoCloseableEventExecutor.java [new file with mode: 0644]
opendaylight/config/netty-event-executor-config/src/main/java/org/opendaylight/controller/config/yang/netty/eventexecutor/GlobalEventExecutorModule.java
opendaylight/config/netty-event-executor-config/src/main/java/org/opendaylight/controller/config/yang/netty/eventexecutor/ImmediateEventExecutorModule.java [new file with mode: 0644]
opendaylight/config/netty-event-executor-config/src/main/java/org/opendaylight/controller/config/yang/netty/eventexecutor/ImmediateEventExecutorModuleFactory.java [new file with mode: 0644]
opendaylight/config/netty-event-executor-config/src/main/yang/netty-event-executor.yang
opendaylight/config/netty-threadgroup-config/pom.xml
opendaylight/config/netty-timer-config/pom.xml
opendaylight/config/pom.xml
opendaylight/config/shutdown-api/pom.xml
opendaylight/config/shutdown-impl/pom.xml
opendaylight/config/shutdown-impl/src/test/java/org/opendaylight/controller/config/yang/shutdown/impl/ShutdownTest.java
opendaylight/config/threadpool-config-api/pom.xml
opendaylight/config/threadpool-config-impl/pom.xml
opendaylight/config/yang-jmx-generator-it/pom.xml
opendaylight/config/yang-jmx-generator-plugin/pom.xml
opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/FtlFilePersister.java
opendaylight/config/yang-jmx-generator/pom.xml
opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntryBuilder.java
opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/TOAttribute.java
opendaylight/config/yang-store-api/pom.xml
opendaylight/config/yang-store-impl/pom.xml
opendaylight/config/yang-test-plugin/pom.xml
opendaylight/config/yang-test/pom.xml
opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/IdentityTestModule.java
opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/IdentityTestModuleStub.txt
opendaylight/distribution/opendaylight/src/main/resources/run.sh
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/adsal/FlowServiceAdapter.java
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/adsal/FlowStatisticsAdapter.java
opendaylight/md-sal/model/pom.xml
opendaylight/md-sal/pom.xml
opendaylight/md-sal/remoterpc-routingtable/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/api/RoutingTable.java
opendaylight/md-sal/remoterpc-routingtable/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/impl/Activator.java
opendaylight/md-sal/remoterpc-routingtable/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/impl/RoutingTableImpl.java
opendaylight/md-sal/remoterpc-routingtable/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/impl/RoutingTableImplTest.java
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/data/DataBrokerService.java
opendaylight/md-sal/sal-binding-broker/pom.xml
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/DataBrokerImpl.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/DeprecatedDataAPISupport.xtend [deleted file]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentConnector.java
opendaylight/md-sal/sal-binding-config/pom.xml
opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/WriteParentReadChildTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-it/pom.xml
opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/AbstractBindingSalConsumerInstance.java
opendaylight/md-sal/sal-common-api/src/main/java/org/opendaylight/controller/md/sal/common/api/data/DataCommitHandler.java
opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/service/TwoPhaseCommit.java
opendaylight/md-sal/sal-common-util/src/main/java/org/opendaylight/controller/sal/common/util/Futures.java
opendaylight/md-sal/sal-dom-api/pom.xml
opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/Broker.java
opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/RoutedRpcDefaultImplementation.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/RpcImplementation.java
opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/RpcProvisionRegistry.java
opendaylight/md-sal/sal-dom-broker/pom.xml
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/BrokerConfigActivator.xtend
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/MountPointImpl.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/SchemaAwareDataStoreAdapter.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/SchemaAwareRpcBroker.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/osgi/RpcProvisionRegistryProxy.java
opendaylight/md-sal/sal-netconf-connector/pom.xml
opendaylight/md-sal/sal-remote/pom.xml
opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/config/yang/md/sal/remote/rpc/ZeroMQServerModule.java
opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/ClientImpl.java
opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/RemoteRpcClient.java
opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/RemoteRpcProvider.java
opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/RoutingTableProvider.java
opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/ServerImpl.java
opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/dto/RouteIdentifierImpl.java
opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/yang/odl-sal-dom-rpc-remote-cfg.yang
opendaylight/md-sal/sal-remoterpc-connector/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/ClientImplTest.java
opendaylight/md-sal/sal-remoterpc-connector/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/MockRoutingTable.java
opendaylight/md-sal/sal-remoterpc-connector/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/RemoteRpcProviderTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-remoterpc-connector/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/RouteIdentifierImplTest.java [deleted file]
opendaylight/md-sal/sal-remoterpc-connector/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/ServerImplTest.java
opendaylight/md-sal/sal-remoterpc-connector/integrationtest/test-nb/pom.xml
opendaylight/md-sal/sal-restconf-broker/src/main/java/org/opendaylight/controller/sal/restconf/binding/impl/DataBrokerServiceImpl.java
opendaylight/md-sal/sal-restconf-broker/src/main/java/org/opendaylight/controller/sal/restconf/broker/client/SalRemoteClient.java [moved from opendaylight/md-sal/samples/toaster-provider/src/main/java/org/opendaylight/controller/sample/toaster/provider/ToasterActivator.java with 55% similarity]
opendaylight/md-sal/sal-restconf-broker/src/main/java/org/opendaylight/controller/sal/restconf/broker/client/SalRemoteClientDeployer.java [new file with mode: 0644]
opendaylight/md-sal/sal-restconf-broker/src/main/java/org/opendaylight/controller/sal/restconf/broker/client/SalRemoteClientImpl.java [new file with mode: 0644]
opendaylight/md-sal/sal-restconf-broker/src/main/java/org/opendaylight/controller/sal/restconf/broker/impl/DataBrokerServiceImpl.java
opendaylight/md-sal/samples/pom.xml
opendaylight/md-sal/samples/toaster-consumer/pom.xml
opendaylight/md-sal/samples/toaster-consumer/src/main/java/org/opendaylight/controller/config/yang/config/toaster_consumer/impl/ToasterConsumerModule.java [new file with mode: 0644]
opendaylight/md-sal/samples/toaster-consumer/src/main/java/org/opendaylight/controller/config/yang/config/toaster_consumer/impl/ToasterConsumerModuleFactory.java [new file with mode: 0644]
opendaylight/md-sal/samples/toaster-consumer/src/main/java/org/opendaylight/controller/sample/toaster/provider/impl/ToastConsumerImpl.java
opendaylight/md-sal/samples/toaster-consumer/src/main/yang/toaster-consumer-impl.yang [new file with mode: 0644]
opendaylight/md-sal/samples/toaster-consumer/src/main/yang/toaster-consumer.yang [new file with mode: 0644]
opendaylight/md-sal/samples/toaster-it/pom.xml
opendaylight/md-sal/samples/toaster-it/src/test/java/org/opendaylight/controller/sample/toaster/it/ToasterTest.java
opendaylight/md-sal/samples/toaster-it/src/test/resources/controller.xml [new file with mode: 0644]
opendaylight/md-sal/samples/toaster-it/src/test/resources/logback.xml
opendaylight/md-sal/samples/toaster-provider/pom.xml
opendaylight/md-sal/samples/toaster-provider/src/main/java/org/opendaylight/controller/config/yang/config/toaster_provider/impl/ToasterProviderModule.java [new file with mode: 0644]
opendaylight/md-sal/samples/toaster-provider/src/main/java/org/opendaylight/controller/config/yang/config/toaster_provider/impl/ToasterProviderModuleFactory.java [new file with mode: 0644]
opendaylight/md-sal/samples/toaster-provider/src/main/java/org/opendaylight/controller/sample/toaster/provider/OpendaylightToaster.java
opendaylight/md-sal/samples/toaster-provider/src/main/java/org/opendaylight/controller/sample/toaster/provider/ToasterProvider.java [deleted file]
opendaylight/md-sal/samples/toaster-provider/src/main/yang/toaster-provider-impl.yang [new file with mode: 0644]
opendaylight/md-sal/samples/toaster-provider/src/main/yang/toaster-provider.yang [new file with mode: 0644]
opendaylight/md-sal/samples/toaster/pom.xml
opendaylight/netconf/config-netconf-connector/pom.xml
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/Commit.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/DiscardChanges.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/Validate.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfig.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/Activator.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/transactions/TransactionProvider.java
opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java
opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigTest.java
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/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/ConfigPusherConfiguration.java [new file with mode: 0644]
opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/ConfigPusherConfigurationBuilder.java [new file with mode: 0644]
opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/PersisterAggregator.java
opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/osgi/ConfigPersisterActivator.java
opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/osgi/ConfigPersisterTest.java [new file with mode: 0644]
opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/osgi/MockNetconfEndpoint.java [new file with mode: 0644]
opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/osgi/MockedBundleContext.java [new file with mode: 0644]
opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/osgi/TestingExceptionHandler.java [new file with mode: 0644]
opendaylight/netconf/ietf-netconf-monitoring-extension/pom.xml
opendaylight/netconf/ietf-netconf-monitoring/pom.xml
opendaylight/netconf/netconf-api/pom.xml
opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/NetconfDocumentedException.java
opendaylight/netconf/netconf-client/pom.xml
opendaylight/netconf/netconf-impl/pom.xml
opendaylight/netconf/netconf-it/pom.xml
opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/pax/IdentityRefNetconfTest.java [new file with mode: 0644]
opendaylight/netconf/netconf-it/src/test/resources/controller.xml [new file with mode: 0644]
opendaylight/netconf/netconf-it/src/test/resources/netconfMessages/commit.xml [new file with mode: 0644]
opendaylight/netconf/netconf-it/src/test/resources/netconfMessages/editConfig_identities.xml [new file with mode: 0644]
opendaylight/netconf/netconf-it/src/test/resources/netconfMessages/getConfig.xml [new file with mode: 0644]
opendaylight/netconf/netconf-mapping-api/pom.xml
opendaylight/netconf/netconf-monitoring/pom.xml
opendaylight/netconf/netconf-ssh/pom.xml
opendaylight/netconf/netconf-util/pom.xml
opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/test/XmlFileLoader.java
opendaylight/netconf/pom.xml
opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronFloatingIPsNorthbound.java
opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronNetworksNorthbound.java
opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronPortsNorthbound.java
opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronRoutersNorthbound.java
opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSubnetsNorthbound.java
opendaylight/sal/api/pom.xml
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Edge.java
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Path.java

index 328dfaf..d42f1fd 100644 (file)
     <arphandler.version>0.5.2-SNAPSHOT</arphandler.version>
     <forwarding.staticrouting>0.5.2-SNAPSHOT</forwarding.staticrouting>
     <samples.loadbalancer>0.5.2-SNAPSHOT</samples.loadbalancer>
-    <config.version>0.2.4-SNAPSHOT</config.version>
-    <netconf.version>0.2.4-SNAPSHOT</netconf.version>
+    <config.version>0.2.5-SNAPSHOT</config.version>
+    <netconf.version>0.2.5-SNAPSHOT</netconf.version>
     <mdsal.version>1.1-SNAPSHOT</mdsal.version>
     <containermanager.version>0.5.2-SNAPSHOT</containermanager.version>
     <containermanager.it.version>0.5.2-SNAPSHOT</containermanager.it.version>
     <switchmanager.api.version>0.7.1-SNAPSHOT</switchmanager.api.version>
     <connectionmanager.version>0.1.2-SNAPSHOT</connectionmanager.version>
-    <sal.version>0.7.1-SNAPSHOT</sal.version>
+    <sal.version>0.8.1-SNAPSHOT</sal.version>
     <sal.networkconfiguration.version>0.0.3-SNAPSHOT</sal.networkconfiguration.version>
     <sal.connection.version>0.1.2-SNAPSHOT</sal.connection.version>
     <networkconfig.bridgedomain.northbound.version>0.0.3-SNAPSHOT</networkconfig.bridgedomain.northbound.version>
     <java.version.target>1.7</java.version.target>
     <!-- enforcer version -->
     <enforcer.version>1.3.1</enforcer.version>
+    <xtend.version>2.4.3</xtend.version>
+    <xtend.dstdir>${project.build.directory}/generated-sources/xtend-gen</xtend.dstdir>
   </properties>
 
   <dependencyManagement>
       </dependency>
 
         <!-- md-sal -->
+        <dependency>
+            <groupId>org.eclipse.xtend</groupId>
+            <artifactId>org.eclipse.xtend.lib</artifactId>
+            <version>${xtend.version}</version>
+        </dependency>
         <dependency>
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>sal-common</artifactId>
           <artifactId>config-persister-impl</artifactId>
           <version>${netconf.version}</version>
         </dependency>
-        <dependency>
-          <groupId>${project.groupId}</groupId>
-          <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>
 
          <!-- threadpool -->
           <dependency>
           <artifactId>maven-release-plugin</artifactId>
           <version>${releaseplugin.version}</version>
         </plugin>
+        <plugin>
+            <groupId>org.opendaylight.yangtools</groupId>
+            <artifactId>yang-maven-plugin</artifactId>
+            <version>${yangtools.version}</version>
+        </plugin>
         <!-- Ignore/Execute plugin execution -->
         <plugin>
           <groupId>org.eclipse.m2e</groupId>
             <testTarget>${java.version.target}</testTarget>
           </configuration>
        </plugin>
+          <plugin>
+              <groupId>org.eclipse.xtend</groupId>
+              <artifactId>xtend-maven-plugin</artifactId>
+              <version>${xtend.version}</version>
+              <executions>
+                  <execution>
+                      <goals>
+                          <goal>compile</goal>
+                      </goals>
+                      <configuration>
+                          <outputDirectory>${xtend.dstdir}</outputDirectory>
+                      </configuration>
+                  </execution>
+              </executions>
+          </plugin>
       </plugins>
     </pluginManagement>
   </build>
index e7bd665..47e96d1 100644 (file)
@@ -40,6 +40,7 @@ public abstract class AbstractProtocolSession<M> extends SimpleChannelInboundHan
     }
 
     @Override
+    @SuppressWarnings("unchecked")
     protected final void channelRead0(final ChannelHandlerContext ctx, final Object msg) {
         LOG.debug("Message was received: {}", msg);
         handleMessage((M) msg);
index d41e810..cbe9235 100644 (file)
@@ -85,6 +85,7 @@ public abstract class AbstractSessionNegotiator<M, S extends AbstractProtocolSes
     }
 
     @Override
+    @SuppressWarnings("unchecked")
     public final void channelRead(final ChannelHandlerContext ctx, final Object msg) {
         LOG.debug("Negotiation read invoked on channel {}", channel);
         try {
index 425e4b4..cab2e8c 100644 (file)
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>config-subsystem</artifactId>
         <groupId>org.opendaylight.controller</groupId>
-        <version>0.2.4-SNAPSHOT</version>
+        <version>0.2.5-SNAPSHOT</version>
     </parent>
 
     <artifactId>config-api</artifactId>
index 9c25242..2edf261 100644 (file)
@@ -14,7 +14,7 @@ package org.opendaylight.controller.config.api;
  * transaction was committed after creating this transaction. Clients can create
  * new transaction and merge the changes.
  */
-public class ConflictingVersionException extends RuntimeException {
+public class ConflictingVersionException extends Exception {
     private static final long serialVersionUID = 1L;
 
     public ConflictingVersionException() {
index 7373759..5ad6e0d 100644 (file)
@@ -19,8 +19,9 @@ public final class IdentityAttributeRef {
 
     @ConstructorProperties(QNAME_ATTR_NAME)
     public IdentityAttributeRef(String qNameOfIdentity) {
-        if (qNameOfIdentity == null)
+        if (qNameOfIdentity == null) {
             throw new NullPointerException("Parameter " + QNAME_ATTR_NAME + " is null");
+        }
         this.qNameOfIdentity = qNameOfIdentity;
     }
 
@@ -46,12 +47,18 @@ public final class IdentityAttributeRef {
 
     @Override
     public boolean equals(Object o) {
-        if (this == o) return true;
-        if (!(o instanceof IdentityAttributeRef)) return false;
+        if (this == o) {
+            return true;
+        }
+        if (!(o instanceof IdentityAttributeRef)) {
+            return false;
+        }
 
         IdentityAttributeRef that = (IdentityAttributeRef) o;
 
-        if (!qNameOfIdentity.equals(that.qNameOfIdentity)) return false;
+        if (!qNameOfIdentity.equals(that.qNameOfIdentity)) {
+            return false;
+        }
 
         return true;
     }
index 96deb05..244f22f 100644 (file)
@@ -15,8 +15,9 @@ public class JmxAttribute {
     private final String attributeName;
 
     public JmxAttribute(String attributeName) {
-        if (attributeName == null)
+        if (attributeName == null) {
             throw new NullPointerException("Parameter 'attributeName' is null");
+        }
         this.attributeName = attributeName;
     }
 
@@ -26,16 +27,19 @@ public class JmxAttribute {
 
     @Override
     public boolean equals(Object o) {
-        if (this == o)
+        if (this == o) {
             return true;
-        if (o == null || getClass() != o.getClass())
+        }
+        if (o == null || getClass() != o.getClass()) {
             return false;
+        }
 
         JmxAttribute that = (JmxAttribute) o;
 
         if (attributeName != null ? !attributeName.equals(that.attributeName)
-                : that.attributeName != null)
+                : that.attributeName != null) {
             return false;
+        }
 
         return true;
     }
index c654f5f..7baaf9f 100644 (file)
@@ -14,12 +14,12 @@ public class ModuleIdentifier implements Identifier {
     private final String factoryName, instanceName;
 
     public ModuleIdentifier(String factoryName, String instanceName) {
-        if (factoryName == null)
-            throw new IllegalArgumentException(
-                    "Parameter 'factoryName' is null");
-        if (instanceName == null)
-            throw new IllegalArgumentException(
-                    "Parameter 'instanceName' is null");
+        if (factoryName == null) {
+            throw new IllegalArgumentException("Parameter 'factoryName' is null");
+        }
+        if (instanceName == null) {
+            throw new IllegalArgumentException("Parameter 'instanceName' is null");
+        }
         this.factoryName = factoryName;
         this.instanceName = instanceName;
     }
@@ -34,17 +34,21 @@ public class ModuleIdentifier implements Identifier {
 
     @Override
     public boolean equals(Object o) {
-        if (this == o)
+        if (this == o) {
             return true;
-        if (o == null || getClass() != o.getClass())
+        }
+        if (o == null || getClass() != o.getClass()) {
             return false;
+        }
 
         ModuleIdentifier that = (ModuleIdentifier) o;
 
-        if (!factoryName.equals(that.factoryName))
+        if (!factoryName.equals(that.factoryName)) {
             return false;
-        if (!instanceName.equals(that.instanceName))
+        }
+        if (!instanceName.equals(that.instanceName)) {
             return false;
+        }
 
         return true;
     }
index f27d123..82b73d4 100644 (file)
@@ -16,9 +16,11 @@ import java.util.Map.Entry;
 
 /**
  * This exception is not intended to be used while implementing modules,
- * itaggregates validation exceptions and sends them back to the user.
+ * it aggregates validation exceptions and sends them back to the user.
+ * Use {@link org.opendaylight.controller.config.api.JmxAttributeValidationException} for
+ * validating modules instead.
  */
-public class ValidationException extends RuntimeException {
+public class ValidationException extends Exception {
     private static final long serialVersionUID = -6072893219820274247L;
 
     private final Map<String/* module name */, Map<String/* instance name */, ExceptionMessageWithStackTrace>> failedValidations;
@@ -118,23 +120,30 @@ public class ValidationException extends RuntimeException {
 
         @Override
         public boolean equals(Object obj) {
-            if (this == obj)
+            if (this == obj) {
                 return true;
-            if (obj == null)
+            }
+            if (obj == null) {
                 return false;
-            if (getClass() != obj.getClass())
+            }
+            if (getClass() != obj.getClass()) {
                 return false;
+            }
             ExceptionMessageWithStackTrace other = (ExceptionMessageWithStackTrace) obj;
             if (message == null) {
-                if (other.message != null)
+                if (other.message != null) {
                     return false;
-            } else if (!message.equals(other.message))
+                }
+            } else if (!message.equals(other.message)) {
                 return false;
+            }
             if (stackTrace == null) {
-                if (other.stackTrace != null)
+                if (other.stackTrace != null) {
                     return false;
-            } else if (!stackTrace.equals(other.stackTrace))
+                }
+            } else if (!stackTrace.equals(other.stackTrace)) {
                 return false;
+            }
             return true;
         }
 
index bd53bd4..4f9ea7a 100644 (file)
@@ -7,32 +7,27 @@
  */
 package org.opendaylight.controller.config.api.jmx;
 
+import javax.annotation.concurrent.Immutable;
+import javax.management.ObjectName;
 import java.beans.ConstructorProperties;
 import java.util.Collections;
 import java.util.List;
 
-import javax.annotation.concurrent.Immutable;
-import javax.management.ObjectName;
-
 @Immutable
 public class CommitStatus {
     private final List<ObjectName> newInstances, reusedInstances,
             recreatedInstances;
 
     /**
-     *
-     * @param newInstances
-     *            newly created instances
-     * @param reusedInstances
-     *            reused instances
-     * @param recreatedInstances
-     *            recreated instances
+     * @param newInstances       newly created instances
+     * @param reusedInstances    reused instances
+     * @param recreatedInstances recreated instances
      */
-    @ConstructorProperties({ "newInstances", "reusedInstances",
-            "recreatedInstances" })
+    @ConstructorProperties({"newInstances", "reusedInstances",
+            "recreatedInstances"})
     public CommitStatus(List<ObjectName> newInstances,
-            List<ObjectName> reusedInstances,
-            List<ObjectName> recreatedInstances) {
+                        List<ObjectName> reusedInstances,
+                        List<ObjectName> recreatedInstances) {
         this.newInstances = Collections.unmodifiableList(newInstances);
         this.reusedInstances = Collections.unmodifiableList(reusedInstances);
         this.recreatedInstances = Collections
@@ -40,7 +35,6 @@ public class CommitStatus {
     }
 
     /**
-     *
      * @return list of objectNames representing newly created instances
      */
     public List<ObjectName> getNewInstances() {
@@ -48,7 +42,6 @@ public class CommitStatus {
     }
 
     /**
-     *
      * @return list of objectNames representing reused instances
      */
     public List<ObjectName> getReusedInstances() {
@@ -56,7 +49,6 @@ public class CommitStatus {
     }
 
     /**
-     *
      * @return list of objectNames representing recreated instances
      */
     public List<ObjectName> getRecreatedInstances() {
@@ -72,7 +64,7 @@ public class CommitStatus {
         result = prime
                 * result
                 + ((recreatedInstances == null) ? 0 : recreatedInstances
-                        .hashCode());
+                .hashCode());
         result = prime * result
                 + ((reusedInstances == null) ? 0 : reusedInstances.hashCode());
         return result;
@@ -80,28 +72,37 @@ public class CommitStatus {
 
     @Override
     public boolean equals(Object obj) {
-        if (this == obj)
+        if (this == obj) {
             return true;
-        if (obj == null)
+        }
+        if (obj == null) {
             return false;
-        if (getClass() != obj.getClass())
+        }
+        if (getClass() != obj.getClass()) {
             return false;
+        }
         CommitStatus other = (CommitStatus) obj;
         if (newInstances == null) {
-            if (other.newInstances != null)
+            if (other.newInstances != null) {
                 return false;
-        } else if (!newInstances.equals(other.newInstances))
+            }
+        } else if (!newInstances.equals(other.newInstances)) {
             return false;
+        }
         if (recreatedInstances == null) {
-            if (other.recreatedInstances != null)
+            if (other.recreatedInstances != null) {
                 return false;
-        } else if (!recreatedInstances.equals(other.recreatedInstances))
+            }
+        } else if (!recreatedInstances.equals(other.recreatedInstances)) {
             return false;
+        }
         if (reusedInstances == null) {
-            if (other.reusedInstances != null)
+            if (other.reusedInstances != null) {
                 return false;
-        } else if (!reusedInstances.equals(other.reusedInstances))
+            }
+        } else if (!reusedInstances.equals(other.reusedInstances)) {
             return false;
+        }
         return true;
     }
 
index 3baa103..d60e608 100644 (file)
@@ -11,6 +11,7 @@ import org.opendaylight.controller.config.api.ModuleIdentifier;
 import org.opendaylight.controller.config.api.jmx.constants.ConfigRegistryConstants;
 
 import javax.annotation.concurrent.ThreadSafe;
+import javax.management.MalformedObjectNameException;
 import javax.management.ObjectName;
 import java.util.Arrays;
 import java.util.HashMap;
@@ -46,8 +47,8 @@ public class ObjectNameUtil {
     public static ObjectName createON(String on) {
         try {
             return new ObjectName(on);
-        } catch (Exception e) {
-            throw new RuntimeException(e);
+        } catch (MalformedObjectNameException e) {
+            throw new IllegalArgumentException(e);
         }
     }
 
@@ -63,8 +64,8 @@ public class ObjectNameUtil {
         Hashtable<String, String> table = new Hashtable<>(attribs);
         try {
             return new ObjectName(domain, table);
-        } catch (Exception e) {
-            throw new RuntimeException(e);
+        } catch (MalformedObjectNameException e) {
+            throw new IllegalArgumentException(e);
         }
 
     }
@@ -116,8 +117,7 @@ public class ObjectNameUtil {
     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;
+        return unquoteAndUnescape(objectName, quoted);
     }
 
     // ObjectName supports quotation and ignores tokens like =, but fails to ignore ? sign.
@@ -292,8 +292,8 @@ public class ObjectNameUtil {
         }
     }
 
-    public static void checkTypeOneOf(ObjectName objectName, String ... types) {
-        for(String type: types) {
+    public static void checkTypeOneOf(ObjectName objectName, String... types) {
+        for (String type : types) {
             if (type.equals(objectName.getKeyProperty(TYPE_KEY))) {
                 return;
             }
@@ -304,10 +304,12 @@ public class ObjectNameUtil {
 
     public static ObjectName createModulePattern(String moduleName,
                                                  String instanceName) {
-        if (moduleName == null)
+        if (moduleName == null) {
             moduleName = "*";
-        if (instanceName == null)
+        }
+        if (instanceName == null) {
             instanceName = "*";
+        }
         // do not return object names containing transaction name
         ObjectName namePattern = ObjectNameUtil
                 .createON(ObjectNameUtil.ON_DOMAIN + ":"
@@ -343,13 +345,15 @@ public class ObjectNameUtil {
                                           String expectedType) {
         checkType(objectName, expectedType);
         String factoryName = getFactoryName(objectName);
-        if (factoryName == null)
+        if (factoryName == null) {
             throw new IllegalArgumentException(
                     "ObjectName does not contain module name");
+        }
         String instanceName = getInstanceName(objectName);
-        if (instanceName == null)
+        if (instanceName == null) {
             throw new IllegalArgumentException(
                     "ObjectName does not contain instance name");
+        }
         return new ModuleIdentifier(factoryName, instanceName);
     }
 
index 81a29bf..1d9563b 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.controller.config.api.jmx.constants;
 
+import javax.management.MalformedObjectNameException;
 import javax.management.ObjectName;
 
 public class ConfigRegistryConstants {
@@ -19,7 +20,7 @@ public class ConfigRegistryConstants {
 
     public static final ObjectName OBJECT_NAME = createONWithDomainAndType(TYPE_CONFIG_REGISTRY);
 
-    public static String GET_AVAILABLE_MODULE_NAMES_ATTRIBUT_NAME = "AvailableModuleNames";
+    public static final String GET_AVAILABLE_MODULE_NAMES_ATTRIBUT_NAME = "AvailableModuleNames";
 
     public static ObjectName createONWithDomainAndType(String type) {
         return createON(ON_DOMAIN, TYPE_KEY, type);
@@ -28,8 +29,8 @@ public class ConfigRegistryConstants {
     public static ObjectName createON(String name, String key, String value) {
         try {
             return new ObjectName(name, key, value);
-        } catch (Exception e) {
-            throw new RuntimeException(e);
+        } catch (MalformedObjectNameException e) {
+            throw new IllegalArgumentException(e);
         }
 
     }
index dd11b75..1b16ec8 100644 (file)
@@ -7,11 +7,11 @@
  */
 package org.opendaylight.controller.config.spi;
 
-import javax.annotation.concurrent.NotThreadSafe;
-
 import org.opendaylight.controller.config.api.ModuleIdentifier;
 import org.opendaylight.yangtools.concepts.Identifiable;
 
+import javax.annotation.concurrent.NotThreadSafe;
+
 
 /**
  * Represents one service that is to be configured. These methods need to be
@@ -20,7 +20,7 @@ import org.opendaylight.yangtools.concepts.Identifiable;
  * ConfigBeans.
  * <p>
  * In order to guide dependency resolution, the setter method should be
- * annotated with {@link RequireInterface}.
+ * annotated with {@link org.opendaylight.controller.config.api.annotations.RequireInterface}.
  * </p>
  * <p>
  * Thread safety note: implementations of this interface are not required to be
@@ -43,10 +43,10 @@ public interface Module extends Identifiable<ModuleIdentifier>{
      * Returns 'live' object that was configured using this object. It is
      * allowed to call this method only after all ConfigBeans were validated. In
      * this method new resources might be opened or old instance might be
-     * modified. Note that when obtaining dependent Module using
-     * {@link org.opendaylight.controller.config.api.DependencyResolver#validateDependency(Class, javax.management.ObjectName, String)}
-     * a proxy will be created that will disallow calling this method before
-     * second commit phase begins.
+     * modified. This method must be implemented so that it returns same
+     * result for a single transaction. Since Module is created per transaction
+     * this means that it must be safe to cache result of first call.
+     *
      *
      * @return closeable instance: After bundle update the factory might be able
      *         to copy old configuration into new one without being able to cast
index 524cd1f..7d7d9d6 100644 (file)
@@ -3,7 +3,7 @@
     <parent>
         <artifactId>config-subsystem</artifactId>
         <groupId>org.opendaylight.controller</groupId>
-        <version>0.2.4-SNAPSHOT</version>
+        <version>0.2.5-SNAPSHOT</version>
         <relativePath>..</relativePath>
     </parent>
     <artifactId>config-manager</artifactId>
@@ -68,7 +68,6 @@
         <dependency>
             <groupId>com.google.guava</groupId>
             <artifactId>guava</artifactId>
-            <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.yangtools</groupId>
index 9d08629..28732d8 100644 (file)
@@ -14,6 +14,8 @@ import java.util.Map;
 import javax.annotation.concurrent.Immutable;
 
 import org.opendaylight.controller.config.api.ModuleIdentifier;
+import org.opendaylight.controller.config.manager.impl.dependencyresolver.DestroyedModule;
+import org.opendaylight.controller.config.manager.impl.dependencyresolver.ModuleInternalTransactionalInfo;
 
 /**
  * Structure obtained during first phase commit, contains destroyed modules from
index 39682fa..dd510a1 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.controller.config.manager.impl;
 
+import com.google.common.collect.Maps;
 import org.opendaylight.controller.config.api.ConflictingVersionException;
 import org.opendaylight.controller.config.api.ModuleIdentifier;
 import org.opendaylight.controller.config.api.RuntimeBeanRegistratorAwareModule;
@@ -14,6 +15,8 @@ import org.opendaylight.controller.config.api.ServiceReferenceWritableRegistry;
 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.dependencyresolver.DestroyedModule;
+import org.opendaylight.controller.config.manager.impl.dependencyresolver.ModuleInternalTransactionalInfo;
 import org.opendaylight.controller.config.manager.impl.dynamicmbean.DynamicReadableWrapper;
 import org.opendaylight.controller.config.manager.impl.factoriesresolver.HierarchicalConfigMBeanFactoriesHolder;
 import org.opendaylight.controller.config.manager.impl.factoriesresolver.ModuleFactoriesResolver;
@@ -105,19 +108,19 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
     private List<ModuleFactory> lastListOfFactories = Collections.emptyList();
 
     @GuardedBy("this") // switched in every 2ndPC
-    private CloseableServiceReferenceReadableRegistry  readableSRRegistry = ServiceReferenceRegistryImpl.createInitialSRLookupRegistry();
+    private CloseableServiceReferenceReadableRegistry readableSRRegistry = ServiceReferenceRegistryImpl.createInitialSRLookupRegistry();
 
     // constructor
     public ConfigRegistryImpl(ModuleFactoriesResolver resolver,
-            MBeanServer configMBeanServer, CodecRegistry codecRegistry) {
+                              MBeanServer configMBeanServer, CodecRegistry codecRegistry) {
         this(resolver, configMBeanServer,
                 new BaseJMXRegistrator(configMBeanServer), codecRegistry);
     }
 
     // constructor
     public ConfigRegistryImpl(ModuleFactoriesResolver resolver,
-            MBeanServer configMBeanServer,
-            BaseJMXRegistrator baseJMXRegistrator, CodecRegistry codecRegistry) {
+                              MBeanServer configMBeanServer,
+                              BaseJMXRegistrator baseJMXRegistrator, CodecRegistry codecRegistry) {
         this.resolver = resolver;
         this.beanToOsgiServiceManager = new BeanToOsgiServiceManager();
         this.configMBeanServer = configMBeanServer;
@@ -173,7 +176,7 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
             throw new IllegalStateException(e);
         }
         transactionController.copyExistingModulesAndProcessFactoryDiff(currentConfig.getEntries(), lastListOfFactories);
-        transactionsHolder.add(transactionName, transactionController);
+        transactionsHolder.add(transactionName, transactionController, txLookupRegistry);
         return transactionController;
     }
 
@@ -181,6 +184,7 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
      * {@inheritDoc}
      */
     @Override
+    @SuppressWarnings("PMD.AvoidCatchingThrowable")
     public synchronized CommitStatus commitConfig(ObjectName transactionControllerON)
             throws ConflictingVersionException, ValidationException {
         final String transactionName = ObjectNameUtil
@@ -188,12 +192,13 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
         logger.trace("About to commit {}. Current parentVersion: {}, versionCounter {}", transactionName, version, versionCounter);
 
         // find ConfigTransactionController
-        Map<String, ConfigTransactionControllerInternal> transactions = transactionsHolder.getCurrentTransactions();
-        ConfigTransactionControllerInternal configTransactionController = transactions.get(transactionName);
-        if (configTransactionController == null) {
+        Map<String, Entry<ConfigTransactionControllerInternal, ConfigTransactionLookupRegistry>> transactions = transactionsHolder.getCurrentTransactions();
+        Entry<ConfigTransactionControllerInternal, ConfigTransactionLookupRegistry> configTransactionControllerEntry = transactions.get(transactionName);
+        if (configTransactionControllerEntry == null) {
             throw new IllegalArgumentException(String.format(
                     "Transaction with name '%s' not found", transactionName));
         }
+        ConfigTransactionControllerInternal configTransactionController = configTransactionControllerEntry.getKey();
         // check optimistic lock
         if (version != configTransactionController.getParentVersion()) {
             throw new ConflictingVersionException(
@@ -208,10 +213,9 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
         lastListOfFactories = Collections.unmodifiableList(configTransactionController.getCurrentlyRegisteredFactories());
         // non recoverable from here:
         try {
-            return secondPhaseCommit(
-                    configTransactionController, commitInfo);
+            return secondPhaseCommit(configTransactionController, commitInfo, configTransactionControllerEntry.getValue());
         } catch (Throwable t) { // some libs throw Errors: e.g.
-                                // javax.xml.ws.spi.FactoryFinder$ConfigurationError
+            // javax.xml.ws.spi.FactoryFinder$ConfigurationError
             isHealthy = false;
             logger.error("Configuration Transaction failed on 2PC, server is unhealthy", t);
             if (t instanceof RuntimeException) {
@@ -225,14 +229,14 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
     }
 
     private CommitStatus secondPhaseCommit(ConfigTransactionControllerInternal configTransactionController,
-                                           CommitInfo commitInfo) {
+                                           CommitInfo commitInfo, ConfigTransactionLookupRegistry txLookupRegistry) {
 
         // close instances which were destroyed by the user, including
         // (hopefully) runtime beans
         for (DestroyedModule toBeDestroyed : commitInfo
                 .getDestroyedFromPreviousTransactions()) {
             toBeDestroyed.close(); // closes instance (which should close
-                                   // runtime jmx registrator),
+            // runtime jmx registrator),
             // also closes osgi registration and ModuleJMXRegistrator
             // registration
             currentConfig.remove(toBeDestroyed.getIdentifier());
@@ -254,7 +258,7 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
                         .getRuntimeBeanRegistrator();
             }
             // set runtime jmx registrator if required
-            Module module = entry.getModule();
+            Module module = entry.getProxiedModule();
             if (module instanceof RuntimeBeanRegistratorAwareModule) {
                 ((RuntimeBeanRegistratorAwareModule) module)
                         .setRuntimeBeanRegistrator(runtimeBeanRegistrator);
@@ -264,8 +268,9 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
         }
 
         // can register runtime beans
-        List<ModuleIdentifier> orderedModuleIdentifiers = configTransactionController
-                .secondPhaseCommit();
+        List<ModuleIdentifier> orderedModuleIdentifiers = configTransactionController.secondPhaseCommit();
+        txLookupRegistry.close();
+        configTransactionController.close();
 
         // copy configuration to read only mode
         List<ObjectName> newInstances = new LinkedList<>();
@@ -278,10 +283,11 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
         for (ModuleIdentifier moduleIdentifier : orderedModuleIdentifiers) {
             ModuleInternalTransactionalInfo entry = commitInfo.getCommitted()
                     .get(moduleIdentifier);
-            if (entry == null)
+            if (entry == null) {
                 throw new NullPointerException("Module not found "
                         + moduleIdentifier);
-            Module module = entry.getModule();
+            }
+
             ObjectName primaryReadOnlyON = ObjectNameUtil
                     .createReadOnlyModuleON(moduleIdentifier);
 
@@ -298,13 +304,14 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
                     .createModuleJMXRegistrator();
 
             OsgiRegistration osgiRegistration = null;
+            AutoCloseable instance = entry.getProxiedModule().getInstance();
             if (entry.hasOldModule()) {
                 ModuleInternalInfo oldInternalInfo = entry.getOldInternalInfo();
                 DynamicReadableWrapper oldReadableConfigBean = oldInternalInfo.getReadableModule();
                 currentConfig.remove(entry.getIdentifier());
 
                 // test if old instance == new instance
-                if (oldReadableConfigBean.getInstance().equals(module.getInstance())) {
+                if (oldReadableConfigBean.getInstance().equals(instance)) {
                     // reused old instance:
                     // wrap in readable dynamic mbean
                     reusedInstances.add(primaryReadOnlyON);
@@ -326,9 +333,10 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
                 // wrap in readable dynamic mbean
                 newInstances.add(primaryReadOnlyON);
             }
+            Module realModule = entry.getRealModule();
 
             DynamicReadableWrapper newReadableConfigBean = new DynamicReadableWrapper(
-                    module, module.getInstance(), moduleIdentifier,
+                    realModule, instance, moduleIdentifier,
                     registryMBeanServer, configMBeanServer);
 
             // register to JMX
@@ -342,10 +350,10 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
             // register to OSGi
             if (osgiRegistration == null) {
                 ModuleFactory moduleFactory = entry.getModuleFactory();
-                if(moduleFactory != null) {
+                if (moduleFactory != null) {
                     BundleContext bc = configTransactionController.
                             getModuleFactoryBundleContext(moduleFactory.getImplementationName());
-                    osgiRegistration = beanToOsgiServiceManager.registerToOsgi(module.getClass(),
+                    osgiRegistration = beanToOsgiServiceManager.registerToOsgi(realModule.getClass(),
                             newReadableConfigBean.getInstance(), entry.getIdentifier(), bc);
                 } else {
                     throw new NullPointerException(entry.getIdentifier().getFactoryName() + " ModuleFactory not found.");
@@ -360,7 +368,7 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
                     runtimeBeanRegistrator, newModuleJMXRegistrator,
                     orderingIdx, entry.isDefaultBean());
 
-            newConfigEntries.put(module, newInfo);
+            newConfigEntries.put(realModule, newInfo);
             orderingIdx++;
         }
         currentConfig.addAll(newConfigEntries.values());
@@ -382,12 +390,12 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
      */
     @Override
     public synchronized List<ObjectName> getOpenConfigs() {
-        Map<String, ConfigTransactionControllerInternal> transactions = transactionsHolder
+        Map<String, Entry<ConfigTransactionControllerInternal, ConfigTransactionLookupRegistry>> transactions = transactionsHolder
                 .getCurrentTransactions();
         List<ObjectName> result = new ArrayList<>(transactions.size());
-        for (ConfigTransactionControllerInternal configTransactionController : transactions
+        for (Entry<ConfigTransactionControllerInternal, ConfigTransactionLookupRegistry> configTransactionControllerEntry : transactions
                 .values()) {
-            result.add(configTransactionController.getControllerObjectName());
+            result.add(configTransactionControllerEntry.getKey().getControllerObjectName());
         }
         return result;
     }
@@ -401,11 +409,14 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
     @Override
     public synchronized void close() {
         // abort transactions
-        Map<String, ConfigTransactionControllerInternal> transactions = transactionsHolder
+        Map<String, Entry<ConfigTransactionControllerInternal, ConfigTransactionLookupRegistry>> transactions = transactionsHolder
                 .getCurrentTransactions();
-        for (ConfigTransactionControllerInternal configTransactionController : transactions
+        for (Entry<ConfigTransactionControllerInternal, ConfigTransactionLookupRegistry> configTransactionControllerEntry : transactions
                 .values()) {
+
+            ConfigTransactionControllerInternal configTransactionController = configTransactionControllerEntry.getKey();
             try {
+                configTransactionControllerEntry.getValue().close();
                 configTransactionController.abortConfig();
             } catch (RuntimeException e) {
                 logger.warn("Ignoring exception while aborting {}",
@@ -485,7 +496,7 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
      */
     @Override
     public Set<ObjectName> lookupConfigBeans(String moduleName,
-            String instanceName) {
+                                             String instanceName) {
         ObjectName namePattern = ObjectNameUtil.createModulePattern(moduleName,
                 instanceName);
         return baseJMXRegistrator.queryNames(namePattern, null);
@@ -504,11 +515,13 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe
      */
     @Override
     public Set<ObjectName> lookupRuntimeBeans(String moduleName,
-            String instanceName) {
-        if (moduleName == null)
+                                              String instanceName) {
+        if (moduleName == null) {
             moduleName = "*";
-        if (instanceName == null)
+        }
+        if (instanceName == null) {
             instanceName = "*";
+        }
         ObjectName namePattern = ObjectNameUtil.createRuntimeBeanPattern(
                 moduleName, instanceName);
         return baseJMXRegistrator.queryNames(namePattern, null);
@@ -646,18 +659,18 @@ class TransactionsHolder {
      * {@link ConfigTransactionControllerInternal} instances, because platform
      * MBeanServer transforms mbeans into another representation. Map is cleaned
      * every time current transactions are requested.
-     *
      */
     @GuardedBy("ConfigRegistryImpl.this")
-    private final Map<String /* transactionName */, ConfigTransactionControllerInternal> transactions = new HashMap<>();
+    private final Map<String /* transactionName */,
+            Entry<ConfigTransactionControllerInternal, ConfigTransactionLookupRegistry>> transactions = new HashMap<>();
 
     /**
      * Can only be called from within synchronized method.
      */
     public void add(String transactionName,
-            ConfigTransactionControllerInternal transactionController) {
+                    ConfigTransactionControllerInternal transactionController, ConfigTransactionLookupRegistry txLookupRegistry) {
         Object oldValue = transactions.put(transactionName,
-                transactionController);
+                Maps.immutableEntry(transactionController, txLookupRegistry));
         if (oldValue != null) {
             throw new IllegalStateException(
                     "Error: two transactions with same name");
@@ -671,13 +684,13 @@ class TransactionsHolder {
      *
      * @return current view on transactions map.
      */
-    public Map<String, ConfigTransactionControllerInternal> getCurrentTransactions() {
+    public Map<String, Entry<ConfigTransactionControllerInternal, ConfigTransactionLookupRegistry>> getCurrentTransactions() {
         // first, remove closed transaction
-        for (Iterator<Entry<String, ConfigTransactionControllerInternal>> it = transactions
-                .entrySet().iterator(); it.hasNext();) {
-            Entry<String, ConfigTransactionControllerInternal> entry = it
+        for (Iterator<Entry<String, Entry<ConfigTransactionControllerInternal, ConfigTransactionLookupRegistry>>> it = transactions
+                .entrySet().iterator(); it.hasNext(); ) {
+            Entry<String, Entry<ConfigTransactionControllerInternal, ConfigTransactionLookupRegistry>> entry = it
                     .next();
-            if (entry.getValue().isClosed()) {
+            if (entry.getValue().getKey().isClosed()) {
                 it.remove();
             }
         }
index 0ec6969..84f76c9 100644 (file)
@@ -13,6 +13,7 @@ import org.opendaylight.controller.config.api.ServiceReferenceWritableRegistry;
 import org.opendaylight.controller.config.api.ValidationException;
 import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
 import org.opendaylight.controller.config.manager.impl.dependencyresolver.DependencyResolverManager;
+import org.opendaylight.controller.config.manager.impl.dependencyresolver.ModuleInternalTransactionalInfo;
 import org.opendaylight.controller.config.manager.impl.dynamicmbean.DynamicWritableWrapper;
 import org.opendaylight.controller.config.manager.impl.dynamicmbean.ReadOnlyAtomicBoolean;
 import org.opendaylight.controller.config.manager.impl.dynamicmbean.ReadOnlyAtomicBoolean.ReadOnlyAtomicBooleanImpl;
@@ -53,7 +54,7 @@ import static java.lang.String.format;
 class ConfigTransactionControllerImpl implements
         ConfigTransactionControllerInternal,
         ConfigTransactionControllerImplMXBean,
-        Identifiable<TransactionIdentifier>{
+        Identifiable<TransactionIdentifier> {
     private static final Logger logger = LoggerFactory.getLogger(ConfigTransactionControllerImpl.class);
 
     private final ConfigTransactionLookupRegistry txLookupRegistry;
@@ -95,7 +96,8 @@ class ConfigTransactionControllerImpl implements
         this.currentlyRegisteredFactories = currentlyRegisteredFactories;
         this.factoriesHolder = new HierarchicalConfigMBeanFactoriesHolder(currentlyRegisteredFactories);
         this.transactionStatus = new TransactionStatus();
-        this.dependencyResolverManager = new DependencyResolverManager(transactionName, transactionStatus, writableSRRegistry, codecRegistry);
+        this.dependencyResolverManager = new DependencyResolverManager(txLookupRegistry.getTransactionIdentifier(),
+                transactionStatus, writableSRRegistry, codecRegistry);
         this.transactionsMBeanServer = transactionsMBeanServer;
         this.configMBeanServer = configMBeanServer;
         this.blankTransaction = blankTransaction;
@@ -124,12 +126,12 @@ class ConfigTransactionControllerImpl implements
 
         List<ModuleFactory> toBeAdded = new ArrayList<>();
         List<ModuleFactory> toBeRemoved = new ArrayList<>();
-        for(ModuleFactory moduleFactory: factoriesHolder.getModuleFactories()) {
-            if (oldSet.contains(moduleFactory) == false){
+        for (ModuleFactory moduleFactory : factoriesHolder.getModuleFactories()) {
+            if (oldSet.contains(moduleFactory) == false) {
                 toBeAdded.add(moduleFactory);
             }
         }
-        for(ModuleFactory moduleFactory: lastListOfFactories){
+        for (ModuleFactory moduleFactory : lastListOfFactories) {
             if (newSet.contains(moduleFactory) == false) {
                 toBeRemoved.add(moduleFactory);
             }
@@ -151,7 +153,7 @@ class ConfigTransactionControllerImpl implements
         }
 
         // remove modules belonging to removed factories
-        for(ModuleFactory removedFactory: toBeRemoved){
+        for (ModuleFactory removedFactory : toBeRemoved) {
             List<ModuleIdentifier> modulesOfRemovedFactory = dependencyResolverManager.findAllByFactory(removedFactory);
             for (ModuleIdentifier name : modulesOfRemovedFactory) {
                 destroyModule(name);
@@ -189,7 +191,7 @@ class ConfigTransactionControllerImpl implements
 
     @Override
     public synchronized ObjectName createModule(String factoryName,
-            String instanceName) throws InstanceAlreadyExistsException {
+                                                String instanceName) throws InstanceAlreadyExistsException {
 
         transactionStatus.checkNotCommitStarted();
         transactionStatus.checkNotAborted();
@@ -213,11 +215,11 @@ class ConfigTransactionControllerImpl implements
             throws InstanceAlreadyExistsException {
 
         logger.debug("Adding module {} to transaction {}", moduleIdentifier, this);
-        if (moduleIdentifier.equals(module.getIdentifier())==false) {
+        if (moduleIdentifier.equals(module.getIdentifier()) == false) {
             throw new IllegalStateException("Incorrect name reported by module. Expected "
-             + moduleIdentifier + ", got " + module.getIdentifier());
+                    + moduleIdentifier + ", got " + module.getIdentifier());
         }
-        if (dependencyResolver.getIdentifier().equals(moduleIdentifier) == false ) {
+        if (dependencyResolver.getIdentifier().equals(moduleIdentifier) == false) {
             throw new IllegalStateException("Incorrect name reported by dependency resolver. Expected "
                     + moduleIdentifier + ", got " + dependencyResolver.getIdentifier());
         }
@@ -231,11 +233,10 @@ class ConfigTransactionControllerImpl implements
         // put wrapper to jmx
         TransactionModuleJMXRegistration transactionModuleJMXRegistration = getTxModuleJMXRegistrator()
                 .registerMBean(writableDynamicWrapper, writableON);
-        ModuleInternalTransactionalInfo moduleInternalTransactionalInfo = new ModuleInternalTransactionalInfo(
+
+        dependencyResolverManager.put(
                 moduleIdentifier, module, moduleFactory,
                 maybeOldConfigBeanInfo, transactionModuleJMXRegistration, isDefaultBean);
-
-        dependencyResolverManager.put(moduleInternalTransactionalInfo);
         return writableON;
     }
 
@@ -271,7 +272,7 @@ class ConfigTransactionControllerImpl implements
         // first remove refNames, it checks for objectname existence
         try {
             writableSRRegistry.removeServiceReferences(
-                    ObjectNameUtil.createTransactionModuleON(getTransactionName(),moduleIdentifier));
+                    ObjectNameUtil.createTransactionModuleON(getTransactionName(), moduleIdentifier));
         } catch (InstanceNotFoundException e) {
             logger.error("Possible code error: cannot find {} in {}", moduleIdentifier, writableSRRegistry);
             throw new IllegalStateException("Possible code error: cannot find " + moduleIdentifier, e);
@@ -294,8 +295,9 @@ class ConfigTransactionControllerImpl implements
 
     @Override
     public synchronized void validateConfig() throws ValidationException {
-        if (configBeanModificationDisabled.get())
+        if (configBeanModificationDisabled.get()) {
             throw new IllegalStateException("Cannot start validation");
+        }
         configBeanModificationDisabled.set(true);
         try {
             validate_noLocks();
@@ -383,7 +385,7 @@ class ConfigTransactionControllerImpl implements
                 logger.error("Commit failed on {} in transaction {}", name,
                         getTransactionIdentifier(), e);
                 internalAbort();
-                throw new RuntimeException(
+                throw new IllegalStateException(
                         format("Error - getInstance() failed for %s in transaction %s",
                                 name, getTransactionIdentifier()), e);
             }
@@ -393,8 +395,6 @@ class ConfigTransactionControllerImpl implements
 
         logger.trace("Committed configuration {}", getTransactionIdentifier());
         transactionStatus.setCommitted();
-        // unregister this and all modules from jmx
-        close();
 
         return dependencyResolverManager.getSortedModuleIdentifiers();
     }
@@ -412,8 +412,7 @@ class ConfigTransactionControllerImpl implements
     }
 
     public void close() {
-        //FIXME: should not close object that was retrieved in constructor, a wrapper object should do that perhaps
-        txLookupRegistry.close();
+        dependencyResolverManager.close();
     }
 
     @Override
@@ -571,6 +570,7 @@ class ConfigTransactionControllerImpl implements
         return writableSRRegistry;
     }
 
+    @Override
     public TransactionIdentifier getTransactionIdentifier() {
         return txLookupRegistry.getTransactionIdentifier();
     }
index 82bae44..f6164e3 100644 (file)
@@ -23,7 +23,7 @@ import org.osgi.framework.BundleContext;
  * and {@link ConfigRegistryImpl} (consumer).
  */
 interface ConfigTransactionControllerInternal extends
-        ConfigTransactionControllerImplMXBean {
+        ConfigTransactionControllerImplMXBean, AutoCloseable {
 
 
 
@@ -75,4 +75,8 @@ interface ConfigTransactionControllerInternal extends
 
     ServiceReferenceWritableRegistry getWritableRegistry();
 
+    TransactionIdentifier getTransactionIdentifier();
+
+    @Override
+    void close();
 }
diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/DeadlockMonitor.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/DeadlockMonitor.java
new file mode 100644 (file)
index 0000000..ba7ab7f
--- /dev/null
@@ -0,0 +1,122 @@
+package org.opendaylight.controller.config.manager.impl;
+
+import org.opendaylight.controller.config.api.ModuleIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.GuardedBy;
+import java.util.concurrent.TimeUnit;
+
+public class DeadlockMonitor implements AutoCloseable {
+    private static final Logger logger = LoggerFactory.getLogger(DeadlockMonitorRunnable.class);
+
+    private static final long WARN_AFTER_MILLIS = 5000;
+
+    private final TransactionIdentifier transactionIdentifier;
+    private final DeadlockMonitorRunnable thread;
+    @GuardedBy("this")
+    private ModuleIdentifierWithNanos moduleIdentifierWithNanos = new ModuleIdentifierWithNanos();
+
+    public DeadlockMonitor(TransactionIdentifier transactionIdentifier) {
+        this.transactionIdentifier = transactionIdentifier;
+        thread = new DeadlockMonitorRunnable();
+        thread.start();
+    }
+
+    public synchronized void setCurrentlyInstantiatedModule(ModuleIdentifier currentlyInstantiatedModule) {
+        this.moduleIdentifierWithNanos = new ModuleIdentifierWithNanos(currentlyInstantiatedModule);
+    }
+
+    public boolean isAlive() {
+        return thread.isAlive();
+    }
+
+    @Override
+    public void close() {
+        thread.interrupt();
+    }
+
+    @Override
+    public String toString() {
+        return "DeadlockMonitor{" + transactionIdentifier + '}';
+    }
+
+    private class DeadlockMonitorRunnable extends Thread {
+
+        private DeadlockMonitorRunnable() {
+            super(DeadlockMonitor.this.toString());
+        }
+
+        @Override
+        public void run() {
+            ModuleIdentifierWithNanos old = new ModuleIdentifierWithNanos(); // null moduleId
+            while (this.isInterrupted() == false) {
+                ModuleIdentifierWithNanos copy = new ModuleIdentifierWithNanos(DeadlockMonitor.this.moduleIdentifierWithNanos);
+                if (old.moduleIdentifier == null) {
+                    // started
+                    old = copy;
+                } else if (old.moduleIdentifier != null && old.equals(copy)) {
+                    // is the getInstance() running longer than WARN_AFTER_MILLIS ?
+                    long runningTime = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - copy.nanoTime);
+                    if (runningTime > WARN_AFTER_MILLIS) {
+                        logger.warn("{} did not finish after {} ms", copy.moduleIdentifier, runningTime);
+                    }
+                }
+                try {
+                    sleep(1000);
+                } catch (InterruptedException e) {
+                    interrupt();
+                }
+            }
+            logger.trace("Exiting {}", this);
+        }
+
+        @Override
+        public String toString() {
+            return "DeadLockMonitorRunnable{" + transactionIdentifier + "}";
+        }
+    }
+
+    private class ModuleIdentifierWithNanos {
+        @Nullable
+        private final ModuleIdentifier moduleIdentifier;
+        private final long nanoTime;
+
+        private ModuleIdentifierWithNanos() {
+            moduleIdentifier = null;
+            nanoTime = System.nanoTime();
+        }
+
+        private ModuleIdentifierWithNanos(ModuleIdentifier moduleIdentifier) {
+            this.moduleIdentifier = moduleIdentifier;
+            nanoTime = System.nanoTime();
+        }
+
+        private ModuleIdentifierWithNanos(ModuleIdentifierWithNanos copy) {
+            moduleIdentifier = copy.moduleIdentifier;
+            nanoTime = copy.nanoTime;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+
+            ModuleIdentifierWithNanos that = (ModuleIdentifierWithNanos) o;
+
+            if (nanoTime != that.nanoTime) return false;
+            if (moduleIdentifier != null ? !moduleIdentifier.equals(that.moduleIdentifier) : that.moduleIdentifier != null)
+                return false;
+
+            return true;
+        }
+
+        @Override
+        public int hashCode() {
+            int result = moduleIdentifier != null ? moduleIdentifier.hashCode() : 0;
+            result = 31 * result + (int) (nanoTime ^ (nanoTime >>> 32));
+            return result;
+        }
+    }
+}
index 941aec1..fd6262c 100644 (file)
@@ -10,6 +10,7 @@ package org.opendaylight.controller.config.manager.impl;
 import javax.annotation.Nullable;
 
 import org.opendaylight.controller.config.api.ModuleIdentifier;
+import org.opendaylight.controller.config.manager.impl.dependencyresolver.DestroyedModule;
 import org.opendaylight.controller.config.manager.impl.dynamicmbean.DynamicReadableWrapper;
 import org.opendaylight.controller.config.manager.impl.jmx.ModuleJMXRegistrator;
 import org.opendaylight.controller.config.manager.impl.jmx.RootRuntimeBeanRegistratorImpl;
index 0faa32b..bf35fd1 100644 (file)
@@ -195,7 +195,7 @@ public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceRe
 
         this.serviceReferenceRegistrator = serviceReferenceRegistratorFactory.create();
 
-        Map<String, Set<String /* QName */>> factoryNamesToQNames = new HashMap<>();
+        Map<String, Set<String /* QName */>> modifiableFactoryNamesToQNames = new HashMap<>();
         Set<ServiceInterfaceAnnotation> allAnnotations = new HashSet<>();
         Set<String /* qName */> allQNames = new HashSet<>();
         for (Entry<String, ModuleFactory> entry : factories.entrySet()) {
@@ -210,27 +210,27 @@ public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceRe
             }
             allAnnotations.addAll(siAnnotations);
             allQNames.addAll(qNames);
-            factoryNamesToQNames.put(entry.getKey(), Collections.unmodifiableSet(qNames));
+            modifiableFactoryNamesToQNames.put(entry.getKey(), Collections.unmodifiableSet(qNames));
         }
-        this.factoryNamesToQNames = Collections.unmodifiableMap(factoryNamesToQNames);
+        this.factoryNamesToQNames = Collections.unmodifiableMap(modifiableFactoryNamesToQNames);
         this.allQNames = Collections.unmodifiableSet(allQNames);
         // fill namespacesToAnnotations
-        Map<String /* namespace */, Map<String /* localName */, ServiceInterfaceAnnotation>> namespacesToAnnotations =
+        Map<String /* namespace */, Map<String /* localName */, ServiceInterfaceAnnotation>> modifiableNamespacesToAnnotations =
                 new HashMap<>();
         for (ServiceInterfaceAnnotation sia : allAnnotations) {
-            Map<String, ServiceInterfaceAnnotation> ofNamespace = namespacesToAnnotations.get(sia.namespace());
+            Map<String, ServiceInterfaceAnnotation> ofNamespace = modifiableNamespacesToAnnotations.get(sia.namespace());
             if (ofNamespace == null) {
                 ofNamespace = new HashMap<>();
-                namespacesToAnnotations.put(sia.namespace(), ofNamespace);
+                modifiableNamespacesToAnnotations.put(sia.namespace(), ofNamespace);
             }
             if (ofNamespace.containsKey(sia.localName())) {
                 logger.error("Cannot construct namespacesToAnnotations map, conflict between local names in {}, offending local name: {}, map so far {}",
-                        sia.namespace(), sia.localName(), namespacesToAnnotations);
+                        sia.namespace(), sia.localName(), modifiableNamespacesToAnnotations);
                 throw new IllegalArgumentException("Conflict between local names in " + sia.namespace() + " : " + sia.localName());
             }
             ofNamespace.put(sia.localName(), sia);
         }
-        this.namespacesToAnnotations = Collections.unmodifiableMap(namespacesToAnnotations);
+        this.namespacesToAnnotations = Collections.unmodifiableMap(modifiableNamespacesToAnnotations);
         // copy refNames
         logger.trace("factoryNamesToQNames:{}", this.factoryNamesToQNames);
     }
index 28bd613..15c69bf 100644 (file)
@@ -28,15 +28,18 @@ public class TransactionIdentifier implements Identifier {
 
     @Override
     public boolean equals(Object o) {
-        if (this == o)
+        if (this == o) {
             return true;
-        if (o == null || getClass() != o.getClass())
+        }
+        if (o == null || getClass() != o.getClass()) {
             return false;
+        }
 
         TransactionIdentifier that = (TransactionIdentifier) o;
 
-        if (name != null ? !name.equals(that.name) : that.name != null)
+        if (name != null ? !name.equals(that.name) : that.name != null) {
             return false;
+        }
 
         return true;
     }
index a250620..f86d6b1 100644 (file)
@@ -48,18 +48,21 @@ public class TransactionStatus {
     }
 
     public synchronized void checkNotCommitStarted() {
-        if (secondPhaseCommitStarted == true)
+        if (secondPhaseCommitStarted == true) {
             throw new IllegalStateException("Commit was triggered");
+        }
     }
 
     public synchronized void checkCommitStarted() {
-        if (secondPhaseCommitStarted == false)
+        if (secondPhaseCommitStarted == false) {
             throw new IllegalStateException("Commit was not triggered");
+        }
     }
 
     public synchronized void checkNotAborted() {
-        if (aborted == true)
+        if (aborted == true) {
             throw new IllegalStateException("Configuration was aborted");
+        }
     }
 
     public synchronized void checkNotCommitted() {
index ec9678f..c229450 100644 (file)
@@ -39,7 +39,7 @@ import static java.lang.String.format;
  * during validation. Tracks dependencies for ordering purposes.
  */
 final class DependencyResolverImpl implements DependencyResolver,
-       Comparable<DependencyResolverImpl> {
+        Comparable<DependencyResolverImpl> {
     private static final Logger logger = LoggerFactory.getLogger(DependencyResolverImpl.class);
 
     private final ModulesHolder modulesHolder;
@@ -74,15 +74,15 @@ final class DependencyResolverImpl implements DependencyResolver,
             throw new NullPointerException(
                     "Parameter 'expectedServiceInterface' is null");
         }
-        if (jmxAttribute == null)
+        if (jmxAttribute == null) {
             throw new NullPointerException("Parameter 'jmxAttribute' is null");
+        }
 
         JmxAttributeValidationException.checkNotNull(dependentReadOnlyON,
                 "is null, expected dependency implementing "
                         + expectedServiceInterface, jmxAttribute);
 
 
-
         // check that objectName belongs to this transaction - this should be
         // stripped
         // in DynamicWritableWrapper
@@ -118,7 +118,7 @@ final class DependencyResolverImpl implements DependencyResolver,
         }
     }
 
-    // transalate from serviceref to module ON
+    // translate from serviceref to module ON
     private ObjectName translateServiceRefIfPossible(ObjectName dependentReadOnlyON) {
         if (ObjectNameUtil.isServiceReference(dependentReadOnlyON)) {
             String serviceQName = ObjectNameUtil.getServiceQName(dependentReadOnlyON);
@@ -135,7 +135,7 @@ final class DependencyResolverImpl implements DependencyResolver,
     //TODO: check for cycles
     @Override
     public <T> T resolveInstance(Class<T> expectedType, ObjectName dependentReadOnlyON,
-            JmxAttribute jmxAttribute) {
+                                 JmxAttribute jmxAttribute) {
         if (expectedType == null || dependentReadOnlyON == null || jmxAttribute == null) {
             throw new IllegalArgumentException(format(
                     "Null parameters not allowed, got %s %s %s", expectedType,
@@ -161,8 +161,7 @@ final class DependencyResolverImpl implements DependencyResolver,
             throw new JmxAttributeValidationException(message, jmxAttribute);
         }
         try {
-            T result = expectedType.cast(instance);
-            return result;
+            return expectedType.cast(instance);
         } catch (ClassCastException e) {
             String message = format(
                     "Instance cannot be cast to expected type. Instance class is %s , "
@@ -178,7 +177,7 @@ final class DependencyResolverImpl implements DependencyResolver,
         IdentityCodec<?> identityCodec = codecRegistry.getIdentityCodec();
         Class<? extends BaseIdentity> deserialized = identityCodec.deserialize(qName);
         if (deserialized == null) {
-            throw new RuntimeException("Unable to retrieve identity class for " + qName + ", null response from "
+            throw new IllegalStateException("Unable to retrieve identity class for " + qName + ", null response from "
                     + codecRegistry);
         }
         if (expectedBaseClass.isAssignableFrom(deserialized)) {
@@ -194,7 +193,7 @@ final class DependencyResolverImpl implements DependencyResolver,
     public <T extends BaseIdentity> void validateIdentity(IdentityAttributeRef identityRef, Class<T> expectedBaseClass, JmxAttribute jmxAttribute) {
         try {
             resolveIdentity(identityRef, expectedBaseClass);
-        } catch(Exception e) {
+        } catch (Exception e) {
             throw JmxAttributeValidationException.wrap(e, jmxAttribute);
         }
     }
@@ -215,7 +214,7 @@ final class DependencyResolverImpl implements DependencyResolver,
         return maxDependencyDepth;
     }
 
-    public void countMaxDependencyDepth(DependencyResolverManager manager) {
+    void countMaxDependencyDepth(DependencyResolverManager manager) {
         transactionStatus.checkCommitted();
         if (maxDependencyDepth == null) {
             maxDependencyDepth = getMaxDepth(this, manager,
@@ -224,8 +223,8 @@ final class DependencyResolverImpl implements DependencyResolver,
     }
 
     private static int getMaxDepth(DependencyResolverImpl impl,
-            DependencyResolverManager manager,
-            LinkedHashSet<ModuleIdentifier> chainForDetectingCycles) {
+                                   DependencyResolverManager manager,
+                                   LinkedHashSet<ModuleIdentifier> chainForDetectingCycles) {
         int maxDepth = 0;
         LinkedHashSet<ModuleIdentifier> chainForDetectingCycles2 = new LinkedHashSet<>(
                 chainForDetectingCycles);
@@ -258,4 +257,5 @@ final class DependencyResolverImpl implements DependencyResolver,
     public ModuleIdentifier getIdentifier() {
         return name;
     }
+
 }
index c115934..b99bf83 100644 (file)
@@ -7,45 +7,57 @@
  */
 package org.opendaylight.controller.config.manager.impl.dependencyresolver;
 
+import com.google.common.reflect.AbstractInvocationHandler;
+import com.google.common.reflect.Reflection;
 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.RuntimeBeanRegistratorAwareModule;
 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.DeadlockMonitor;
+import org.opendaylight.controller.config.manager.impl.ModuleInternalInfo;
+import org.opendaylight.controller.config.manager.impl.TransactionIdentifier;
 import org.opendaylight.controller.config.manager.impl.TransactionStatus;
+import org.opendaylight.controller.config.manager.impl.jmx.TransactionModuleJMXRegistrator.TransactionModuleJMXRegistration;
 import org.opendaylight.controller.config.spi.Module;
 import org.opendaylight.controller.config.spi.ModuleFactory;
 import org.opendaylight.yangtools.yang.data.impl.codec.CodecRegistry;
 
 import javax.annotation.concurrent.GuardedBy;
 import javax.management.InstanceAlreadyExistsException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import static com.google.common.base.Preconditions.checkState;
+
 /**
  * Holds information about modules being created and destroyed within this
  * transaction. Observes usage of DependencyResolver within modules to figure
  * out dependency tree.
  */
-public class DependencyResolverManager implements TransactionHolder, DependencyResolverFactory {
+public class DependencyResolverManager implements DependencyResolverFactory, AutoCloseable {
     @GuardedBy("this")
     private final Map<ModuleIdentifier, DependencyResolverImpl> moduleIdentifiersToDependencyResolverMap = new HashMap<>();
     private final ModulesHolder modulesHolder;
     private final TransactionStatus transactionStatus;
     private final ServiceReferenceReadableRegistry readableRegistry;
     private final CodecRegistry codecRegistry;
+    private final DeadlockMonitor deadlockMonitor;
 
-    public DependencyResolverManager(String transactionName,
+    public DependencyResolverManager(TransactionIdentifier transactionIdentifier,
                                      TransactionStatus transactionStatus, ServiceReferenceReadableRegistry readableRegistry, CodecRegistry codecRegistry) {
-        this.modulesHolder = new ModulesHolder(transactionName);
+        this.modulesHolder = new ModulesHolder(transactionIdentifier);
         this.transactionStatus = transactionStatus;
         this.readableRegistry = readableRegistry;
         this.codecRegistry = codecRegistry;
+        this.deadlockMonitor = new DeadlockMonitor(transactionIdentifier);
     }
 
     @Override
@@ -88,7 +100,6 @@ public class DependencyResolverManager implements TransactionHolder, DependencyR
         return result;
     }
 
-    @Override
     public ModuleInternalTransactionalInfo destroyModule(
             ModuleIdentifier moduleIdentifier) {
         transactionStatus.checkNotCommitted();
@@ -99,45 +110,85 @@ public class DependencyResolverManager implements TransactionHolder, DependencyR
     }
 
     // protect write access
-    @Override
+
     public void put(
-            ModuleInternalTransactionalInfo moduleInternalTransactionalInfo) {
+            final ModuleIdentifier moduleIdentifier,
+            final Module module,
+            ModuleFactory moduleFactory,
+            ModuleInternalInfo maybeOldInternalInfo,
+            TransactionModuleJMXRegistration transactionModuleJMXRegistration,
+            boolean isDefaultBean) {
         transactionStatus.checkNotCommitted();
+
+        Class<? extends Module> moduleClass = Module.class;
+        if (module instanceof RuntimeBeanRegistratorAwareModule) {
+            moduleClass = RuntimeBeanRegistratorAwareModule.class;
+        }
+        Module proxiedModule = Reflection.newProxy(moduleClass, new AbstractInvocationHandler() {
+            // optimization: subsequent calls to getInstance MUST return the same value during transaction,
+            // so it is safe to cache the response
+            private Object cachedInstance;
+
+            @Override
+            protected Object handleInvocation(Object proxy, Method method, Object[] args) throws Throwable {
+                boolean isGetInstance = method.getName().equals("getInstance");
+                if (isGetInstance) {
+                    if (cachedInstance != null) {
+                        return cachedInstance;
+                    }
+
+                    checkState(deadlockMonitor.isAlive(), "Deadlock monitor is not alive");
+                    deadlockMonitor.setCurrentlyInstantiatedModule(moduleIdentifier);
+                }
+                try {
+                    Object response = method.invoke(module, args);
+                    if (isGetInstance) {
+                        cachedInstance = response;
+                    }
+                    return response;
+                } catch(InvocationTargetException e) {
+                    throw e.getCause();
+                } finally {
+                    if (isGetInstance) {
+                        deadlockMonitor.setCurrentlyInstantiatedModule(null);
+                    }
+                }
+            }
+        });
+
+
+        ModuleInternalTransactionalInfo moduleInternalTransactionalInfo = new ModuleInternalTransactionalInfo(
+                moduleIdentifier, proxiedModule, moduleFactory,
+                maybeOldInternalInfo, transactionModuleJMXRegistration, isDefaultBean, module);
         modulesHolder.put(moduleInternalTransactionalInfo);
     }
 
     // wrapped methods:
 
-    @Override
     public CommitInfo toCommitInfo() {
         return modulesHolder.toCommitInfo();
     }
 
-    @Override
     public Module findModule(ModuleIdentifier moduleIdentifier,
-            JmxAttribute jmxAttributeForReporting) {
+                             JmxAttribute jmxAttributeForReporting) {
         return modulesHolder.findModule(moduleIdentifier,
                 jmxAttributeForReporting);
     }
 
-    @Override
     public ModuleInternalTransactionalInfo findModuleInternalTransactionalInfo(ModuleIdentifier moduleIdentifier) {
         return modulesHolder.findModuleInternalTransactionalInfo(moduleIdentifier);
     }
 
-    @Override
     public ModuleFactory findModuleFactory(ModuleIdentifier moduleIdentifier,
-            JmxAttribute jmxAttributeForReporting) {
+                                           JmxAttribute jmxAttributeForReporting) {
         return modulesHolder.findModuleFactory(moduleIdentifier,
                 jmxAttributeForReporting);
     }
 
-    @Override
     public Map<ModuleIdentifier, Module> getAllModules() {
         return modulesHolder.getAllModules();
     }
 
-    @Override
     public void assertNotExists(ModuleIdentifier moduleIdentifier)
             throws InstanceAlreadyExistsException {
         modulesHolder.assertNotExists(moduleIdentifier);
@@ -145,11 +196,16 @@ public class DependencyResolverManager implements TransactionHolder, DependencyR
 
     public List<ModuleIdentifier> findAllByFactory(ModuleFactory factory) {
         List<ModuleIdentifier> result = new ArrayList<>();
-        for( ModuleInternalTransactionalInfo  info : modulesHolder.getAllInfos()) {
+        for (ModuleInternalTransactionalInfo info : modulesHolder.getAllInfos()) {
             if (factory.equals(info.getModuleFactory())) {
                 result.add(info.getIdentifier());
             }
         }
         return result;
     }
+
+    public void close() {
+        deadlockMonitor.close();
+    }
+
 }
@@ -5,7 +5,7 @@
  * terms of the Eclipse 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;
+package org.opendaylight.controller.config.manager.impl.dependencyresolver;
 
 import org.opendaylight.controller.config.api.ModuleIdentifier;
 import org.opendaylight.controller.config.manager.impl.jmx.ModuleJMXRegistrator;
@@ -31,7 +31,7 @@ public class DestroyedModule implements AutoCloseable,
     private final OsgiRegistration osgiRegistration;
     private final int orderingIdx;
 
-    DestroyedModule(ModuleIdentifier identifier, AutoCloseable instance,
+    public DestroyedModule(ModuleIdentifier identifier, AutoCloseable instance,
             ModuleJMXRegistrator oldJMXRegistrator,
             OsgiRegistration osgiRegistration, int orderingIdx) {
         this.identifier = identifier;
@@ -5,38 +5,39 @@
  * terms of the Eclipse 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 javax.annotation.Nullable;
+package org.opendaylight.controller.config.manager.impl.dependencyresolver;
 
 import org.opendaylight.controller.config.api.ModuleIdentifier;
+import org.opendaylight.controller.config.manager.impl.ModuleInternalInfo;
 import org.opendaylight.controller.config.manager.impl.dynamicmbean.DynamicReadableWrapper;
-import org.opendaylight.controller.config.manager.impl.jmx.TransactionModuleJMXRegistrator
-        .TransactionModuleJMXRegistration;
+import org.opendaylight.controller.config.manager.impl.jmx.TransactionModuleJMXRegistrator.TransactionModuleJMXRegistration;
 import org.opendaylight.controller.config.spi.Module;
 import org.opendaylight.controller.config.spi.ModuleFactory;
 import org.opendaylight.yangtools.concepts.Identifiable;
 
+import javax.annotation.Nullable;
+
 public class ModuleInternalTransactionalInfo implements Identifiable<ModuleIdentifier> {
     private final ModuleIdentifier name;
-    private final Module module;
+    private final Module proxiedModule, realModule;
     private final ModuleFactory moduleFactory;
     @Nullable
     private final ModuleInternalInfo maybeOldInternalInfo;
     private final TransactionModuleJMXRegistration transactionModuleJMXRegistration;
     private final boolean isDefaultBean;
 
-    ModuleInternalTransactionalInfo(ModuleIdentifier name, Module module,
-            ModuleFactory moduleFactory,
-            ModuleInternalInfo maybeOldInternalInfo,
-            TransactionModuleJMXRegistration transactionModuleJMXRegistration,
-            boolean isDefaultBean) {
+    public ModuleInternalTransactionalInfo(ModuleIdentifier name, Module proxiedModule,
+                                           ModuleFactory moduleFactory,
+                                           ModuleInternalInfo maybeOldInternalInfo,
+                                           TransactionModuleJMXRegistration transactionModuleJMXRegistration,
+                                           boolean isDefaultBean, Module realModule) {
         this.name = name;
-        this.module = module;
+        this.proxiedModule = proxiedModule;
         this.moduleFactory = moduleFactory;
         this.maybeOldInternalInfo = maybeOldInternalInfo;
         this.transactionModuleJMXRegistration = transactionModuleJMXRegistration;
         this.isDefaultBean = isDefaultBean;
+        this.realModule = realModule;
     }
 
 
@@ -57,8 +58,8 @@ public class ModuleInternalTransactionalInfo implements Identifiable<ModuleIdent
     }
 
 
-    public Module getModule() {
-        return module;
+    public Module getProxiedModule() {
+        return proxiedModule;
     }
 
     public ModuleFactory getModuleFactory() {
@@ -67,8 +68,9 @@ public class ModuleInternalTransactionalInfo implements Identifiable<ModuleIdent
 
     @Nullable
     public ModuleInternalInfo getOldInternalInfo() {
-        if (maybeOldInternalInfo == null)
+        if (maybeOldInternalInfo == null) {
             throw new NullPointerException();
+        }
         return maybeOldInternalInfo;
     }
 
@@ -84,4 +86,8 @@ public class ModuleInternalTransactionalInfo implements Identifiable<ModuleIdent
     public boolean isDefaultBean() {
         return isDefaultBean;
     }
+
+    public Module getRealModule() {
+        return realModule;
+    }
 }
index 7c7d9f9..81cc34a 100644 (file)
@@ -11,8 +11,7 @@ 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.manager.impl.CommitInfo;
-import org.opendaylight.controller.config.manager.impl.DestroyedModule;
-import org.opendaylight.controller.config.manager.impl.ModuleInternalTransactionalInfo;
+import org.opendaylight.controller.config.manager.impl.TransactionIdentifier;
 import org.opendaylight.controller.config.spi.Module;
 import org.opendaylight.controller.config.spi.ModuleFactory;
 
@@ -30,19 +29,19 @@ import java.util.Set;
 /**
  * Represents modules to be committed.
  */
-class ModulesHolder implements TransactionHolder {
-    private final String transactionName;
+class ModulesHolder {
+    private final TransactionIdentifier transactionIdentifier;
     @GuardedBy("this")
     private final Map<ModuleIdentifier, ModuleInternalTransactionalInfo> commitMap = new HashMap<>();
 
     @GuardedBy("this")
     private final Set<ModuleInternalTransactionalInfo> unorderedDestroyedFromPreviousTransactions = new HashSet<>();
 
-    ModulesHolder(String transactionName) {
-        this.transactionName = transactionName;
+    ModulesHolder(TransactionIdentifier transactionIdentifier) {
+        this.transactionIdentifier = transactionIdentifier;
     }
 
-    @Override
+
     public CommitInfo toCommitInfo() {
         List<DestroyedModule> orderedDestroyedFromPreviousTransactions = new ArrayList<>(
                 unorderedDestroyedFromPreviousTransactions.size());
@@ -62,43 +61,38 @@ class ModulesHolder implements TransactionHolder {
                 .get(moduleIdentifier);
         JmxAttributeValidationException.checkNotNull(
                 moduleInternalTransactionalInfo, "Module " + moduleIdentifier
-                        + "" + " not found in transaction " + transactionName,
+                        + "" + " not found in transaction " + transactionIdentifier,
                 jmxAttributeForReporting);
         return moduleInternalTransactionalInfo;
     }
 
-    @Override
     public Module findModule(ModuleIdentifier moduleIdentifier,
             JmxAttribute jmxAttributeForReporting) {
         return findModuleInternalTransactionalInfo(moduleIdentifier,
-                jmxAttributeForReporting).getModule();
+                jmxAttributeForReporting).getProxiedModule();
     }
 
-    @Override
     public ModuleFactory findModuleFactory(ModuleIdentifier moduleIdentifier,
             JmxAttribute jmxAttributeForReporting) {
         return findModuleInternalTransactionalInfo(moduleIdentifier,
                 jmxAttributeForReporting).getModuleFactory();
     }
 
-    @Override
     public Map<ModuleIdentifier, Module> getAllModules() {
         Map<ModuleIdentifier, Module> result = new HashMap<>();
         for (ModuleInternalTransactionalInfo entry : commitMap.values()) {
             ModuleIdentifier name = entry.getIdentifier();
-            result.put(name, entry.getModule());
+            result.put(name, entry.getProxiedModule());
         }
         return result;
     }
 
-    @Override
     public void put(
             ModuleInternalTransactionalInfo moduleInternalTransactionalInfo) {
         commitMap.put(moduleInternalTransactionalInfo.getIdentifier(),
                 moduleInternalTransactionalInfo);
     }
 
-    @Override
     public ModuleInternalTransactionalInfo destroyModule(
             ModuleIdentifier moduleIdentifier) {
         ModuleInternalTransactionalInfo found = commitMap.remove(moduleIdentifier);
@@ -111,7 +105,6 @@ class ModulesHolder implements TransactionHolder {
         return found;
     }
 
-    @Override
     public void assertNotExists(ModuleIdentifier moduleIdentifier)
             throws InstanceAlreadyExistsException {
         if (commitMap.containsKey(moduleIdentifier)) {
@@ -124,7 +117,6 @@ class ModulesHolder implements TransactionHolder {
         return commitMap.values();
     }
 
-    @Override
     public ModuleInternalTransactionalInfo findModuleInternalTransactionalInfo(ModuleIdentifier moduleIdentifier) {
         ModuleInternalTransactionalInfo found = commitMap.get(moduleIdentifier);
         if (found == null) {
diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/dependencyresolver/TransactionHolder.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/dependencyresolver/TransactionHolder.java
deleted file mode 100644 (file)
index bccd453..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.config.manager.impl.dependencyresolver;
-
-import org.opendaylight.controller.config.api.JmxAttribute;
-import org.opendaylight.controller.config.api.ModuleIdentifier;
-import org.opendaylight.controller.config.manager.impl.CommitInfo;
-import org.opendaylight.controller.config.manager.impl.ModuleInternalTransactionalInfo;
-import org.opendaylight.controller.config.spi.Module;
-import org.opendaylight.controller.config.spi.ModuleFactory;
-
-import javax.management.InstanceAlreadyExistsException;
-import java.util.Map;
-
-interface TransactionHolder {
-    CommitInfo toCommitInfo();
-
-    Module findModule(ModuleIdentifier moduleIdentifier,
-            JmxAttribute jmxAttributeForReporting);
-
-    ModuleFactory findModuleFactory(ModuleIdentifier moduleIdentifier,
-            JmxAttribute jmxAttributeForReporting);
-
-    Map<ModuleIdentifier, Module> getAllModules();
-
-    void put(ModuleInternalTransactionalInfo moduleInternalTransactionalInfo);
-
-    ModuleInternalTransactionalInfo destroyModule(
-            ModuleIdentifier moduleIdentifier);
-
-    void assertNotExists(ModuleIdentifier moduleIdentifier)
-            throws InstanceAlreadyExistsException;
-
-    ModuleInternalTransactionalInfo findModuleInternalTransactionalInfo(ModuleIdentifier moduleIdentifier);
-
-}
index 6f0d1b2..7e48af1 100644 (file)
@@ -55,7 +55,6 @@ import static java.lang.String.format;
  * requests (getAttribute, setAttribute, invoke) into the actual instance, but
  * provides additional functionality - namely it disallows setting attribute on
  * a read only wrapper.
- *
  */
 abstract class AbstractDynamicWrapper implements DynamicMBeanModuleWrapper {
     private static final Logger logger = LoggerFactory
@@ -71,9 +70,9 @@ abstract class AbstractDynamicWrapper implements DynamicMBeanModuleWrapper {
     protected final MBeanServer internalServer;
 
     public AbstractDynamicWrapper(Module module, boolean writable,
-            ModuleIdentifier moduleIdentifier,
-            ObjectName thisWrapperObjectName, MBeanOperationInfo[] dOperations,
-            MBeanServer internalServer, MBeanServer configMBeanServer) {
+                                  ModuleIdentifier moduleIdentifier,
+                                  ObjectName thisWrapperObjectName, MBeanOperationInfo[] dOperations,
+                                  MBeanServer internalServer, MBeanServer configMBeanServer) {
 
         this.writable = writable;
         this.module = module;
@@ -98,10 +97,10 @@ abstract class AbstractDynamicWrapper implements DynamicMBeanModuleWrapper {
      * case unregister the module and remove listener.
      */
     private final NotificationListener registerActualModule(Module module,
-            final ObjectName thisWrapperObjectName,
-            final ObjectName objectNameInternal,
-            final MBeanServer internalServer,
-            final MBeanServer configMBeanServer) {
+                                                            final ObjectName thisWrapperObjectName,
+                                                            final ObjectName objectNameInternal,
+                                                            final MBeanServer internalServer,
+                                                            final MBeanServer configMBeanServer) {
 
         try {
             internalServer.registerMBean(module, objectNameInternal);
@@ -116,7 +115,7 @@ abstract class AbstractDynamicWrapper implements DynamicMBeanModuleWrapper {
             public void handleNotification(Notification n, Object handback) {
                 if (n instanceof MBeanServerNotification
                         && n.getType()
-                                .equals(MBeanServerNotification.UNREGISTRATION_NOTIFICATION)) {
+                        .equals(MBeanServerNotification.UNREGISTRATION_NOTIFICATION)) {
                     if (((MBeanServerNotification) n).getMBeanName().equals(
                             thisWrapperObjectName)) {
                         try {
@@ -142,8 +141,8 @@ abstract class AbstractDynamicWrapper implements DynamicMBeanModuleWrapper {
     }
 
     private static MBeanInfo generateMBeanInfo(String className, Module module,
-            Map<String, AttributeHolder> attributeHolderMap,
-            MBeanOperationInfo[] dOperations, Set<Class<?>> jmxInterfaces) {
+                                               Map<String, AttributeHolder> attributeHolderMap,
+                                               MBeanOperationInfo[] dOperations, Set<Class<?>> jmxInterfaces) {
 
         String dDescription = findDescription(module.getClass(), jmxInterfaces);
         MBeanConstructorInfo[] dConstructors = new MBeanConstructorInfo[0];
@@ -170,9 +169,9 @@ abstract class AbstractDynamicWrapper implements DynamicMBeanModuleWrapper {
     // inspect all exported interfaces ending with MXBean, extract getters &
     // setters into attribute holder
     private static Map<String, AttributeHolder> buildMBeanInfo(Module module,
-            boolean writable, ModuleIdentifier moduleIdentifier,
-            Set<Class<?>> jmxInterfaces, MBeanServer internalServer,
-            ObjectName internalObjectName) {
+                                                               boolean writable, ModuleIdentifier moduleIdentifier,
+                                                               Set<Class<?>> jmxInterfaces, MBeanServer internalServer,
+                                                               ObjectName internalObjectName) {
 
         // internal variables for describing MBean elements
         Set<Method> methods = new HashSet<>();
@@ -217,7 +216,7 @@ abstract class AbstractDynamicWrapper implements DynamicMBeanModuleWrapper {
                 }
                 AttributeHolder attributeHolder = new AttributeHolder(
                         attribName, module, attributeMap.get(attribName)
-                                .getType(), writable, ifc, description);
+                        .getType(), writable, ifc, description);
                 attributeHolderMap.put(attribName, attributeHolder);
             }
         }
@@ -257,7 +256,7 @@ abstract class AbstractDynamicWrapper implements DynamicMBeanModuleWrapper {
         }
 
 
-        if(isDependencyListAttr(attributeName, obj)) {
+        if (isDependencyListAttr(attributeName, obj)) {
             obj = fixDependencyListAttribute(obj);
         }
 
@@ -265,14 +264,16 @@ abstract class AbstractDynamicWrapper implements DynamicMBeanModuleWrapper {
     }
 
     private Object fixDependencyListAttribute(Object attribute) {
-        if(attribute.getClass().isArray() == false)
+        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)
+            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);
@@ -282,8 +283,9 @@ abstract class AbstractDynamicWrapper implements DynamicMBeanModuleWrapper {
     }
 
     private boolean isDependencyListAttr(String attributeName, Object attribute) {
-        if (attributeHolderMap.containsKey(attributeName) == false)
+        if (attributeHolderMap.containsKey(attributeName) == false) {
             return false;
+        }
 
         AttributeHolder attributeHolder = attributeHolderMap.get(attributeName);
 
@@ -294,15 +296,17 @@ abstract class AbstractDynamicWrapper implements DynamicMBeanModuleWrapper {
     }
 
     protected ObjectName fixObjectName(ObjectName on) {
-        if (!ObjectNameUtil.ON_DOMAIN.equals(on.getDomain()))
+        if (!ObjectNameUtil.ON_DOMAIN.equals(on.getDomain())) {
             throw new IllegalArgumentException("Wrong domain, expected "
                     + ObjectNameUtil.ON_DOMAIN + " setter on " + on);
+        }
         // if on contains transaction name, remove it
         String transactionName = ObjectNameUtil.getTransactionName(on);
-        if (transactionName != null)
+        if (transactionName != null) {
             return ObjectNameUtil.withoutTransactionName(on);
-        else
+        } else {
             return on;
+        }
     }
 
     @Override
index 64664f7..f3e1b4e 100644 (file)
@@ -7,15 +7,15 @@
  */
 package org.opendaylight.controller.config.manager.impl.dynamicmbean;
 
+import org.opendaylight.controller.config.api.annotations.Description;
+
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Set;
 
-import org.opendaylight.controller.config.api.annotations.Description;
-
-class AnnotationsHelper {
+public class AnnotationsHelper {
 
     /**
      * Look for annotation specified by annotationType on method. First observe
index 9dd6a22..044f7a9 100644 (file)
@@ -40,9 +40,9 @@ class AttributeHolder {
     }
 
     public AttributeHolder(String name, Object object, String returnType,
-            boolean writable,
-            @Nullable RequireInterface requireInterfaceAnnotation,
-            String description) {
+                           boolean writable,
+                           @Nullable RequireInterface requireInterfaceAnnotation,
+                           String description) {
         if (name == null) {
             throw new NullPointerException();
         }
@@ -65,7 +65,7 @@ class AttributeHolder {
 
     /**
      * @return annotation if setter sets ObjectName or ObjectName[], and is
-     *         annotated. Return null otherwise.
+     * annotated. Return null otherwise.
      */
     RequireInterface getRequireInterfaceOrNull() {
         return requireInterfaceAnnotation;
@@ -98,7 +98,7 @@ class AttributeHolder {
      * @param setter
      * @param jmxInterfaces
      * @return empty string if no annotation is found, or list of descriptions
-     *         separated by newline
+     * separated by newline
      */
     static String findDescription(Method setter, Set<Class<?>> jmxInterfaces) {
         List<Description> descriptions = AnnotationsHelper
@@ -112,21 +112,21 @@ class AttributeHolder {
      *
      * @param setter
      * @param inspectedInterfaces
-     * @throws IllegalStateException
-     *             if more than one value is specified by found annotations
-     * @throws IllegalArgumentException
-     *             if set of exported interfaces contains non interface type
      * @return null if no annotation is found, otherwise return the annotation
+     * @throws IllegalStateException    if more than one value is specified by found annotations
+     * @throws IllegalArgumentException if set of exported interfaces contains non interface type
      */
     static RequireInterface findRequireInterfaceAnnotation(final Method setter,
-            Set<Class<?>> inspectedInterfaces) {
+                                                           Set<Class<?>> inspectedInterfaces) {
 
         // only allow setX(ObjectName y) or setX(ObjectName[] y) or setX(List<ObjectName> y) to continue
 
-        if (setter.getParameterTypes().length > 1)
+        if (setter.getParameterTypes().length > 1) {
             return null;
-        if(PERMITTED_PARAMETER_TYPES_FOR_DEPENDENCY_SETTER.contains(setter.getParameterTypes()[0]) == false)
+        }
+        if (PERMITTED_PARAMETER_TYPES_FOR_DEPENDENCY_SETTER.contains(setter.getParameterTypes()[0]) == false) {
             return null;
+        }
 
         List<RequireInterface> foundRequireInterfaces = AnnotationsHelper
                 .findMethodAnnotationInSuperClassesAndIfcs(setter, RequireInterface.class, inspectedInterfaces);
index 2ab04e5..335acc8 100644 (file)
@@ -164,8 +164,9 @@ public class DynamicWritableWrapper extends AbstractDynamicWrapper {
             try {
                 validate();
             } catch (Exception e) {
-                throw ValidationException.createForSingleException(
-                        moduleIdentifier, e);
+
+                throw new MBeanException(ValidationException.createForSingleException(
+                        moduleIdentifier, e));
             }
             return Void.TYPE;
         }
index 16f7cf0..adc8168 100644 (file)
@@ -10,25 +10,21 @@ package org.opendaylight.controller.config.manager.impl.factoriesresolver;
 
 import org.opendaylight.controller.config.spi.ModuleFactory;
 import org.osgi.framework.BundleContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
-import java.util.Map.Entry;
-import java.util.Set;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
-import java.util.Collections;
+import java.util.Map.Entry;
+import java.util.Set;
 import java.util.TreeSet;
-import java.util.Collection;
-import java.util.ArrayList;
 
 /**
  * Hold sorted ConfigMBeanFactories by their module names. Check that module
  * names are globally unique.
  */
 public class HierarchicalConfigMBeanFactoriesHolder {
-    private static final Logger logger = LoggerFactory
-            .getLogger(HierarchicalConfigMBeanFactoriesHolder.class);
 
     private final Map<String, Map.Entry<ModuleFactory, BundleContext>> moduleNamesToConfigBeanFactories;
     private final Set<String> moduleNames;
index 5d77156..98f0908 100644 (file)
@@ -7,22 +7,24 @@
  */
 package org.opendaylight.controller.config.manager.impl.jmx;
 
-import java.io.Closeable;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import javax.annotation.concurrent.GuardedBy;
 import javax.management.InstanceAlreadyExistsException;
+import javax.management.InstanceNotFoundException;
 import javax.management.JMX;
+import javax.management.MBeanRegistrationException;
 import javax.management.MBeanServer;
+import javax.management.NotCompliantMBeanException;
 import javax.management.ObjectName;
 import javax.management.QueryExp;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import java.io.Closeable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
 
 public class InternalJMXRegistrator implements Closeable {
     private static final Logger logger = LoggerFactory
@@ -38,7 +40,7 @@ public class InternalJMXRegistrator implements Closeable {
         private final ObjectName on;
 
         InternalJMXRegistration(InternalJMXRegistrator internalJMXRegistrator,
-                ObjectName on) {
+                                ObjectName on) {
             this.internalJMXRegistrator = internalJMXRegistrator;
             this.on = on;
         }
@@ -54,13 +56,11 @@ public class InternalJMXRegistrator implements Closeable {
     private final List<InternalJMXRegistrator> children = new ArrayList<>();
 
     public synchronized InternalJMXRegistration registerMBean(Object object,
-            ObjectName on) throws InstanceAlreadyExistsException {
+                                                              ObjectName on) throws InstanceAlreadyExistsException {
         try {
             configMBeanServer.registerMBean(object, on);
-        } catch (InstanceAlreadyExistsException e) {
-            throw e;
-        } catch (Exception e) {
-            throw new RuntimeException(e);
+        } catch (MBeanRegistrationException | NotCompliantMBeanException e) {
+            throw new IllegalStateException(e);
         }
         registeredObjectNames.add(on);
         return new InternalJMXRegistration(this, on);
@@ -69,14 +69,13 @@ public class InternalJMXRegistrator implements Closeable {
     private synchronized void unregisterMBean(ObjectName on) {
         // first check that on was registered using this instance
         boolean removed = registeredObjectNames.remove(on);
-        if (!removed)
-            throw new IllegalStateException(
-                    "Cannot unregister - ObjectName not found in 'registeredObjectNames': "
-                            + on);
+        if (!removed) {
+            throw new IllegalStateException("Cannot unregister - ObjectName not found in 'registeredObjectNames': " + on);
+        }
         try {
             configMBeanServer.unregisterMBean(on);
-        } catch (Exception e) {
-            throw new RuntimeException(e);
+        } catch (InstanceNotFoundException | MBeanRegistrationException e) {
+            throw new IllegalStateException(e);
         }
     }
 
@@ -112,7 +111,7 @@ public class InternalJMXRegistrator implements Closeable {
     }
 
     public <T> T newMBeanProxy(ObjectName objectName, Class<T> interfaceClass,
-            boolean notificationBroadcaster) {
+                               boolean notificationBroadcaster) {
         return JMX.newMBeanProxy(configMBeanServer, objectName, interfaceClass,
                 notificationBroadcaster);
     }
@@ -123,7 +122,7 @@ public class InternalJMXRegistrator implements Closeable {
     }
 
     public <T> T newMXBeanProxy(ObjectName objectName, Class<T> interfaceClass,
-            boolean notificationBroadcaster) {
+                                boolean notificationBroadcaster) {
         return JMX.newMXBeanProxy(configMBeanServer, objectName,
                 interfaceClass, notificationBroadcaster);
     }
index 849f752..cd74ddf 100644 (file)
@@ -25,13 +25,21 @@ public class ServiceReference {
 
     @Override
     public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
+        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;
+        if (!refName.equals(that.refName)) {
+            return false;
+        }
+        if (!serviceInterfaceName.equals(that.serviceInterfaceName)) {
+            return false;
+        }
 
         return true;
     }
index b371c3f..6fd2a2f 100644 (file)
@@ -7,15 +7,14 @@
  */
 package org.opendaylight.controller.config.manager.impl.jmx;
 
-import java.io.Closeable;
-import java.util.Set;
+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;
 import javax.management.QueryExp;
-
-import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
-import org.opendaylight.controller.config.manager.impl.jmx.InternalJMXRegistrator.InternalJMXRegistration;
+import java.io.Closeable;
+import java.util.Set;
 
 /**
  * Contains constraints on passed {@link ObjectName} parameters. Only allow (un)
@@ -26,7 +25,7 @@ public class TransactionJMXRegistrator implements Closeable {
     private final String transactionName;
 
     TransactionJMXRegistrator(InternalJMXRegistrator internalJMXRegistrator,
-            String transactionName) {
+                              String transactionName) {
         this.childJMXRegistrator = internalJMXRegistrator.createChild();
         this.transactionName = transactionName;
     }
@@ -46,10 +45,11 @@ public class TransactionJMXRegistrator implements Closeable {
 
     public TransactionJMXRegistration registerMBean(Object object, ObjectName on)
             throws InstanceAlreadyExistsException {
-        if (!transactionName.equals(ObjectNameUtil.getTransactionName(on)))
+        if (!transactionName.equals(ObjectNameUtil.getTransactionName(on))) {
             throw new IllegalArgumentException(
                     "Transaction name mismatch between expected "
                             + transactionName + " " + "and " + on);
+        }
         ObjectNameUtil.checkType(on, ObjectNameUtil.TYPE_CONFIG_TRANSACTION);
         return new TransactionJMXRegistration(
                 childJMXRegistrator.registerMBean(object, on));
index b973b92..720b719 100644 (file)
@@ -8,6 +8,7 @@
 package org.opendaylight.controller.config.manager.impl.osgi;
 
 import org.opendaylight.controller.config.api.ConflictingVersionException;
+import org.opendaylight.controller.config.api.ValidationException;
 import org.opendaylight.controller.config.api.jmx.CommitStatus;
 import org.opendaylight.controller.config.manager.impl.ConfigRegistryImpl;
 import org.opendaylight.controller.config.spi.ModuleFactory;
@@ -41,7 +42,8 @@ public class BlankTransactionServiceTracker implements ServiceTrackerCustomizer<
     synchronized void blankTransaction() {
         // race condition check: config-persister might push new configuration while server is starting up.
         ConflictingVersionException lastException = null;
-        for (int i = 0; i < 10; i++) {
+        int maxAttempts = 10;
+        for (int i = 0; i < maxAttempts; i++) {
             try {
                 // create transaction
                 boolean blankTransaction = true;
@@ -57,9 +59,13 @@ public class BlankTransactionServiceTracker implements ServiceTrackerCustomizer<
                     Thread.currentThread().interrupt();
                     throw new IllegalStateException(interruptedException);
                 }
+            } catch (ValidationException e) {
+                logger.error("Validation exception while running blank transaction indicates programming error", e);
+                throw new RuntimeException("Validation exception while running blank transaction indicates programming error", e);
             }
         }
-        throw lastException;
+        throw new RuntimeException("Maximal number of attempts reached and still cannot get optimistic lock from " +
+                "config manager",lastException);
     }
 
     @Override
index 2a533ab..1e94e5e 100644 (file)
@@ -53,7 +53,7 @@ public class BundleContextBackedModuleFactoriesResolver implements
             if(factory == null) {
                 throw new NullPointerException("ServiceReference of class" + serviceReference.getClass() + "not found.");
             }
-            StringBuffer errors = new StringBuffer();
+
             String moduleName = factory.getImplementationName();
             if (moduleName == null || moduleName.isEmpty()) {
                 throw new IllegalStateException(
@@ -63,23 +63,17 @@ public class BundleContextBackedModuleFactoriesResolver implements
                 throw new NullPointerException("Bundle context of " + factory + " ModuleFactory not found.");
             }
             logger.debug("Reading factory {} {}", moduleName, factory);
-            String error = null;
+
             Map.Entry<ModuleFactory, BundleContext> conflicting = result.get(moduleName);
             if (conflicting != null) {
-                error = String
-                        .format("Module name is not unique. Found two conflicting factories with same name '%s': " +
-                                "\n\t%s\n\t%s\n", moduleName, conflicting.getKey(), factory);
-
-            }
-
-            if (error == null) {
+                String error = String
+                        .format("Module name is not unique. Found two conflicting factories with same name '%s': '%s' '%s'",
+                                moduleName, conflicting.getKey(), factory);
+                logger.error(error);
+                throw new IllegalArgumentException(error);
+            } else {
                 result.put(moduleName, new AbstractMap.SimpleImmutableEntry<>(factory,
                         serviceReference.getBundle().getBundleContext()));
-            } else {
-                errors.append(error);
-            }
-            if (errors.length() > 0) {
-                throw new IllegalArgumentException(errors.toString());
             }
         }
         return result;
index d464cb9..02cc5ea 100644 (file)
@@ -41,7 +41,7 @@ public class ConfigManagerActivator implements BundleActivator {
     private RuntimeGeneratedMappingServiceActivator mappingServiceActivator;
 
     @Override
-    public void start(BundleContext context) throws Exception {
+    public void start(BundleContext context) {
 
         // track bundles containing YangModuleInfo
         ModuleInfoBundleTracker moduleInfoBundleTracker = new ModuleInfoBundleTracker();
@@ -72,7 +72,7 @@ public class ConfigManagerActivator implements BundleActivator {
         try {
             configRegistryJMXRegistrator.registerToJMX(configRegistry);
         } catch (InstanceAlreadyExistsException e) {
-            throw new RuntimeException("Config Registry was already registered to JMX", e);
+            throw new IllegalStateException("Config Registry was already registered to JMX", e);
         }
 
         ServiceTracker<ModuleFactory, Object> serviceTracker = new ServiceTracker<>(context, ModuleFactory.class,
@@ -81,7 +81,7 @@ public class ConfigManagerActivator implements BundleActivator {
     }
 
     @Override
-    public void stop(BundleContext context) throws Exception {
+    public void stop(BundleContext context) {
         try {
             configRegistry.close();
         } catch (Exception e) {
index 8ba290f..a8fdfda 100644 (file)
@@ -20,7 +20,6 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.io.InputStream;
-import java.lang.reflect.InvocationTargetException;
 import java.net.URL;
 import java.util.Collection;
 import java.util.LinkedList;
@@ -98,31 +97,26 @@ public final class ModuleInfoBundleTracker implements BundleTrackerCustomizer<Co
             errorMessage = logMessage("Class {} does not implement {} in bundle {}", clazz, YangModelBindingProvider.class, bundle);
             throw new IllegalStateException(errorMessage);
         }
-
+        YangModelBindingProvider instance;
         try {
-            Object instance = clazz.newInstance();
-            Object result = clazz.getMethod(GET_MODULE_INFO_METHOD).invoke(instance);
-
-            if (YangModuleInfo.class.isAssignableFrom(result.getClass()) == false) {
-                errorMessage = logMessage("Error invoking method not found {} in bundle {}, reason {}",
-                        GET_MODULE_INFO_METHOD, bundle, "Not assignable from " + YangModuleInfo.class);
-            } else {
-                return (YangModuleInfo) result;
-            }
-
+            Object instanceObj = clazz.newInstance();
+            instance = YangModelBindingProvider.class.cast(instanceObj);
         } catch (InstantiationException e) {
             errorMessage = logMessage("Could not instantiate {} in bundle {}, reason {}", moduleInfoClass, bundle, e);
+            throw new IllegalStateException(errorMessage, e);
         } catch (IllegalAccessException e) {
             errorMessage = logMessage("Illegal access during instatiation of class {} in bundle {}, reason {}",
                     moduleInfoClass, bundle, e);
-        } catch (NoSuchMethodException e) {
-            errorMessage = logMessage("Method not found {} in bundle {}, reason {}", GET_MODULE_INFO_METHOD, bundle, e);
-        } catch (InvocationTargetException e) {
-            errorMessage = logMessage("Error invoking method {} in bundle {}, reason {}", GET_MODULE_INFO_METHOD,
-                    bundle, e);
+            throw new IllegalStateException(errorMessage, e);
         }
+        try{
+            return instance.getModuleInfo();
+        } catch (NoClassDefFoundError e) {
 
-        throw new IllegalStateException(errorMessage);
+
+            logger.error("Error while executing getModuleInfo on {}", instance, e);
+            throw e;
+        }
     }
 
     private static Class<?> loadClass(String moduleInfoClass, Bundle bundle) {
index 63a66e9..123e52f 100644 (file)
@@ -7,24 +7,27 @@
  */
 package org.opendaylight.controller.config.manager.impl.dependencyresolver;
 
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.reset;
-
-import java.util.Arrays;
-import java.util.List;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.opendaylight.controller.config.api.JmxAttribute;
 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.ModuleInternalInfo;
+import org.opendaylight.controller.config.manager.impl.TransactionIdentifier;
 import org.opendaylight.controller.config.manager.impl.TransactionStatus;
+import org.opendaylight.controller.config.manager.impl.jmx.TransactionModuleJMXRegistrator.TransactionModuleJMXRegistration;
 import org.opendaylight.controller.config.spi.Module;
+import org.opendaylight.controller.config.spi.ModuleFactory;
+
+import java.util.Arrays;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.reset;
 
 public class DependencyResolverManagerTest {
 
@@ -42,7 +45,7 @@ public class DependencyResolverManagerTest {
     public void setUp() {
         transactionStatus = mock(TransactionStatus.class);
         ServiceReferenceReadableRegistry mockedRegistry = mock(ServiceReferenceReadableRegistry.class);
-        tested = new DependencyResolverManager("txName", transactionStatus, mockedRegistry, null);
+        tested = new DependencyResolverManager(new TransactionIdentifier("txName"), transactionStatus, mockedRegistry, null);
         doNothing().when(transactionStatus).checkCommitStarted();
         doNothing().when(transactionStatus).checkNotCommitted();
     }
@@ -87,10 +90,18 @@ public class DependencyResolverManagerTest {
 
     private static void mockGetInstance(DependencyResolverManager tested,
             ModuleIdentifier moduleIdentifier) {
-        ModuleInternalTransactionalInfo mock = mock(ModuleInternalTransactionalInfo.class);
-        doReturn(moduleIdentifier).when(mock).getIdentifier();
-        doReturn(mockedModule()).when(mock).getModule();
-        tested.put(mock);
+
+        ModuleFactory moduleFactory = mock(ModuleFactory.class);
+        ModuleInternalInfo maybeOldInternalInfo = null;
+        TransactionModuleJMXRegistration transactionModuleJMXRegistration = null;
+        boolean isDefaultBean = false;
+
+        tested.put(moduleIdentifier,
+        mockedModule(),
+         moduleFactory,
+         maybeOldInternalInfo,
+         transactionModuleJMXRegistration,
+         isDefaultBean);
     }
 
     private static Module mockedModule() {
index f4ba5ef..df6dce1 100644 (file)
@@ -7,15 +7,7 @@
  */
 package org.opendaylight.controller.config.manager.testingservices.parallelapsp;
 
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkState;
-
-import java.io.Closeable;
-
-import javax.annotation.Nullable;
-import javax.annotation.concurrent.NotThreadSafe;
-import javax.management.ObjectName;
-
+import com.google.common.base.Strings;
 import org.opendaylight.controller.config.api.DependencyResolver;
 import org.opendaylight.controller.config.api.JmxAttribute;
 import org.opendaylight.controller.config.api.ModuleIdentifier;
@@ -26,7 +18,13 @@ import org.opendaylight.controller.config.spi.Module;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.base.Strings;
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.NotThreadSafe;
+import javax.management.ObjectName;
+import java.io.Closeable;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
 
 /**
  * Represents service that has dependency to thread pool.
index 441de36..28408ab 100644 (file)
@@ -30,7 +30,6 @@ import javax.management.InstanceNotFoundException;
 import javax.management.MBeanException;
 import javax.management.ObjectName;
 import javax.management.ReflectionException;
-import javax.management.RuntimeMBeanException;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
@@ -135,7 +134,7 @@ public class SimpleConfigurationTest extends AbstractConfigTest {
 
     private void testValidation(ConfigTransactionClient transaction)
             throws InstanceAlreadyExistsException, ReflectionException,
-            InstanceNotFoundException, MBeanException {
+            InstanceNotFoundException, MBeanException, ConflictingVersionException {
         ObjectName fixed1names = transaction.createModule(
                 TestingFixedThreadPoolModuleFactory.NAME, fixed1);
         // call validate on config bean
@@ -143,8 +142,8 @@ public class SimpleConfigurationTest extends AbstractConfigTest {
             platformMBeanServer.invoke(fixed1names, "validate", new Object[0],
                     new String[0]);
             fail();
-        } catch (RuntimeMBeanException e) {
-            RuntimeException targetException = e.getTargetException();
+        } catch (MBeanException e) {
+            Exception targetException = e.getTargetException();
             assertNotNull(targetException);
             assertEquals(ValidationException.class, targetException.getClass());
         }
@@ -327,7 +326,7 @@ public class SimpleConfigurationTest extends AbstractConfigTest {
     }
 
     @Test
-    public void testAbort() {
+    public void testAbort() throws InstanceAlreadyExistsException, ValidationException {
         ConfigTransactionJMXClient transaction = configRegistryClient
                 .createTransaction();
         assertEquals(1, configRegistryClient.getOpenConfigs().size());
@@ -337,14 +336,14 @@ public class SimpleConfigurationTest extends AbstractConfigTest {
             transaction.createModule(TestingFixedThreadPoolModuleFactory.NAME,
                     fixed1);
             fail();
-        } catch (Exception e) {
-            assertTrue(e.getCause() instanceof InstanceNotFoundException);
+        } catch (IllegalStateException e) {
+            assertEquals("Configuration was aborted", e.getMessage());
         }
         try {
             transaction.validateConfig();
             fail();
-        } catch (Exception e) {
-            assertTrue(e.getCause() instanceof InstanceNotFoundException);
+        } catch (IllegalStateException e) {
+            assertEquals("Configuration was aborted", e.getMessage());
         }
         assertEquals(0, configRegistryClient.getOpenConfigs().size());
     }
index 42c9105..7fb6224 100644 (file)
@@ -5,7 +5,7 @@
   <parent>
     <groupId>org.opendaylight.controller</groupId>
     <artifactId>config-subsystem</artifactId>
-    <version>0.2.4-SNAPSHOT</version>
+    <version>0.2.5-SNAPSHOT</version>
   </parent>
 
   <artifactId>config-module-archetype</artifactId>
index 403ee82..f800e36 100644 (file)
@@ -3,7 +3,7 @@
     <parent>
         <artifactId>config-subsystem</artifactId>
         <groupId>org.opendaylight.controller</groupId>
-        <version>0.2.4-SNAPSHOT</version>
+        <version>0.2.5-SNAPSHOT</version>
         <relativePath>..</relativePath>
     </parent>
     <artifactId>config-persister-api</artifactId>
index 919fd13..86b8c4d 100644 (file)
@@ -4,7 +4,7 @@
     <parent>
         <artifactId>config-subsystem</artifactId>
         <groupId>org.opendaylight.controller</groupId>
-        <version>0.2.4-SNAPSHOT</version>
+        <version>0.2.5-SNAPSHOT</version>
         <relativePath>..</relativePath>
     </parent>
     <artifactId>config-persister-directory-adapter</artifactId>
index 92f7e27..5e556c0 100644 (file)
@@ -4,7 +4,7 @@
     <parent>
         <artifactId>config-subsystem</artifactId>
         <groupId>org.opendaylight.controller</groupId>
-        <version>0.2.4-SNAPSHOT</version>
+        <version>0.2.5-SNAPSHOT</version>
         <relativePath>..</relativePath>
     </parent>
     <artifactId>config-persister-directory-autodetect-adapter</artifactId>
index 2c5d235..75188fe 100644 (file)
@@ -4,7 +4,7 @@
     <parent>
         <artifactId>config-subsystem</artifactId>
         <groupId>org.opendaylight.controller</groupId>
-        <version>0.2.4-SNAPSHOT</version>
+        <version>0.2.5-SNAPSHOT</version>
         <relativePath>..</relativePath>
     </parent>
     <artifactId>config-persister-directory-xml-adapter</artifactId>
index 4681b3b..a8ea93e 100644 (file)
@@ -4,7 +4,7 @@
     <parent>
         <artifactId>config-subsystem</artifactId>
         <groupId>org.opendaylight.controller</groupId>
-        <version>0.2.4-SNAPSHOT</version>
+        <version>0.2.5-SNAPSHOT</version>
         <relativePath>..</relativePath>
     </parent>
     <artifactId>config-persister-file-adapter</artifactId>
index 6fa496d..dd20795 100644 (file)
@@ -4,7 +4,7 @@
     <parent>
         <artifactId>config-subsystem</artifactId>
         <groupId>org.opendaylight.controller</groupId>
-        <version>0.2.4-SNAPSHOT</version>
+        <version>0.2.5-SNAPSHOT</version>
         <relativePath>..</relativePath>
     </parent>
     <artifactId>config-persister-file-xml-adapter</artifactId>
index 0bc1ef6..e382c33 100644 (file)
@@ -4,7 +4,7 @@
     <parent>
         <groupId>org.opendaylight.controller</groupId>
         <artifactId>config-subsystem</artifactId>
-        <version>0.2.4-SNAPSHOT</version>
+        <version>0.2.5-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <artifactId>config-plugin-parent</artifactId>
@@ -16,7 +16,6 @@
 
     <properties>
         <jmxGeneratorPath>${project.build.directory}/generated-sources/config</jmxGeneratorPath>
-        <config.version>0.2.4-SNAPSHOT</config.version>
     </properties>
 
     <build>
index 6a50ee8..9b866ef 100644 (file)
@@ -3,7 +3,7 @@
     <parent>
         <artifactId>config-subsystem</artifactId>
         <groupId>org.opendaylight.controller</groupId>
-        <version>0.2.4-SNAPSHOT</version>
+        <version>0.2.5-SNAPSHOT</version>
         <relativePath>..</relativePath>
     </parent>
     <artifactId>config-util</artifactId>
index 3583daf..4adc0d9 100644 (file)
@@ -7,24 +7,23 @@
  */
 package org.opendaylight.controller.config.util;
 
-import java.util.Map;
-import java.util.Set;
+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.ConfigRegistryMXBean;
+import org.opendaylight.controller.config.api.jmx.ConfigTransactionControllerMXBean;
+import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
 
 import javax.management.Attribute;
 import javax.management.InstanceAlreadyExistsException;
 import javax.management.InstanceNotFoundException;
 import javax.management.JMException;
 import javax.management.JMX;
+import javax.management.MBeanException;
 import javax.management.MBeanServer;
 import javax.management.ObjectName;
-import javax.management.RuntimeMBeanException;
-
-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.ConfigRegistryMXBean;
-import org.opendaylight.controller.config.api.jmx.ConfigTransactionControllerMXBean;
-import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
+import java.util.Map;
+import java.util.Set;
 
 public class ConfigTransactionJMXClient implements ConfigTransactionClient {
     private final ConfigRegistryMXBean configRegistryMXBeanProxy;
@@ -234,10 +233,15 @@ public class ConfigTransactionJMXClient implements ConfigTransactionClient {
             throws ValidationException {
         try {
             configMBeanServer.invoke(configBeanON, "validate", null, null);
+        } catch (MBeanException e) {
+            Exception targetException = e.getTargetException();
+            if (targetException instanceof ValidationException){
+                throw (ValidationException) targetException;
+            } else {
+                throw new RuntimeException(e);
+            }
         } catch (JMException e) {
             throw new RuntimeException(e);
-        } catch (RuntimeMBeanException e) {
-            throw e.getTargetException();
         }
     }
 
index 4e0cfaa..fbebda5 100644 (file)
@@ -5,7 +5,7 @@
     <parent>
         <groupId>org.opendaylight.controller</groupId>
         <artifactId>config-plugin-parent</artifactId>
-        <version>0.2.4-SNAPSHOT</version>
+        <version>0.2.5-SNAPSHOT</version>
         <relativePath>../config-plugin-parent</relativePath>
     </parent>
     <artifactId>logback-config</artifactId>
index eeb8289..e543f75 100644 (file)
@@ -7,24 +7,19 @@
  */
 package org.opendaylight.controller.config.yang.logback.config;
 
-import static org.junit.Assert.assertEquals;
-
-import java.io.File;
-import java.io.IOException;
-import java.lang.management.ManagementFactory;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.InstanceNotFoundException;
-import javax.management.JMX;
-import javax.management.MalformedObjectNameException;
-import javax.management.ObjectName;
-
+import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
+import ch.qos.logback.classic.joran.JoranConfigurator;
+import ch.qos.logback.classic.spi.ILoggingEvent;
+import ch.qos.logback.core.joran.spi.JoranException;
+import ch.qos.logback.core.rolling.FixedWindowRollingPolicy;
+import ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy;
+import com.google.common.collect.Lists;
 import org.apache.commons.io.FileUtils;
 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.ObjectNameUtil;
 import org.opendaylight.controller.config.manager.impl.AbstractConfigTest;
 import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
@@ -32,15 +27,19 @@ import org.opendaylight.controller.config.util.ConfigTransactionClient;
 import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
 import org.slf4j.LoggerFactory;
 
-import ch.qos.logback.classic.LoggerContext;
-import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
-import ch.qos.logback.classic.joran.JoranConfigurator;
-import ch.qos.logback.classic.spi.ILoggingEvent;
-import ch.qos.logback.core.joran.spi.JoranException;
-import ch.qos.logback.core.rolling.FixedWindowRollingPolicy;
-import ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy;
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.InstanceNotFoundException;
+import javax.management.JMX;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+import java.io.File;
+import java.io.IOException;
+import java.lang.management.ManagementFactory;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
 
-import com.google.common.collect.Lists;
+import static org.junit.Assert.assertEquals;
 
 public class LogbackModuleWithInitialConfigurationTest extends AbstractConfigTest {
 
@@ -145,7 +144,7 @@ public class LogbackModuleWithInitialConfigurationTest extends AbstractConfigTes
     }
 
     public ObjectName createBeans() throws JoranException, InstanceAlreadyExistsException, IOException,
-            MalformedObjectNameException, InstanceNotFoundException {
+            MalformedObjectNameException, InstanceNotFoundException, ValidationException, ConflictingVersionException {
 
         LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
 
index 8718f8a..8149659 100644 (file)
@@ -7,32 +7,31 @@
  */
 package org.opendaylight.controller.config.yang.logback.config;
 
-import static org.junit.Assert.assertEquals;
-
-import java.io.File;
-import java.io.IOException;
-import java.lang.management.ManagementFactory;
-import java.util.List;
-
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.InstanceNotFoundException;
-import javax.management.JMX;
-import javax.management.MalformedObjectNameException;
-import javax.management.ObjectName;
-
+import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.classic.joran.JoranConfigurator;
+import ch.qos.logback.core.joran.spi.JoranException;
+import com.google.common.collect.Lists;
 import org.apache.commons.io.FileUtils;
 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.manager.impl.AbstractConfigTest;
 import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
 import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
 import org.slf4j.LoggerFactory;
 
-import ch.qos.logback.classic.LoggerContext;
-import ch.qos.logback.classic.joran.JoranConfigurator;
-import ch.qos.logback.core.joran.spi.JoranException;
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.InstanceNotFoundException;
+import javax.management.JMX;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+import java.io.File;
+import java.io.IOException;
+import java.lang.management.ManagementFactory;
+import java.util.List;
 
-import com.google.common.collect.Lists;
+import static org.junit.Assert.assertEquals;
 
 public class LogbackWithXmlConfigModuleTest extends AbstractConfigTest {
 
@@ -61,7 +60,7 @@ public class LogbackWithXmlConfigModuleTest extends AbstractConfigTest {
      * @throws MalformedObjectNameException
      */
     @Test
-    public void test() throws InstanceAlreadyExistsException, InstanceNotFoundException, MalformedObjectNameException {
+    public void test() throws InstanceAlreadyExistsException, InstanceNotFoundException, MalformedObjectNameException, ValidationException, ConflictingVersionException {
 
         ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
         ObjectName nameRetrieved = transaction.lookupConfigBean(factory.getImplementationName(), LogbackModuleFactory.INSTANCE_NAME);
@@ -106,7 +105,7 @@ public class LogbackWithXmlConfigModuleTest extends AbstractConfigTest {
      */
     @Test
     public void testAddNewLogger() throws InstanceAlreadyExistsException, InstanceNotFoundException,
-            MalformedObjectNameException {
+            MalformedObjectNameException, ValidationException, ConflictingVersionException {
 
         ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
         ObjectName nameRetrieved = transaction.lookupConfigBean(factory.getImplementationName(), LogbackModuleFactory.INSTANCE_NAME);
index fd099b3..2a53e44 100644 (file)
@@ -4,7 +4,7 @@
   <parent>
     <groupId>org.opendaylight.controller</groupId>
         <artifactId>config-plugin-parent</artifactId>
-        <version>0.2.4-SNAPSHOT</version>
+        <version>0.2.5-SNAPSHOT</version>
         <relativePath>../config-plugin-parent</relativePath>
   </parent>
   <modelVersion>4.0.0</modelVersion>
index 88afa13..452c5ac 100644 (file)
@@ -4,7 +4,7 @@
    <parent>
       <groupId>org.opendaylight.controller</groupId>
         <artifactId>config-plugin-parent</artifactId>
-        <version>0.2.4-SNAPSHOT</version>
+        <version>0.2.5-SNAPSHOT</version>
         <relativePath>../config-plugin-parent</relativePath>
    </parent>
    <modelVersion>4.0.0</modelVersion>
diff --git a/opendaylight/config/netty-event-executor-config/src/main/java/org/opendaylight/controller/config/yang/netty/eventexecutor/AutoCloseableEventExecutor.java b/opendaylight/config/netty-event-executor-config/src/main/java/org/opendaylight/controller/config/yang/netty/eventexecutor/AutoCloseableEventExecutor.java
new file mode 100644 (file)
index 0000000..69ea51f
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * 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.netty.eventexecutor;
+
+import com.google.common.reflect.AbstractInvocationHandler;
+import com.google.common.reflect.Reflection;
+import io.netty.util.concurrent.EventExecutor;
+
+import java.lang.reflect.Method;
+import java.util.concurrent.TimeUnit;
+
+public interface AutoCloseableEventExecutor extends EventExecutor, AutoCloseable {
+
+
+    public static class CloseableEventExecutorMixin implements AutoCloseable {
+        public static final int DEFAULT_SHUTDOWN_SECONDS = 1;
+        private final EventExecutor eventExecutor;
+
+        public CloseableEventExecutorMixin(EventExecutor eventExecutor) {
+            this.eventExecutor = eventExecutor;
+        }
+
+        @Override
+        public void close() {
+            eventExecutor.shutdownGracefully(0, DEFAULT_SHUTDOWN_SECONDS, TimeUnit.SECONDS);
+        }
+
+
+        public static AutoCloseable createCloseableProxy(final EventExecutor eventExecutor) {
+            final CloseableEventExecutorMixin closeableGlobalEventExecutorMixin =
+                    new CloseableEventExecutorMixin(eventExecutor);
+            return Reflection.newProxy(AutoCloseableEventExecutor.class, new AbstractInvocationHandler() {
+                @Override
+                protected Object handleInvocation(Object proxy, Method method, Object[] args) throws Throwable {
+                    if (method.getName().equals("close")) {
+                        closeableGlobalEventExecutorMixin.close();
+                        return null;
+                    } else {
+                        return method.invoke(eventExecutor, args);
+                    }
+                }
+            });
+        }
+
+
+    }
+}
\ No newline at end of file
index 2c4c211..8751a80 100644 (file)
  */
 package org.opendaylight.controller.config.yang.netty.eventexecutor;
 
-import com.google.common.reflect.AbstractInvocationHandler;
-import com.google.common.reflect.Reflection;
 import io.netty.util.concurrent.EventExecutor;
 import io.netty.util.concurrent.GlobalEventExecutor;
-
-import java.lang.reflect.Method;
-import java.util.concurrent.TimeUnit;
+import org.opendaylight.controller.config.yang.netty.eventexecutor.AutoCloseableEventExecutor.CloseableEventExecutorMixin;
 
 public final class GlobalEventExecutorModule extends
         org.opendaylight.controller.config.yang.netty.eventexecutor.AbstractGlobalEventExecutorModule {
@@ -46,35 +42,10 @@ public final class GlobalEventExecutorModule extends
 
     @Override
     public java.lang.AutoCloseable createInstance() {
-        final CloseableGlobalEventExecutorMixin closeableGlobalEventExecutorMixin =
-                new CloseableGlobalEventExecutorMixin(GlobalEventExecutor.INSTANCE);
-        return Reflection.newProxy(AutoCloseableEventExecutor.class, new AbstractInvocationHandler() {
-            @Override
-            protected Object handleInvocation(Object proxy, Method method, Object[] args) throws Throwable {
-                if (method.getName().equals("close")) {
-                    closeableGlobalEventExecutorMixin.close();
-                    return null;
-                } else {
-                    return method.invoke(GlobalEventExecutor.INSTANCE, args);
-                }
-            }
-        });
+        EventExecutor eventExecutor = GlobalEventExecutor.INSTANCE;
+        return CloseableEventExecutorMixin.createCloseableProxy(eventExecutor);
     }
 
-    public static interface AutoCloseableEventExecutor extends EventExecutor, AutoCloseable {
-
-    }
 
-    public static class CloseableGlobalEventExecutorMixin implements AutoCloseable {
-        private final GlobalEventExecutor eventExecutor;
 
-        public CloseableGlobalEventExecutorMixin(GlobalEventExecutor eventExecutor) {
-            this.eventExecutor = eventExecutor;
-        }
-
-        @Override
-        public void close() {
-            eventExecutor.shutdownGracefully(0, 1, TimeUnit.SECONDS);
-        }
-    }
 }
diff --git a/opendaylight/config/netty-event-executor-config/src/main/java/org/opendaylight/controller/config/yang/netty/eventexecutor/ImmediateEventExecutorModule.java b/opendaylight/config/netty-event-executor-config/src/main/java/org/opendaylight/controller/config/yang/netty/eventexecutor/ImmediateEventExecutorModule.java
new file mode 100644 (file)
index 0000000..27ca63f
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * 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.netty.eventexecutor;
+
+import io.netty.util.concurrent.EventExecutor;
+import io.netty.util.concurrent.ImmediateEventExecutor;
+import org.opendaylight.controller.config.yang.netty.eventexecutor.AutoCloseableEventExecutor.CloseableEventExecutorMixin;
+
+public final class ImmediateEventExecutorModule extends org.opendaylight.controller.config.yang.netty.eventexecutor.AbstractImmediateEventExecutorModule {
+
+    public ImmediateEventExecutorModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+        super(identifier, dependencyResolver);
+    }
+
+    public ImmediateEventExecutorModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver,
+                                        ImmediateEventExecutorModule oldModule, java.lang.AutoCloseable oldInstance) {
+
+        super(identifier, dependencyResolver, oldModule, oldInstance);
+    }
+
+    @Override
+    protected void customValidation() {
+        // Add custom validation for module attributes here.
+    }
+
+    @Override
+    public java.lang.AutoCloseable createInstance() {
+        EventExecutor eventExecutor = ImmediateEventExecutor.INSTANCE;
+        return CloseableEventExecutorMixin.createCloseableProxy(eventExecutor);
+    }
+}
diff --git a/opendaylight/config/netty-event-executor-config/src/main/java/org/opendaylight/controller/config/yang/netty/eventexecutor/ImmediateEventExecutorModuleFactory.java b/opendaylight/config/netty-event-executor-config/src/main/java/org/opendaylight/controller/config/yang/netty/eventexecutor/ImmediateEventExecutorModuleFactory.java
new file mode 100644 (file)
index 0000000..b3ec67b
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * 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.netty.eventexecutor;
+
+import org.opendaylight.controller.config.api.DependencyResolver;
+import org.osgi.framework.BundleContext;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+public class ImmediateEventExecutorModuleFactory extends org.opendaylight.controller.config.yang.netty.eventexecutor.AbstractImmediateEventExecutorModuleFactory {
+    public static final String SINGLETON_NAME = "singleton";
+
+    @Override
+    public ImmediateEventExecutorModule instantiateModule(String instanceName, DependencyResolver dependencyResolver, ImmediateEventExecutorModule oldModule, AutoCloseable oldInstance, BundleContext bundleContext) {
+        checkArgument(SINGLETON_NAME.equals(instanceName), "Illegal instance name '" + instanceName + "', only allowed name is " + SINGLETON_NAME);
+        return super.instantiateModule(instanceName, dependencyResolver, oldModule, oldInstance, bundleContext);
+    }
+
+    @Override
+    public ImmediateEventExecutorModule instantiateModule(String instanceName, DependencyResolver dependencyResolver, BundleContext bundleContext) {
+        checkArgument(SINGLETON_NAME.equals(instanceName), "Illegal instance name '" + instanceName + "', only allowed name is " + SINGLETON_NAME);
+        return super.instantiateModule(instanceName, dependencyResolver, bundleContext);
+    }
+}
index e9d1da3..8d812ad 100644 (file)
@@ -36,7 +36,18 @@ module netty-event-executor {
     augment "/config:modules/config:module/config:configuration" {
         case netty-global-event-executor {
             when "/config:modules/config:module/config:type = 'netty-global-event-executor'";
+        }
+    }
 
+    identity netty-immediate-event-executor {
+        base config:module-type;
+        config:provided-service netty:netty-event-executor;
+        config:java-name-prefix ImmediateEventExecutor;
+    }
+
+    augment "/config:modules/config:module/config:configuration" {
+        case netty-immediate-event-executor {
+            when "/config:modules/config:module/config:type = 'netty-immediate-event-executor'";
         }
     }
 }
index 172fe7f..5414335 100644 (file)
@@ -5,7 +5,7 @@
     <parent>
         <groupId>org.opendaylight.controller</groupId>
         <artifactId>config-plugin-parent</artifactId>
-        <version>0.2.4-SNAPSHOT</version>
+        <version>0.2.5-SNAPSHOT</version>
         <relativePath>../config-plugin-parent</relativePath>
     </parent>
 
index 9d3b550..a056a1c 100644 (file)
@@ -4,7 +4,7 @@
    <parent>
       <groupId>org.opendaylight.controller</groupId>
         <artifactId>config-plugin-parent</artifactId>
-        <version>0.2.4-SNAPSHOT</version>
+        <version>0.2.5-SNAPSHOT</version>
         <relativePath>../config-plugin-parent</relativePath>
    </parent>
    <modelVersion>4.0.0</modelVersion>
index 3474740..4ec7e2f 100644 (file)
@@ -10,7 +10,7 @@
     </parent>
 
 
-    <version>0.2.4-SNAPSHOT</version>
+    <version>0.2.5-SNAPSHOT</version>
     <artifactId>config-subsystem</artifactId>
     <packaging>pom</packaging>
     <name>${project.artifactId}</name>
@@ -68,7 +68,6 @@
         <jacoco.version>0.6.2.201302030002</jacoco.version>
         <slf4j.version>1.7.2</slf4j.version>
         <salGeneratorPath>${project.build.directory}/generated-sources/sal</salGeneratorPath>
-        <config.version>0.2.4-SNAPSHOT</config.version>
     </properties>
 
     <dependencies>
index 99a88fe..1e14bc4 100644 (file)
@@ -3,7 +3,7 @@
     <parent>
         <artifactId>config-plugin-parent</artifactId>
         <groupId>org.opendaylight.controller</groupId>
-        <version>0.2.4-SNAPSHOT</version>
+        <version>0.2.5-SNAPSHOT</version>
         <relativePath>../config-plugin-parent</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>
index fa661b4..8cf164d 100644 (file)
@@ -3,7 +3,7 @@
     <parent>
         <artifactId>config-plugin-parent</artifactId>
         <groupId>org.opendaylight.controller</groupId>
-        <version>0.2.4-SNAPSHOT</version>
+        <version>0.2.5-SNAPSHOT</version>
         <relativePath>../config-plugin-parent</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>
index d1abe08..d4a3160 100644 (file)
@@ -11,6 +11,8 @@ import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
+import org.opendaylight.controller.config.api.ConflictingVersionException;
+import org.opendaylight.controller.config.api.ValidationException;
 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;
@@ -92,7 +94,7 @@ public class ShutdownTest extends AbstractConfigTest {
         shutdownViaRuntimeJMX(secret);
     }
 
-    private void setSecret(String secret) throws InstanceNotFoundException {
+    private void setSecret(String secret) throws InstanceNotFoundException, ValidationException, ConflictingVersionException {
         ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
         ObjectName on = transaction.lookupConfigBean(NAME, NAME);
         ShutdownModuleMXBean proxy = transaction.newMXBeanProxy(on, ShutdownModuleMXBean.class);
index 2f5e35c..7e45fa3 100644 (file)
@@ -4,7 +4,7 @@
    <parent>
       <groupId>org.opendaylight.controller</groupId>
         <artifactId>config-plugin-parent</artifactId>
-        <version>0.2.4-SNAPSHOT</version>
+        <version>0.2.5-SNAPSHOT</version>
         <relativePath>../config-plugin-parent</relativePath>
    </parent>
    <modelVersion>4.0.0</modelVersion>
index 08f1d55..fcedbd8 100644 (file)
@@ -4,7 +4,7 @@
    <parent>
       <groupId>org.opendaylight.controller</groupId>
         <artifactId>config-plugin-parent</artifactId>
-        <version>0.2.4-SNAPSHOT</version>
+        <version>0.2.5-SNAPSHOT</version>
         <relativePath>../config-plugin-parent</relativePath>
    </parent>
    <modelVersion>4.0.0</modelVersion>
index a0ef5c2..f081b7b 100644 (file)
@@ -4,7 +4,7 @@
     <parent>
         <artifactId>config-subsystem</artifactId>
         <groupId>org.opendaylight.controller</groupId>
-        <version>0.2.4-SNAPSHOT</version>
+        <version>0.2.5-SNAPSHOT</version>
     </parent>
 
     <artifactId>yang-jmx-generator-it</artifactId>
index f6d1c88..a8119b8 100644 (file)
@@ -3,7 +3,7 @@
     <parent>
         <artifactId>config-subsystem</artifactId>
         <groupId>org.opendaylight.controller</groupId>
-        <version>0.2.4-SNAPSHOT</version>
+        <version>0.2.5-SNAPSHOT</version>
         <relativePath>..</relativePath>
     </parent>
     <artifactId>yang-jmx-generator-plugin</artifactId>
index d6d3893..37d5e6b 100644 (file)
@@ -53,7 +53,7 @@ public class FtlFilePersister {
                         ftlFile.getFtlTempleteLocation());
                 try {
                     template.process(ftlFile, writer);
-                } catch (Throwable e) {
+                } catch (Exception e) {
                     throw new IllegalStateException(
                             "Template error while generating " + ftlFile, e);
                 }
index b6e89cb..92ce0fe 100644 (file)
@@ -4,7 +4,7 @@
     <parent>
         <artifactId>config-subsystem</artifactId>
         <groupId>org.opendaylight.controller</groupId>
-        <version>0.2.4-SNAPSHOT</version>
+        <version>0.2.5-SNAPSHOT</version>
     </parent>
 
     <artifactId>yang-jmx-generator</artifactId>
index 4a9d551..676c8ec 100644 (file)
@@ -195,16 +195,17 @@ final class ModuleMXBeanEntryBuilder {
                 boolean providedServiceWasSet = false;
                 for (UnknownSchemaNode unknownNode : id.getUnknownSchemaNodes()) {
                     // TODO: test this
-                    if (ConfigConstants.PROVIDED_SERVICE_EXTENSION_QNAME.equals(unknownNode.getNodeType())) {
-                        // no op: 0 or more provided identities are allowed
-                    } else if (ConfigConstants.JAVA_NAME_PREFIX_EXTENSION_QNAME.equals(unknownNode.getNodeType())) {
+                    boolean unknownNodeIsProvidedServiceExtension = ConfigConstants.PROVIDED_SERVICE_EXTENSION_QNAME.equals(unknownNode.getNodeType());
+                    // true => no op: 0 or more provided identities are allowed
+
+                    if (ConfigConstants.JAVA_NAME_PREFIX_EXTENSION_QNAME.equals(unknownNode.getNodeType())) {
                         // 0..1 allowed
                         checkState(
                                 providedServiceWasSet == false,
                                 format("More than one language extension %s is not allowed here: %s",
                                         ConfigConstants.JAVA_NAME_PREFIX_EXTENSION_QNAME, id));
                         providedServiceWasSet = true;
-                    } else {
+                    } else if (unknownNodeIsProvidedServiceExtension == false) {
                         throw new IllegalStateException("Unexpected language extension " + unknownNode.getNodeType());
                     }
                 }
index 84300cb..cbeb5c3 100644 (file)
@@ -25,7 +25,9 @@ import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
 import javax.management.openmbean.CompositeType;
 import javax.management.openmbean.OpenDataException;
 import javax.management.openmbean.OpenType;
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
@@ -208,22 +210,20 @@ public class TOAttribute extends AbstractAttribute implements TypedAttribute {
 
     @Override
     public CompositeType getOpenType() {
-        String description = getNullableDescription() == null ? getAttributeYangName()
-                : getNullableDescription();
-        final String[] itemNames = new String[yangNameToAttributeMap.keySet()
-                .size()];
-        String[] itemDescriptions = itemNames;
-        FunctionImpl functionImpl = new FunctionImpl(itemNames);
+        String description = getNullableDescription() == null ? getAttributeYangName() : getNullableDescription();
+
+        FunctionImpl functionImpl = new FunctionImpl();
         Map<String, AttributeIfc> jmxPropertiesToTypesMap = getJmxPropertiesToTypesMap();
         OpenType<?>[] itemTypes = Collections2.transform(
                 jmxPropertiesToTypesMap.entrySet(), functionImpl).toArray(
                 new OpenType<?>[] {});
+        String[] itemNames = functionImpl.getItemNames();
         try {
             // TODO add package name to create fully qualified name for this
             // type
             CompositeType compositeType = new CompositeType(
                     getUpperCaseCammelCase(), description, itemNames,
-                    itemDescriptions, itemTypes);
+                    itemNames, itemTypes);
             return compositeType;
         } catch (OpenDataException e) {
             throw new RuntimeException("Unable to create CompositeType for "
@@ -235,20 +235,20 @@ public class TOAttribute extends AbstractAttribute implements TypedAttribute {
         return packageName;
     }
 
-    private static final class FunctionImpl implements
-            Function<Entry<String, AttributeIfc>, OpenType<?>> {
-        private final String[] itemNames;
-        int i = 0;
+}
 
-        private FunctionImpl(String[] itemNames) {
-            this.itemNames = itemNames;
-        }
+class FunctionImpl implements
+        Function<Entry<String, AttributeIfc>, OpenType<?>> {
+    private final List<String> itemNames = new ArrayList<>();
 
-        @Override
-        public OpenType<?> apply(Entry<String, AttributeIfc> input) {
-            AttributeIfc innerType = input.getValue();
-            itemNames[i++] = input.getKey();
-            return innerType.getOpenType();
-        }
+    @Override
+    public OpenType<?> apply(Entry<String, AttributeIfc> input) {
+        AttributeIfc innerType = input.getValue();
+        itemNames.add(input.getKey());
+        return innerType.getOpenType();
+    }
+
+    public String[] getItemNames(){
+        return itemNames.toArray(new String[itemNames.size()]);
     }
 }
index b071025..dfd9adb 100644 (file)
@@ -3,7 +3,7 @@
     <parent>
         <artifactId>config-subsystem</artifactId>
         <groupId>org.opendaylight.controller</groupId>
-        <version>0.2.4-SNAPSHOT</version>
+        <version>0.2.5-SNAPSHOT</version>
         <relativePath>..</relativePath>
     </parent>
     <artifactId>yang-store-api</artifactId>
index c4ac830..8a88cd0 100644 (file)
@@ -3,7 +3,7 @@
     <parent>
         <artifactId>config-subsystem</artifactId>
         <groupId>org.opendaylight.controller</groupId>
-        <version>0.2.4-SNAPSHOT</version>
+        <version>0.2.5-SNAPSHOT</version>
         <relativePath>..</relativePath>
     </parent>
     <artifactId>yang-store-impl</artifactId>
index fe7358e..0b4fc8b 100644 (file)
@@ -3,7 +3,7 @@
     <parent>
         <groupId>org.opendaylight.controller</groupId>
         <artifactId>config-plugin-parent</artifactId>
-        <version>0.2.4-SNAPSHOT</version>
+        <version>0.2.5-SNAPSHOT</version>
         <relativePath>../config-plugin-parent</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>
index 9037ff0..6caee41 100644 (file)
@@ -5,7 +5,7 @@
     <parent>
         <groupId>org.opendaylight.controller</groupId>
         <artifactId>config-plugin-parent</artifactId>
-        <version>0.2.4-SNAPSHOT</version>
+        <version>0.2.5-SNAPSHOT</version>
         <relativePath>../config-plugin-parent</relativePath>
     </parent>
 
index b000f11..398bba9 100644 (file)
@@ -31,15 +31,16 @@ public final class IdentityTestModule extends org.opendaylight.controller.config
 
     @Override
     public java.lang.AutoCloseable createInstance() {
-        System.err.println(getAfi());
-        System.err.println(getAfiIdentity());
+        org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(getClass());
+        logger.info("Afi: {}", getAfi());
+        logger.info("Afi class: {}", getAfiIdentity());
 
-        getAfiIdentity();
         for (Identities identities : getIdentities()) {
-            identities.resolveAfi();
-            identities.resolveSafi();
+            logger.info("Identities Afi class: {}", identities.resolveAfi());
+            logger.info("Identities Safi class: {}", identities.resolveSafi());
+
         }
-        getIdentitiesContainer().resolveAfi();
+        logger.info("IdentityContainer Afi class: {}", getIdentitiesContainer().resolveAfi());
 
         return new AutoCloseable() {
             @Override
index a81159e..7fa0c10 100644 (file)
@@ -1,12 +1,13 @@
-        System.err.println(getAfi());
-        System.err.println(getAfiIdentity());
+        org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(getClass());
+        logger.info("Afi: {}", getAfi());
+        logger.info("Afi class: {}", getAfiIdentity());
 
-        getAfiIdentity();
         for (Identities identities : getIdentities()) {
-            identities.resolveAfi();
-            identities.resolveSafi();
+            logger.info("Identities Afi class: {}", identities.resolveAfi());
+            logger.info("Identities Safi class: {}", identities.resolveSafi());
+
         }
-        getIdentitiesContainer().resolveAfi();
+        logger.info("IdentityContainer Afi class: {}", getIdentitiesContainer().resolveAfi());
 
         return new AutoCloseable() {
             @Override
index 90e3b03..64f2c87 100755 (executable)
@@ -59,7 +59,7 @@ else
 fi
 
 function usage {
-    echo "Usage: $0 [-jmx] [-jmxport <num>] [-debug] [-debugsuspend] [-debugport <num>] [-start [<console port>]] [-stop] [-status] [-console] [-help] [<other args will automatically be used for the JVM>]"
+    echo "Usage: $0 [-jmx] [-jmxport <num>] [-debug] [-debugsuspend] [-debugport <num>] [-start [<console port>]] [-stop] [-status] [-console] [-help] [-agentpath:<path to lib>] [<other args will automatically be used for the JVM>]"
     exit 1
 }
 
@@ -83,6 +83,7 @@ statusdaemon=0
 consolestart=1
 dohelp=0
 extraJVMOpts=""
+agentPath=""
 unknown_option=0
 while true ; do
     case "$1" in
@@ -98,6 +99,7 @@ while true ; do
         -help) dohelp=1; shift;;
         -D*) extraJVMOpts="${extraJVMOpts} $1"; shift;;
         -X*) extraJVMOpts="${extraJVMOpts} $1"; shift;;
+        -agentpath:*) agentPath="$1"; shift;;
         "") break ;;
         *) echo "Unknown option $1"; unknown_option=1; shift ;;
     esac
@@ -209,6 +211,7 @@ if [ "${startdaemon}" -eq 1 ]; then
         exit -1
     fi
     $JAVA_HOME/bin/java ${extraJVMOpts} \
+        ${agentPath} \
         -Djava.io.tmpdir="${iotmpdir}/work/tmp" \
         -Dosgi.install.area="${bdir}" \
         -Dosgi.configuration.area="${confarea}/configuration" \
@@ -227,6 +230,7 @@ elif [ "${consolestart}" -eq 1 ]; then
         exit -1
     fi
     $JAVA_HOME/bin/java ${extraJVMOpts} \
+        ${agentPath} \
         -Djava.io.tmpdir="${iotmpdir}/work/tmp" \
         -Dosgi.install.area="${bdir}" \
         -Dosgi.configuration.area="${confarea}/configuration" \
index b94103f..bdbf7ac 100644 (file)
@@ -1121,7 +1121,10 @@ public class ForwardingRulesManager implements
             List<FlowEntryInstall> list = new ArrayList<FlowEntryInstall>(groupFlows.get(groupName));
             toBeRemoved = list.size();
             for (FlowEntryInstall entry : list) {
-                Status status = this.removeEntry(entry.getOriginal(), false);
+                // since this is the entry that was stored in groupFlows
+                // it is already validated and merged
+                // so can call removeEntryInternal directly
+                Status status = this.removeEntryInternal(entry, false);
                 if (status.isSuccess()) {
                     toBeRemoved -= 1;
                 } else {
index 84508ca..01d75ac 100644 (file)
@@ -8,10 +8,8 @@
 package org.opendaylight.controller.sal.compatibility.adsal;
 
 import java.math.BigInteger;
-import java.util.concurrent.Future;
 
 import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
-import org.opendaylight.controller.sal.common.util.Futures;
 import org.opendaylight.controller.sal.common.util.Rpcs;
 import org.opendaylight.controller.sal.compatibility.InventoryMapping;
 import org.opendaylight.controller.sal.compatibility.ToSalConversionsUtils;
@@ -37,6 +35,9 @@ import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+
 public class FlowServiceAdapter implements SalFlowService, IFlowProgrammerListener {
 
     private static final Logger LOG = LoggerFactory.getLogger(FlowServiceAdapter.class);
@@ -59,7 +60,7 @@ public class FlowServiceAdapter implements SalFlowService, IFlowProgrammerListen
     }
 
     @Override
-    public Future<RpcResult<AddFlowOutput>> addFlow(AddFlowInput input) {
+    public ListenableFuture<RpcResult<AddFlowOutput>> addFlow(AddFlowInput input) {
 
         Flow flow = ToSalConversionsUtils.toFlow(input, null);
         @SuppressWarnings("unchecked")
@@ -73,7 +74,7 @@ public class FlowServiceAdapter implements SalFlowService, IFlowProgrammerListen
     }
 
     @Override
-    public Future<RpcResult<RemoveFlowOutput>> removeFlow(RemoveFlowInput input) {
+    public ListenableFuture<RpcResult<RemoveFlowOutput>> removeFlow(RemoveFlowInput input) {
 
         Flow flow = ToSalConversionsUtils.toFlow(input, null);
         @SuppressWarnings("unchecked")
@@ -88,7 +89,7 @@ public class FlowServiceAdapter implements SalFlowService, IFlowProgrammerListen
     }
 
     @Override
-    public Future<RpcResult<UpdateFlowOutput>> updateFlow(UpdateFlowInput input) {
+    public ListenableFuture<RpcResult<UpdateFlowOutput>> updateFlow(UpdateFlowInput input) {
         @SuppressWarnings("unchecked")
         org.opendaylight.controller.sal.core.Node node = InventoryMapping.toAdNode((InstanceIdentifier<Node>) input
                 .getNode().getValue());
index 4bc23fe..c5cbeca 100644 (file)
@@ -13,7 +13,6 @@ import java.util.List;
 import java.util.concurrent.Future;
 
 import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
-import org.opendaylight.controller.sal.common.util.Futures;
 import org.opendaylight.controller.sal.common.util.Rpcs;
 import org.opendaylight.controller.sal.compatibility.FromSalConversionsUtils;
 import org.opendaylight.controller.sal.compatibility.InventoryMapping;
@@ -64,6 +63,9 @@ import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+
 public class FlowStatisticsAdapter implements OpendaylightFlowStatisticsService, IReadServiceListener{
 
     private static final Logger LOG = LoggerFactory.getLogger(FlowStatisticsAdapter.class);
@@ -73,7 +75,7 @@ public class FlowStatisticsAdapter implements OpendaylightFlowStatisticsService,
     @Override
     public Future<RpcResult<GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutput>> getAggregateFlowStatisticsFromFlowTableForAllFlows(
             GetAggregateFlowStatisticsFromFlowTableForAllFlowsInput input) {
-        //TODO: No supported API exist in AD-SAL, it can either be implemented by fetching all the stats of the flows and 
+        //TODO: No supported API exist in AD-SAL, it can either be implemented by fetching all the stats of the flows and
         // generating aggregate flow statistics out of those individual flow stats.
         return null;
     }
@@ -81,13 +83,13 @@ public class FlowStatisticsAdapter implements OpendaylightFlowStatisticsService,
     @Override
     public Future<RpcResult<GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput>> getAggregateFlowStatisticsFromFlowTableForGivenMatch(
             GetAggregateFlowStatisticsFromFlowTableForGivenMatchInput input) {
-        //TODO: No supported API exist in AD-SAL, it can either be implemented by fetching all the stats of the flows and 
+        //TODO: No supported API exist in AD-SAL, it can either be implemented by fetching all the stats of the flows and
         // generating aggregate flow statistics out of those individual flow stats.
         return null;
     }
 
     @Override
-    public Future<RpcResult<GetAllFlowStatisticsFromFlowTableOutput>> getAllFlowStatisticsFromFlowTable(
+    public ListenableFuture<RpcResult<GetAllFlowStatisticsFromFlowTableOutput>> getAllFlowStatisticsFromFlowTable(
             GetAllFlowStatisticsFromFlowTableInput input) {
         GetAllFlowStatisticsFromFlowTableOutput rpcResultType = null;
         boolean rpcResultBool = false;
@@ -99,7 +101,7 @@ public class FlowStatisticsAdapter implements OpendaylightFlowStatisticsService,
             GetAllFlowStatisticsFromFlowTableOutputBuilder builder = new GetAllFlowStatisticsFromFlowTableOutputBuilder();
             builder.setTransactionId(new TransactionId(new BigInteger("0")));
             rpcResultType = builder.setFlowAndStatisticsMapList(flowsStatistics).build();
-            
+
             rpcResultBool = true;
         } catch (ConstructionException e) {
             LOG.error(e.getMessage());
@@ -112,9 +114,9 @@ public class FlowStatisticsAdapter implements OpendaylightFlowStatisticsService,
      * Essentially this API will return the same result as getAllFlowStatisticsFromFlowTable
      */
     @Override
-    public Future<RpcResult<GetAllFlowsStatisticsFromAllFlowTablesOutput>> getAllFlowsStatisticsFromAllFlowTables(
+    public ListenableFuture<RpcResult<GetAllFlowsStatisticsFromAllFlowTablesOutput>> getAllFlowsStatisticsFromAllFlowTables(
             GetAllFlowsStatisticsFromAllFlowTablesInput input) {
-        
+
         GetAllFlowsStatisticsFromAllFlowTablesOutput rpcResultType = null;
         boolean rpcResultBool = false;
 
@@ -125,7 +127,7 @@ public class FlowStatisticsAdapter implements OpendaylightFlowStatisticsService,
             GetAllFlowsStatisticsFromAllFlowTablesOutputBuilder builder = new GetAllFlowsStatisticsFromAllFlowTablesOutputBuilder();
             builder.setTransactionId(new TransactionId(new BigInteger("0")));
             rpcResultType = builder.setFlowAndStatisticsMapList(flowsStatistics).build();
-            
+
             rpcResultBool = true;
         } catch (ConstructionException e) {
             LOG.error(e.getMessage());
@@ -135,7 +137,7 @@ public class FlowStatisticsAdapter implements OpendaylightFlowStatisticsService,
     }
 
     @Override
-    public Future<RpcResult<GetFlowStatisticsFromFlowTableOutput>> getFlowStatisticsFromFlowTable(
+    public ListenableFuture<RpcResult<GetFlowStatisticsFromFlowTableOutput>> getFlowStatisticsFromFlowTable(
             GetFlowStatisticsFromFlowTableInput input) {
         GetFlowStatisticsFromFlowTableOutput rpcResultType = null;
         boolean rpcResultBool = false;
@@ -170,7 +172,7 @@ public class FlowStatisticsAdapter implements OpendaylightFlowStatisticsService,
     public void nodeConnectorStatisticsUpdated(Node node, List<NodeConnectorStatistics> ncStatsList) {
         NodeConnectorStatisticsUpdateBuilder nodeConnectorStatisticsUpdateBuilder = new NodeConnectorStatisticsUpdateBuilder();
         List<NodeConnectorStatisticsAndPortNumberMap> nodeConnectorStatistics = toOdNodeConnectorStatistics(ncStatsList);
-        
+
         nodeConnectorStatisticsUpdateBuilder.setNodeConnectorStatisticsAndPortNumberMap(nodeConnectorStatistics);
         nodeConnectorStatisticsUpdateBuilder.setMoreReplies(false);
         nodeConnectorStatisticsUpdateBuilder.setTransactionId(null);
@@ -180,9 +182,9 @@ public class FlowStatisticsAdapter implements OpendaylightFlowStatisticsService,
 
     @Override
     public void nodeTableStatisticsUpdated(Node node, List<NodeTableStatistics> tableStatsList) {
-        
-        FlowTableStatisticsUpdateBuilder flowTableStatisticsUpdateBuilder = new FlowTableStatisticsUpdateBuilder();  
-        
+
+        FlowTableStatisticsUpdateBuilder flowTableStatisticsUpdateBuilder = new FlowTableStatisticsUpdateBuilder();
+
         List<FlowTableAndStatisticsMap>  flowTableStatistics = toOdFlowTableStatistics(tableStatsList);
         flowTableStatisticsUpdateBuilder.setFlowTableAndStatisticsMap(flowTableStatistics);
         flowTableStatisticsUpdateBuilder.setMoreReplies(false);
@@ -194,7 +196,7 @@ public class FlowStatisticsAdapter implements OpendaylightFlowStatisticsService,
         @Override
     public void descriptionStatisticsUpdated(Node node, NodeDescription nodeDescription) {
             // TODO which *StatisticsUpdated interface should be used?
-        
+
     }
 
     private List<FlowAndStatisticsMapList> toOdFlowsStatistics(List<FlowOnNode> flowsOnNode) {
@@ -234,7 +236,7 @@ public class FlowStatisticsAdapter implements OpendaylightFlowStatisticsService,
     }
 
     private List<FlowTableAndStatisticsMap> toOdFlowTableStatistics(List<NodeTableStatistics> tableStatsList) {
-        
+
         List<FlowTableAndStatisticsMap> flowTableStatsMap = new ArrayList<FlowTableAndStatisticsMap>();
         for (NodeTableStatistics nodeTableStatistics : tableStatsList) {
             FlowTableAndStatisticsMapBuilder flowTableAndStatisticsMapBuilder = new FlowTableAndStatisticsMapBuilder();
@@ -245,7 +247,7 @@ public class FlowStatisticsAdapter implements OpendaylightFlowStatisticsService,
             flowTableAndStatisticsMapBuilder.setTableId(new TableId((short)nodeTableStatistics.getNodeTable().getID()));
             flowTableStatsMap.add(flowTableAndStatisticsMapBuilder.build());
         }
-        
+
         return flowTableStatsMap;
     }
 
@@ -254,7 +256,7 @@ public class FlowStatisticsAdapter implements OpendaylightFlowStatisticsService,
         List<NodeConnectorStatisticsAndPortNumberMap> nodeConnectorStatisticsList = new ArrayList<NodeConnectorStatisticsAndPortNumberMap>();
         for(NodeConnectorStatistics ofNodeConnectorStatistics : ncStatsList){
             NodeConnectorStatisticsAndPortNumberMapBuilder nodeConnectorStatisticsAndPortNumberMapBuilder = new NodeConnectorStatisticsAndPortNumberMapBuilder();
-            
+
             nodeConnectorStatisticsAndPortNumberMapBuilder.setBytes(extractBytes(ofNodeConnectorStatistics));
             nodeConnectorStatisticsAndPortNumberMapBuilder.setCollisionCount(toBI(ofNodeConnectorStatistics.getCollisionCount()));
             nodeConnectorStatisticsAndPortNumberMapBuilder.setDuration(null);
@@ -268,7 +270,7 @@ public class FlowStatisticsAdapter implements OpendaylightFlowStatisticsService,
             nodeConnectorStatisticsAndPortNumberMapBuilder.setTransmitErrors(toBI(ofNodeConnectorStatistics.getTransmitErrorCount()));
             nodeConnectorStatisticsList.add(nodeConnectorStatisticsAndPortNumberMapBuilder.build());
         }
-        
+
         return nodeConnectorStatisticsList;
     }
 
index 5092995..1ea0a3e 100644 (file)
@@ -47,7 +47,6 @@
             <plugin>
                 <groupId>org.opendaylight.yangtools</groupId>
                 <artifactId>yang-maven-plugin</artifactId>
-                <version>${yangtools.version}</version>
                 <executions>
                     <execution>
                         <goals>
index f900c0b..6cc06ba 100644 (file)
 
         <!-- Dependency Versions -->
         <mockito.version>1.9.5</mockito.version>
-        <xtend.version>2.4.3</xtend.version>
+
 
         <!-- Sonar properties using jacoco to retrieve integration test results -->
         <sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
         <sonar.branch>${user.name}-private-view</sonar.branch>
         <sonar.language>java</sonar.language>
         <exam.version>3.0.0</exam.version>
-        <sal.version>0.7.1-SNAPSHOT</sal.version>
+        <sal.version>0.8.1-SNAPSHOT</sal.version>
     </properties>
 
     <dependencyManagement>
                 <artifactId>slf4j-api</artifactId>
                 <version>${slf4j.version}</version>
             </dependency>
-            <dependency>
-                <groupId>org.eclipse.xtend</groupId>
-                <artifactId>org.eclipse.xtend.lib</artifactId>
-                <version>${xtend.version}</version>
-            </dependency>
+
             <dependency>
                 <groupId>org.osgi</groupId>
                 <artifactId>org.osgi.core</artifactId>
index 2da031e..e5e314c 100644 (file)
@@ -7,25 +7,33 @@
  */
 package org.opendaylight.controller.sal.connector.remoterpc.api;
 
-import java.util.Map;
 import java.util.Set;
 
 public interface RoutingTable<I,R> {
 
-
-
   /**
-   * Adds a network address for the route. If address for route
-   * exists, appends the address to the list
+   * Adds a network address for the route. If the route already exists,
+   * it throws <code>DuplicateRouteException</code>.
+   * This method would be used when registering a global service.
+   *
    *
    * @param routeId route identifier
    * @param route network address
-   * @throws RoutingTableException for any logical exception
+   * @throws DuplicateRouteException
+   * @throws RoutingTableException
+   */
+  public void addGlobalRoute(I routeId, R route) throws  RoutingTableException, SystemException;
+
+  /**
+   * Remove the route.
+   * This method would be used when registering a global service.
+   * @param routeId
+   * @throws RoutingTableException
    * @throws SystemException
    */
-  public void addRoute(I routeId, R route) throws  RoutingTableException,SystemException;
+  public void removeGlobalRoute(I routeId) throws RoutingTableException, SystemException;
 
-    /**
+  /**
    * Adds a network address for the route. If the route already exists,
    * it throws <code>DuplicateRouteException</code>.
    * This method would be used when registering a global service.
@@ -36,9 +44,18 @@ public interface RoutingTable<I,R> {
    * @throws DuplicateRouteException
    * @throws RoutingTableException
    */
-  public void addGlobalRoute(I routeId, R route) throws  RoutingTableException, SystemException;
-
+  public R getGlobalRoute(I routeId) throws  RoutingTableException, SystemException;
 
+  /**
+   * Adds a network address for the route. If address for route
+   * exists, appends the address to the list
+   *
+   * @param routeId route identifier
+   * @param route network address
+   * @throws RoutingTableException for any logical exception
+   * @throws SystemException
+   */
+  public void addRoute(I routeId, R route) throws RoutingTableException,SystemException;
 
 
   /**
@@ -47,17 +64,28 @@ public interface RoutingTable<I,R> {
    * @param routeId
    * @param route
    */
-  public void removeRoute(I routeId, R route);
+  public void removeRoute(I routeId, R route) throws RoutingTableException,SystemException;
 
+  /**
+   * Adds address for a set of route identifiers. If address for route
+   * exists, appends the address to the set.
+   *
+   * @param routeIds a set of routeIds
+   * @param route network address
+   * @throws RoutingTableException for any logical exception
+   * @throws SystemException
+   */
+  public void addRoutes(Set<I> routeIds, R route) throws  RoutingTableException,SystemException;
 
-    /**
-     * Remove the route.
-     * This method would be used when registering a global service.
-     * @param routeId
-     * @throws RoutingTableException
-     * @throws SystemException
-     */
-    public void removeGlobalRoute(I routeId) throws RoutingTableException, SystemException;
+  /**
+   * Removes address for a set of route identifiers.
+   *
+   * @param routeIds a set of routeIds
+   * @param route network address
+   * @throws RoutingTableException for any logical exception
+   * @throws SystemException
+   */
+  public void removeRoutes(Set<I> routeIds, R route) throws  RoutingTableException,SystemException;
 
   /**
    * Returns a set of network addresses associated with this route
@@ -66,29 +94,14 @@ public interface RoutingTable<I,R> {
    */
   public Set<R> getRoutes(I routeId);
 
-  /**
-   * Returns all network addresses stored in the table
-   * @return
-   */
-  public Set<Map.Entry> getAllRoutes();
 
   /**
-   * Returns only one address from the list of network addresses
-   * associated with the route. The algorithm to determine that
-   * one address is upto the implementer
+   * Returns the last inserted address from the list of network addresses
+   * associated with the route.
    * @param routeId
    * @return
    */
-  public R getARoute(I routeId);
-
-    /**
-     *
-     * This will be removed after listeners
-     * have made change on their end to use whiteboard pattern
-     * @deprecated
-     */
-
-  public void registerRouteChangeListener(RouteChangeListener listener);
+  public R getLastAddedRoute(I routeId);
 
   public class DuplicateRouteException extends RoutingTableException {
       public DuplicateRouteException(String message) {
index 6e2d280..a826a3c 100644 (file)
@@ -67,7 +67,8 @@ public class Activator extends ComponentActivatorAbstractBase {
         if (imp.equals(RoutingTableImpl.class)) {
             Dictionary<String, Set<String>> props = new Hashtable<String, Set<String>>();
             Set<String> propSet = new HashSet<String>();
-            propSet.add(RoutingTableImpl.ROUTING_TABLE_GLOBAL_CACHE);
+            propSet.add(RoutingTableImpl.GLOBALRPC_CACHE);
+            propSet.add(RoutingTableImpl.RPC_CACHE);
             props.put(CACHE_UPDATE_AWARE_REGISTRY_KEY, propSet);
 
             c.setInterface(new String[] { RoutingTable.class.getName(),ICacheUpdateAware.class.getName()  }, props);
index 40c4c6b..d6b42fa 100644 (file)
@@ -8,15 +8,11 @@
 
 package org.opendaylight.controller.sal.connector.remoterpc.impl;
 
+import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableSet;
 import org.apache.felix.dm.Component;
-import org.opendaylight.controller.clustering.services.CacheConfigException;
-import org.opendaylight.controller.clustering.services.CacheExistException;
-import org.opendaylight.controller.clustering.services.CacheListenerAddException;
-import org.opendaylight.controller.clustering.services.ICacheUpdateAware;
-import org.opendaylight.controller.clustering.services.IClusterGlobalServices;
-import org.opendaylight.controller.clustering.services.IClusterServices;
-import org.opendaylight.controller.sal.connector.remoterpc.api.RouteChangeListener;
+import org.opendaylight.controller.clustering.services.*;
 import org.opendaylight.controller.sal.connector.remoterpc.api.RoutingTable;
 import org.opendaylight.controller.sal.connector.remoterpc.api.RoutingTableException;
 import org.opendaylight.controller.sal.connector.remoterpc.api.SystemException;
@@ -27,309 +23,415 @@ import javax.transaction.HeuristicMixedException;
 import javax.transaction.HeuristicRollbackException;
 import javax.transaction.NotSupportedException;
 import javax.transaction.RollbackException;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
 import java.util.concurrent.ConcurrentMap;
 
-/**
- * @author: syedbahm
- */
 public class RoutingTableImpl<I, R> implements RoutingTable<I, R>, ICacheUpdateAware<I, R> {
-    public static final String ROUTING_TABLE_GLOBAL_CACHE = "routing_table_global_cache";
 
-    private Logger log = LoggerFactory.getLogger(RoutingTableImpl.class);
+  private Logger log = LoggerFactory.getLogger(RoutingTableImpl.class);
 
-    private IClusterGlobalServices clusterGlobalServices = null;
-    private RoutingTableImpl routingTableInstance = null;
-    private ConcurrentMap routingTableCache = null;
-    private Set<RouteChangeListener> routeChangeListeners = Collections
-            .synchronizedSet(new HashSet<RouteChangeListener>());
+  private IClusterGlobalServices clusterGlobalServices = null;
 
-    public RoutingTableImpl() {
-    }
+  private ConcurrentMap<I,R> globalRpcCache = null;
+  private ConcurrentMap<I, LinkedHashSet<R>> rpcCache = null;  //need routes to ordered by insert-order
 
-    @Override
-    public void addRoute(I routeId, R route) throws RoutingTableException {
-        throw new UnsupportedOperationException(" Not implemented yet!");
-    }
+  public static final String GLOBALRPC_CACHE = "remoterpc_routingtable.globalrpc_cache";
+  public static final String RPC_CACHE = "remoterpc_routingtable.rpc_cache";
 
-    @Override
-    public void addGlobalRoute(I routeId, R route) throws RoutingTableException, SystemException {
-        Preconditions.checkNotNull(routeId, "addGlobalRoute: routeId cannot be null!");
-        Preconditions.checkNotNull(route, "addGlobalRoute: route cannot be null!");
-        try {
-
-            Set<R> existingRoute = null;
-            // ok does the global route is already registered ?
-            if ((existingRoute = getRoutes(routeId)) == null) {
-
-                if (log.isDebugEnabled()) {
-                    log.debug("addGlobalRoute: adding  a new route with id" + routeId + " and value = "
-                            + route);
-                }
-                // lets start a transaction
-                clusterGlobalServices.tbegin();
-
-                routingTableCache.put(routeId, route);
-                clusterGlobalServices.tcommit();
-            } else {
-                throw new DuplicateRouteException(" There is already existing route " + existingRoute);
-            }
-
-        } catch (NotSupportedException|HeuristicRollbackException|RollbackException|HeuristicMixedException e) {
-            throw new RoutingTableException("Transaction error - while trying to create route id="
-                    + routeId + "with route" + route, e);
-        } catch (javax.transaction.SystemException e) {
-            throw new SystemException("System error occurred - while trying to create with value", e);
-        }
+  public RoutingTableImpl() {
+  }
 
-    }
+  @Override
+  public R getGlobalRoute(I routeId) throws RoutingTableException, SystemException {
+    Preconditions.checkNotNull(routeId, "getGlobalRoute: routeId cannot be null!");
+    return globalRpcCache.get(routeId);
+  }
 
-    @Override
-    public void removeRoute(I routeId, R route) {
-        throw new UnsupportedOperationException("Not implemented yet!");
+  @Override
+  public void addGlobalRoute(I routeId, R route) throws RoutingTableException, SystemException {
+    Preconditions.checkNotNull(routeId, "addGlobalRoute: routeId cannot be null!");
+    Preconditions.checkNotNull(route, "addGlobalRoute: route cannot be null!");
+    try {
+
+      log.debug("addGlobalRoute: adding  a new route with id[{}] and value [{}]", routeId, route);
+      clusterGlobalServices.tbegin();
+      if (globalRpcCache.putIfAbsent(routeId, route) != null) {
+        throw new DuplicateRouteException(" There is already existing route " + routeId);
+      }
+      clusterGlobalServices.tcommit();
+
+    } catch (NotSupportedException | HeuristicRollbackException | RollbackException | HeuristicMixedException e) {
+      throw new RoutingTableException("Transaction error - while trying to create route id="
+          + routeId + "with route" + route, e);
+    } catch (javax.transaction.SystemException e) {
+      throw new SystemException("System error occurred - while trying to create with value", e);
     }
 
-    @Override
-    public void removeGlobalRoute(I routeId) throws RoutingTableException, SystemException {
-        Preconditions.checkNotNull(routeId, "removeGlobalRoute: routeId cannot be null!");
-        try {
-            if (log.isDebugEnabled()) {
-                log.debug("removeGlobalRoute: removing  a new route with id" + routeId);
-            }
-            // lets start a transaction
-            clusterGlobalServices.tbegin();
-
-            routingTableCache.remove(routeId);
-            clusterGlobalServices.tcommit();
-
-        } catch (NotSupportedException|HeuristicRollbackException|RollbackException|HeuristicMixedException e) {
-            throw new RoutingTableException("Transaction error - while trying to remove route id="
-                    + routeId, e);
-        } catch (javax.transaction.SystemException e) {
-            throw new SystemException("System error occurred - while trying to remove with value", e);
-        }
+  }
+
+  @Override
+  public void removeGlobalRoute(I routeId) throws RoutingTableException, SystemException {